-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix handling of emtpy command lines Add Mem class for handling memory read/writes Ensure we always allocate at least a page when creating working space Change read and write commands to take length Changes to move source code to different directories Update docs Add commandlet for display file descriptors Add support for loading init script Add support for loading new commandlets from JS Support comments
- Loading branch information
Your Name
committed
Apr 23, 2024
1 parent
8323c71
commit 14811f8
Showing
51 changed files
with
1,235 additions
and
538 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# allocate some memory, assign a variable and dump it | ||
malloc 32 | ||
v p ret | ||
d p | ||
|
||
# load a new commandlet from a script file and execute | ||
src src.js | ||
test malloc | ||
|
||
# show the first instruction of exit | ||
l exit 1 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
# Development | ||
All of the commands supported by `frida-cshell` are implemented as commandlets. A list of available commands can be seen by running `help`: | ||
``` | ||
-> help | ||
breakpoints: | ||
@F : function exit breakpoint | ||
@f : function entry breakpoint | ||
@i : instruction breakpoint | ||
@r : memory read breakpoint | ||
@w : memory write breakpoint | ||
R : register management | ||
data: | ||
cp : copy data in memory | ||
d : dump data from memory | ||
l : disassembly listing | ||
r : read data from memory | ||
w : write data to memory | ||
math: | ||
& : and two operands | ||
* : multiply two operands | ||
+ : add two operands | ||
- : subtract two operands | ||
/ : divide two operands | ||
<< : shl op1 by op2 | ||
>> : shr op1 by op2 | ||
^ : xor two operands | ||
| : or two operands | ||
~ : bitwise not | ||
memory: | ||
sym : look up a symbol information | ||
vm : display virtual memory ranges | ||
misc: | ||
h : command history | ||
help : print this message | ||
v : variable management | ||
modules: | ||
ld : load modules | ||
mod : display module information | ||
thread: | ||
bt : display backtrace information | ||
t : display thread information | ||
For more information about a command use: | ||
help <cmd> | ||
ret: 0x00000000 0 | ||
``` | ||
# Interface | ||
Commandlets all implement the following interface: | ||
```js | ||
export abstract class CmdLet { | ||
public abstract readonly category: string; | ||
public abstract readonly name: string; | ||
public abstract readonly help: string; | ||
public readonly visible: boolean = true; | ||
public abstract usage(): Var; | ||
public abstract run(tokens: Token[]): Var; | ||
public isSupported(): boolean { | ||
return true; | ||
} | ||
} | ||
``` | ||
## Members | ||
* The `category` field is used to group the commandlets in the `help` output. | ||
* The `name` field is used to determine the command name which must be entered by the user. | ||
* The `help` field contains the string printed alongside the command in the `help` output | ||
* The `visible` field dictates whether the commandlet is visible in the help menu. | ||
* The `usage` method is called when the user enters `help <cmd name>` to print more detailed usage information to the console. | ||
* The `run` method is called when the user executes the command, it is passed the `tokens` which have been passed as arguments. | ||
* The `isSupported` method is called during initialization to allow it to determine whether it should be ignored, e.g. if the command only works on a subset of operating systems or architectures. | ||
|
||
# Tokens | ||
The token class represents each token the user has entered on the command line (each separated by whitespace). The `getLiteral` method can be used to retrieve the original string which the user typed. Otherwise, the `toVar` method can be used to interpret the value as a `Var` type. | ||
```js | ||
export class Token { | ||
... | ||
public getLiteral(): string; | ||
public toVar(): Var | undefined; | ||
... | ||
} | ||
``` | ||
|
||
# Var | ||
The `Var` class represents the parameters passed to a commandlet after their interpretation by `frida-cshell`. Each can be accessed as either a `UInt64` or a `NativePointer` type. Note that `UInt64` is used in place of `number` since the number type loses precision handling numbers greater than `2^52`. | ||
|
||
When converting tokens, `frida-cshell` will automatically convert several types of input: | ||
1. Double-quoted strings will be interpreted and copied into memory. The `toPointer` method of these can then be used to reference the UTF-8 string data. | ||
2. Numeric types are parsed from their string form. These can either be: | ||
* Hexadecimal numbers with a `0x` or `0X` prefix | ||
* Decimal numbers with a `0d` or `0D` prefix | ||
* Octal numbers with a `0o` or `0O` prefix | ||
* Decimal numbers without a prefix | ||
3. Register names starting with a `$` prefix (these are only available during breakpoint execution). | ||
4. Names variables which have been created using the `v` command. | ||
5. Exported function names | ||
6. Debug symbol names | ||
|
||
Each of these types of input is handled transparently by `frida-cshell` and passed to the commandlet in a single consistent form. | ||
|
||
```js | ||
export class Var { | ||
... | ||
public toPointer(): NativePointer; | ||
public toU64(): UInt64; | ||
... | ||
} | ||
``` | ||
|
||
Similarly, the `run` method of each commandlet is expected to return a `Var` type which can subsequently be referenced by the user using the `ret` keyword in the execution of the next command. | ||
|
||
# Parsing | ||
Below is snippet of the `dump` commandlet showing how it parses it's two arguments. The first is the address which to dump and the second is the length. Note that the first argument is also used as the return value for this commandlet. Note also that the second argument is also converted from a `UInt64` to a `number` type, since this is what is reqired by the `hexdump` function called by `this.dump`. This is used in many commands where the parameter is likely to be a small number and therefore loss of precision is not a concern. | ||
```js | ||
private runWithLength(tokens: Token[]): Var | undefined { | ||
if (tokens.length != 2) return undefined; | ||
|
||
const t0 = tokens[0]?.toVar(); | ||
if (t0 === undefined) return undefined; | ||
|
||
const address = t0.toPointer(); | ||
if (address === undefined) return undefined; | ||
|
||
const length = tokens[1]?.toVar()?.toU64().toNumber(); | ||
if (length === undefined) return undefined; | ||
|
||
this.dump(address, length); | ||
return t0; | ||
} | ||
|
||
public run(tokens: Token[]): Var { | ||
const retWithLength = this.runWithLength(tokens); | ||
if (retWithLength !== undefined) return retWithLength; | ||
|
||
... | ||
|
||
return this.usage(); | ||
} | ||
``` | ||
# Scripts | ||
Whilst scripts can be written in Typescript and added to the project, for more adhoc use cases, it is also possible to write commandlets in JavaScript and load them dynamically into `frida-cshell`. An example script can be seen [here](src.js). Note that all of the exported classes within `frida-cshell` should also be available to these scripts. These scripts can be loaded using the `src` command, simply passing the filename to be loaded. | ||
# Initialization | ||
To automate this process, it is also possible to provide a [`.cshellrc`](assets/initrd/.cshellrc) file in your home directory containing commands to execute during start-up. This can include the use of the `src` command and the subsequent execution of any commandlets loaded as a result. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# allocate some memory, assign a variable and dump it | ||
malloc 32 | ||
v p ret | ||
d p | ||
|
||
# load a new commandlet from a script file and execute | ||
src /home/ws/src.js | ||
test malloc | ||
|
||
# show the first instruction of exit | ||
l exit 1 | ||
|
Oops, something went wrong.