r2papi-async
Version:
r2api on top of r2pipe for typescript and js
492 lines (491 loc) • 15.9 kB
TypeScript
import { R2Shell } from "./shell.js";
import { R2PipeAsync } from "./r2pipe.js";
export type InstructionType = "mov" | "jmp" | "cmp" | "nop" | "call" | "add" | "sub";
export type InstructionFamily = "cpu" | "fpu" | "priv";
export type GraphFormat = "dot" | "json" | "mermaid" | "ascii";
export type Permission = "---" | "r--" | "rw-" | "rwx" | "r-x" | "-wx" | "--x";
export type R2Papi = R2PapiAsync;
export interface SearchResult {
offset: number;
type: string;
data: string;
}
export interface DebugModule {
base: string;
name: string;
path: string;
size: number;
}
export interface Flag {
name: string;
size: number;
offset: number;
}
export type PluginFamily = "core" | "io" | "arch" | "esil" | "lang" | "bin" | "debug" | "anal" | "crypto";
export interface ThreadContext {
context: any;
id: number;
state: string;
selected: boolean;
}
export interface CallRef {
addr: number;
type: string;
at: number;
}
export interface FunctionDetails {
offset: number;
name: string;
size: number;
noreturn: boolean;
stackframe: number;
ebbs: number;
signature: string;
nbbs: number;
callrefs: CallRef[];
codexrefs: CallRef[];
}
export interface BinFile {
arch: string;
static: boolean;
va: boolean;
stripped: boolean;
pic: boolean;
relocs: boolean;
sanitize: boolean;
baddr: number;
binsz: number;
bintype: string;
bits: number;
canary: boolean;
class: string;
compiler: string;
endian: string;
machine: string;
nx: boolean;
os: string;
laddr: number;
linenum: boolean;
havecode: boolean;
intrp: string;
}
export interface Reference {
from: number;
type: string;
perm: string;
opcode: string;
fcn_addr: number;
fcn_name: string;
realname: string;
refname: string;
}
export interface BasicBlock {
addr: number;
size: number;
jump: number;
fail: number;
opaddr: number;
inputs: number;
outputs: number;
ninstr: number;
instrs: number[];
traced: boolean;
}
export declare class ThreadClass {
api: any;
constructor(r2: any);
backtrace(): string;
sleep(seconds: number): string;
}
export interface Instruction {
type: InstructionType;
addr: number;
opcode: string;
pseudo: string;
mnemonic: string;
sign: boolean;
family: InstructionFamily;
description: string;
esil: string;
opex: any;
size: number;
ptr: number;
bytes: string;
id: number;
refptr: number;
direction: "read" | "write";
stackptr: number;
stack: string;
}
export declare class ModuleClass {
api: any;
constructor(r2: R2PipeAsync);
fileName(): string;
name(): string;
findBaseAddress(): string;
findExportByName(name: string): any;
getBaseAddress(name: string): string;
getExportByName(name: string): string;
enumerateExports(): any;
enumerateImports(): any;
enumerateRanges(): any;
enumerateSymbols(): any;
}
export declare class ProcessClass {
r2: any;
constructor(r2: R2PipeAsync);
enumerateMallocRanges(): void;
enumerateSystemRanges(): void;
enumerateRanges(): void;
enumerateThreads(): any;
enumerateModules(): any;
getModuleByAddress(addr: NativePointer | number | string): any;
getModuleByName(moduleName: string): any;
codeSigningPolicy(): string;
getTmpDir(): any;
getHomeDir(): any;
platform(): any;
getCurrentDir(): any;
getCurrentThreadId(): number;
pageSize(): number;
isDebuggerAttached(): boolean;
setExceptionHandler(): void;
id(): any;
pointerSize(): number;
}
/**
* Assembler and disassembler facilities to decode and encode instructions
*
* @typedef Assembler
*/
export declare class Assembler {
program: string;
labels: any;
endian: boolean;
pc: NativePointer;
r2: R2PipeAsync;
constructor(myr2?: R2PipeAsync);
/**
* Change the address of the program counter, some instructions need to know where
* are they located before being encoded or decoded.
*
* @param {NativePointerValue}
*/
setProgramCounter(pc: NativePointer): void;
setEndian(big: boolean): void;
toString(): string;
append(x: string): Promise<void>;
label(s: string): NativePointer;
/**
* Encode (assemble) an instruction by taking the string representation.
*
* @param {string} the string representation of the instruction to assemble
* @returns {string} the hexpairs that represent the assembled instruciton
*/
encode(s: string): Promise<string>;
/**
* Decode (disassemble) an instruction by taking the hexpairs string as input.
* TODO: should take an array of bytes too
*
* @param {string} the hexadecimal pairs of bytes to decode as an instruction
* @returns {string} the mnemonic and operands of the resulting decoding
*/
decode(s: string): Promise<string>;
}
/**
* High level abstraction on top of the r2 command interface provided by r2pipe.
*
* @typedef R2Papi
*/
export declare class R2PapiAsync {
/**
* Keep a reference r2pipe instance
*
* @type {R2PipeAsync}
*/
r2: R2PipeAsync;
/**
* Create a new instance of the R2Papi class, taking an r2pipe interface as reference.
*
* @param {R2PipeAsync} the r2pipe instance to use as backend.
* @returns {R2Papi} instance
*/
constructor(r2: R2PipeAsync);
toString(): string;
toJSON(): string;
/**
* Get the base address used by the current loaded binary
*
* @returns {NativePointer} address of the base of the binary
*/
getBaseAddress(): Promise<NativePointer>;
jsonToTypescript(name: string, a: any): string;
/**
* Get the general purpose register size of the targize architecture in bits
*
* @returns {number} the regsize
*/
getBits(): number;
/**
* Get the name of the arch plugin selected, which tends to be the same target architecture.
* Note that on some situations, this info will be stored protected bby the AirForce.
* When using the r2ghidra arch plugin the underlying arch is in `asm.cpu`:
*
* @returns {string} the name of the target architecture.
*/
getArch(): Promise<string>;
/**
* Get the name of the selected CPU for the current selected architecture.
*
* @returns {string} the value of asm.cpu
*/
getCpu(): Promise<string>;
setArch(arch: string, bits: number | undefined): Promise<void>;
setFlagSpace(name: string): Promise<void>;
setLogLevel(level: number): Promise<void>;
/**
* should return the id for the new map using the given file descriptor
*/
newMap(fd: number, vaddr: NativePointer, size: number, paddr: NativePointer, perm: Permission, name?: string): void;
at(a: string): NativePointer;
getShell(): R2Shell;
version(): Promise<string>;
platform(): Promise<string>;
arch(): Promise<string>;
bits(): Promise<string>;
id(): number;
printAt(msg: string, x: number, y: number): void;
clearScreen(): R2Papi;
getConfig(key: string): Promise<Error | string>;
setConfig(key: string, val: string): Promise<R2Papi>;
getRegisterStateForEsil(): Promise<string>;
getRegisters(): Promise<any>;
resizeFile(newSize: number): R2Papi;
insertNullBytes(newSize: number, at?: NativePointer | number | string): R2Papi;
removeBytes(newSize: number, at?: NativePointer | number | string): R2Papi;
seek(addr: number): R2Papi;
currentSeek(): NativePointer;
seekToRelativeOpcode(nth: number): NativePointer;
getBlockSize(): number;
setBlockSize(a: number): R2Papi;
countFlags(): number;
countFunctions(): number;
analyzeFunctionsWithEsil(depth?: number): void;
analyzeProgramWithEsil(depth?: number): void;
analyzeProgram(depth?: number): this;
enumerateThreads(): ThreadContext[];
currentThreadId(): number;
setRegisters(obj: any): void;
hex(s: number | string): Promise<string>;
step(): Promise<R2Papi>;
stepOver(): R2Papi;
math(expr: number | string): number;
stepUntil(dst: NativePointer | string | number): void;
enumerateXrefsTo(s: string): Promise<string[]>;
findXrefsTo(s: string, use_esil: boolean): void;
analyzeFunctionsFromCalls(): R2Papi;
autonameAllFunctions(): R2Papi;
analyzeFunctionsWithPreludes(): R2Papi;
analyzeObjCReferences(): R2Papi;
analyzeImports(): Promise<R2Papi>;
searchDisasm(s: string): Promise<SearchResult[]>;
searchString(s: string): Promise<SearchResult[]>;
searchBytes(data: number[]): Promise<SearchResult[]>;
binInfo(): Promise<BinFile>;
selectBinary(id: number): void;
openFile(name: string): Promise<number | Error>;
openFileNomap(name: string): Promise<number | Error>;
currentFile(name: string): Promise<string>;
enumeratePlugins(type: PluginFamily): any;
enumerateModules(): Promise<DebugModule[]>;
enumerateFiles(): Promise<any>;
enumerateBinaries(): Promise<any>;
enumerateMaps(): Promise<any>;
enumerateClasses(): Promise<any>;
enumerateSymbols(): Promise<any>;
enumerateExports(): Promise<any>;
enumerateImports(): Promise<any>;
enumerateLibraries(): Promise<string[]>;
enumerateSections(): Promise<any>;
enumerateSegments(): Promise<any>;
enumerateEntrypoints(): Promise<any>;
enumerateRelocations(): Promise<any>;
enumerateFunctions(): Promise<FunctionDetails[]>;
enumerateFlags(): Promise<Flag[]>;
skip(): void;
ptr(s: string | number): NativePointer;
call(s: string): Promise<string>;
callj(s: string): Promise<any>;
cmd(s: string): Promise<string>;
cmdj(s: string): Promise<any>;
log(s: string): Promise<void>;
clippy(msg: string): Promise<void>;
ascii(msg: string): Promise<void>;
}
export declare class NativeFunction {
constructor();
}
export declare class NativeCallback {
constructor();
}
/**
* Global function that returns a new instance of a NativePointer.
* Saves some typing: `ptr(0)` is the same as `new NativePointer(0)`
*
* @type function
*/
export declare function ptr(v: NativePointerValue): NativePointer;
/**
* A NativePointer can be described using a string that contains a number in any base (hexadecimal and decimal are the most common formats used)
* But it actually supports anything else that could be handled by radare2. You can use symbol names, math operations or special symbols like `$$`.
*
* @type NativePointerValue
*/
export type NativePointerValue = string | number | NativePointer;
/**
* Class providing a way to work with 64bit pointers from Javascript, this API mimics the same
* well-known promitive available in Frida, but it's baked by the current session of r2.
*
* It is also possible to use this class via the global `ptr` function.
*
* @typedef NativePointer
*/
export declare class NativePointer {
addr: string;
api: R2Papi;
constructor(s: NativePointerValue, api?: R2Papi);
/**
* Set a flag (name) at the offset pointed
*
* @param {string} name name of the flag to set
* @returns {string} base64 decoded string
*/
setFlag(name: string): void;
/**
* Remove the flag in the current offset
*
*/
unsetFlag(): void;
/**
* Render an hexadecimal dump of the bytes contained in the range starting
* in the current pointer and given length.
*
* @param {number} length optional amount of bytes to dump, using blocksize
* @returns {string} string containing the hexadecimal dump of memory
*/
hexdump(length?: number): Promise<string>;
functionGraph(format?: GraphFormat): Promise<string>;
readByteArray(len: number): Promise<number[]>;
readHexString(len: number): Promise<string>;
and(a: number): Promise<NativePointer>;
or(a: number): Promise<NativePointer>;
add(a: number): Promise<NativePointer>;
sub(a: number): Promise<NativePointer>;
writeByteArray(data: number[]): Promise<NativePointer>;
writeAssembly(instruction: string): NativePointer;
writeCString(s: string): NativePointer;
writeWideString(s: string): NativePointer;
/**
* Check if it's a pointer to the address zero. Also known as null pointer.
*
* @returns {boolean} true if null
*/
isNull(): Promise<boolean>;
/**
* Compare current pointer with the passed one, and return -1, 0 or 1.
*
* * if (this < arg) return -1;
* * if (this > arg) return 1;
* * if (this == arg) return 0;
*
* @returns {number} returns -1, 0 or 1 depending on the comparison of the pointers
*/
compare(a: NativePointerValue): number;
/**
* Check if it's a pointer to the address zero. Also known as null pointer.
*
* @returns {boolean} true if null
*/
pointsToNull(): Promise<boolean>;
toJSON(): Promise<string>;
toString(): Promise<string>;
toNumber(): Promise<number>;
writePointer(p: NativePointer): void;
readRelativePointer(): Promise<NativePointer>;
readPointer(): Promise<NativePointer>;
readS8(): Promise<number>;
readU8(): Promise<number>;
readU16(): Promise<number>;
readU16le(): Promise<number>;
readU16be(): Promise<number>;
readS16(): Promise<number>;
readS16le(): Promise<number>;
readS16be(): Promise<number>;
readS32(): Promise<number>;
readU32(): Promise<number>;
readU32le(): Promise<number>;
readU32be(): Promise<number>;
readU64(): Promise<number>;
readU64le(): Promise<number>;
readU64be(): Promise<number>;
writeInt(n: number): Promise<boolean>;
/**
* Write a byte in the current offset, the value must be between 0 and 255
*
* @param {string} n number to write in the pointed byte in the current address
* @returns {boolean} false if the operation failed
*/
writeU8(n: number): Promise<boolean>;
writeU16(n: number): Promise<boolean>;
writeU16be(n: number): Promise<boolean>;
writeU16le(n: number): Promise<boolean>;
writeU32(n: number): Promise<boolean>;
writeU32be(n: number): Promise<boolean>;
writeU32le(n: number): Promise<boolean>;
writeU64(n: number): Promise<boolean>;
writeU64be(n: number): Promise<boolean>;
writeU64le(n: number): Promise<boolean>;
readInt32(): Promise<number>;
readCString(): Promise<string>;
readWideString(): Promise<string>;
readPascalString(): Promise<string>;
instruction(): Promise<Instruction>;
disassemble(length?: number): Promise<string>;
analyzeFunction(): Promise<NativePointer>;
analyzeFunctionRecursively(): Promise<NativePointer>;
name(): Promise<string>;
methodName(): Promise<string>;
symbolName(): Promise<string>;
getFunction(): Promise<FunctionDetails>;
basicBlock(): Promise<BasicBlock>;
functionBasicBlocks(): Promise<BasicBlock[]>;
xrefs(): Promise<Reference[]>;
}
/**
* Global instance of R2Papi based on the current session of radare2.
* Note that `r2` is the global instance of `r2pipe` used by `R`.
*
* @type R2Papi
*/
export declare const R: R2Papi;
/**
* Global instance of the Module class based on the current radare2 session.
* This variable mimics the same APIs shipped by Frida.
*
* @type ModuleClass
*/
export declare const Module: ModuleClass;
/**
* Global instance of the Process class based on the current radare2 session.
* This variable mimics the same APIs shipped by Frida.
*
* @type ProcessClass
*/
export declare const Process: ProcessClass;
/**
* Global instance of the Thread class based on the current radare2 session.
* This variable mimics the same APIs shipped by Frida.
*
* @type ThreadClass
*/
export declare const Thread: ThreadClass;