Update r2papi to the test version from git ##r2js

This commit is contained in:
pancake 2024-10-21 18:40:31 +02:00 committed by pancake
parent 5eb87127ef
commit e3af0aed83
2 changed files with 352 additions and 268 deletions

View File

@ -414,250 +414,277 @@ static const char *const js_r2papi_qjs = "" \
"{\n return this.toString();\n }\n /**\n * Get the base address us"\
"ed by the current loaded binary\n *\n * @returns {NativePointer"\
"} address of the base of the binary\n */\n getBaseAddress() {\n "\
"return new NativePointer(this.cmd(\"e bin.baddr\"));\n }\n jsonTo"\
"Typescript(name, a) {\n let str = `interface ${name} {\\n`;\n if"\
" (a.length && a.length > 0) {\n a = a[0];\n }\n for (const k of "\
"Object.keys(a)) {\n const typ = typeof a[k];\n const nam = k;\n "\
"str += ` ${nam}: ${typ};\\n`;\n }\n return `${str}}\\n`;\n }\n /**\n"\
" * Get the general purpose register size of the targize archi"\
"tecture in bits\n *\n * @returns {number} the regsize\n */\n getB"\
"its() {\n return +this.cmd(\"-b\");\n }\n /**\n * Get the name of t"\
"he arch plugin selected, which tends to be the same target ar"\
"chitecture.\n * Note that on some situations, this info will b"\
"e stored protected bby the AirForce.\n * When using the r2ghid"\
"ra arch plugin the underlying arch is in `asm.cpu`:\n *\n * @re"\
"turns {string} the name of the target architecture.\n */\n getA"\
"rch() {\n return this.cmdTrim(\"-a\");\n }\n callTrim(x) {\n const "\
"res = this.call(x);\n return res.trim();\n }\n cmdTrim(x) {\n con"\
"st res = this.cmd(x);\n return res.trim();\n }\n /**\n * Get the "\
"name of the selected CPU for the current selected architectur"\
"e.\n *\n * @returns {string} the value of asm.cpu\n */\n getCpu()"\
" {\n // return this.cmd('-c');\n return this.cmdTrim(\"-e asm.cp"\
"u\"); // use arch.cpu\n }\n // TODO: setEndian, setCpu, ...\n set"\
"Arch(arch, bits) {\n this.cmd(\"-a \" + arch);\n if (bits !== und"\
"efined) {\n this.cmd(\"-b \" + bits);\n }\n }\n setFlagSpace(name) "\
"{\n this.cmd(\"fs \" + name);\n }\n demangleSymbol(lang, mangledNa"\
"me) {\n return this.cmdTrim(\"iD \" + lang + \" \" + mangledName);"\
"\n }\n setLogLevel(level) {\n this.cmd(\"e log.level=\" + level);\n"\
" }\n /**\n * should return the id for the new map using the giv"\
"en file descriptor\n */\n // rename to createMap or mapFile?\n n"\
"ewMap(fd, vaddr, size, paddr, perm, name = \"\") {\n this.cmd(`o"\
"m ${fd} ${vaddr} ${size} ${paddr} ${perm} ${name}`);\n }\n at(a"\
") {\n return new NativePointer(a);\n }\n getShell() {\n return ne"\
"w shell_js_1.R2Shell(this);\n }\n // Radare/Frida\n version() {\n"\
" const v = this.r2.cmd(\"?Vq\");\n return v.trim();\n }\n // Proce"\
"ss\n platform() {\n const output = this.r2.cmd(\"uname\");\n retur"\
"n output.trim();\n }\n arch() {\n const output = this.r2.cmd(\"un"\
"ame -a\");\n return output.trim();\n }\n bits() {\n const output ="\
" this.r2.cmd(\"uname -b\");\n return output.trim();\n }\n id() {\n "\
"// getpid();\n return +this.r2.cmd(\"?vi:$p\");\n }\n // Other stu"\
"ff\n printAt(msg, x, y) {\n // see pg, but pg is obrken :D\n }\n "\
"clearScreen() {\n this.r2.cmd(\"!clear\");\n return this;\n }\n get"\
"Config(key) {\n if (key === \"\") {\n return new Error(\"Empty key"\
"\");\n }\n const exist = this.r2.cmd(`e~^${key} =`);\n if (exist."\
"trim() === \"\") {\n return new Error(\"Config key does not exist"\
"\");\n }\n const value = this.r2.call(\"e \" + key);\n return value"\
".trim();\n }\n setConfig(key, val) {\n this.r2.call(\"e \" + key +"\
" \"=\" + val);\n return this;\n }\n getRegisterStateForEsil() {\n c"\
"onst dre = this.cmdj(\"dre\");\n return this.cmdj(\"dre\");\n }\n ge"\
"tRegisters() {\n // this.r2.log(\"winrar\" + JSON.stringify(JSON"\
".parse(this.r2.cmd(\"drj\")),null, 2) );\n return this.cmdj(\"drj"\
"\");\n }\n resizeFile(newSize) {\n this.cmd(`r ${newSize}`);\n ret"\
"urn this;\n }\n insertNullBytes(newSize, at) {\n if (at === unde"\
"fined) {\n at = \"$$\";\n }\n this.cmd(`r+${newSize}@${at}`);\n ret"\
"urn this;\n }\n removeBytes(newSize, at) {\n if (at === undefine"\
"d) {\n at = \"$$\";\n }\n this.cmd(`r-${newSize}@${at}`);\n return "\
"this;\n }\n seek(addr) {\n this.cmd(`s ${addr}`);\n return this;\n"\
" }\n currentSeek() {\n return new NativePointer(\"$$\");\n }\n seek"\
"ToRelativeOpcode(nth) {\n this.cmd(`so ${nth}`);\n return this."\
"currentSeek();\n }\n getBlockSize() {\n return +this.cmd(\"b\");\n "\
"}\n setBlockSize(a) {\n this.cmd(`b ${a}`);\n return this;\n }\n c"\
"ountFlags() {\n return Number(this.cmd(\"f~?\"));\n }\n countFunct"\
"ions() {\n return Number(this.cmd(\"aflc\"));\n }\n analyzeFunctio"\
"nsWithEsil(depth) {\n this.cmd(\"aaef\");\n }\n analyzeProgramWith"\
"Esil(depth) {\n this.cmd(\"aae\");\n }\n analyzeProgram(depth) {\n "\
"if (depth === undefined) {\n depth = 0;\n }\n switch (depth) {\n "\
"case 0:\n this.cmd(\"aa\");\n break;\n case 1:\n this.cmd(\"aaa\");\n "\
"break;\n case 2:\n this.cmd(\"aaaa\");\n break;\n case 3:\n this.cmd"\
"(\"aaaaa\");\n break;\n }\n return this;\n }\n enumerateThreads() {\n"\
" // TODO: use apt/dpt to list threads at iterate over them to"\
" get the registers\n const regs0 = this.cmdj(\"drj\");\n const th"\
"read0 = {\n context: regs0,\n id: 0,\n state: \"waiting\",\n select"\
"ed: true\n };\n return [thread0];\n }\n currentThreadId() {\n if ("\
"+this.cmd(\"e cfg.debug\")) {\n return +this.cmd(\"dpt.\");\n }\n re"\
"turn this.id();\n }\n setRegisters(obj) {\n for (const r of Obje"\
"ct.keys(obj)) {\n const v = obj[r];\n this.r2.cmd(\"dr \" + r + \""\
"=\" + v);\n }\n }\n hex(s) {\n const output = this.r2.cmd(\"?v \" + "\
"s);\n return output.trim();\n }\n step() {\n this.r2.cmd(\"ds\");\n "\
"return this;\n }\n stepOver() {\n this.r2.cmd(\"dso\");\n return th"\
"is;\n }\n math(expr) {\n return +this.r2.cmd(\"?v \" + expr);\n }\n "\
"stepUntil(dst) {\n this.cmd(`dsu ${dst}`);\n }\n enumerateXrefsT"\
"o(s) {\n const output = this.call(\"axtq \" + s);\n return output"\
".trim().split(/\\n/);\n }\n // TODO: rename to searchXrefsTo ?\n "\
"findXrefsTo(s, use_esil) {\n if (use_esil) {\n this.call(\"/r \" "\
"+ s);\n }\n else {\n this.call(\"/re \" + s);\n }\n }\n analyzeFuncti"\
"onsFromCalls() {\n this.call(\"aac\");\n return this;\n }\n autonam"\
"eAllFunctions() {\n this.call(\"aan\");\n return this;\n }\n analyz"\
"eFunctionsWithPreludes() {\n this.call(\"aap\");\n return this;\n "\
"}\n analyzeObjCReferences() {\n this.cmd(\"aao\");\n return this;\n"\
" }\n analyzeImports() {\n this.cmd(\"af @ sym.imp.*\");\n return t"\
"his;\n }\n searchDisasm(s) {\n const res = this.callj(\"/ad \" + s"\
");\n return res;\n }\n searchString(s) {\n const res = this.cmdj("\
"\"/j \" + s);\n return res;\n }\n searchBytes(data) {\n function nu"\
"m2hex(data) {\n return (data & 0xff).toString(16);\n }\n const s"\
" = data.map(num2hex).join(\"\");\n const res = this.cmdj(\"/xj \" "\
"+ s);\n return res;\n }\n binInfo() {\n try {\n return this.cmdj(\""\
"ij~{bin}\");\n }\n catch (e) {\n return {};\n }\n }\n // TODO: take "\
"a BinFile as argument instead of number\n selectBinary(id) {\n "\
"this.call(`ob ${id}`);\n }\n openFile(name) {\n const ofd = this"\
".call(\"oqq\");\n this.call(`o ${name}`);\n const nfd = this.call"\
"(\"oqq\");\n if (ofd.trim() === nfd.trim()) {\n return new Error("\
"\"Cannot open file\");\n }\n return parseInt(nfd);\n }\n openFileNo"\
"map(name) {\n const ofd = this.call(\"oqq\");\n this.call(`of ${n"\
"ame}`);\n const nfd = this.call(\"oqq\");\n if (ofd.trim() === nf"\
"d.trim()) {\n return new Error(\"Cannot open file\");\n }\n return"\
" parseInt(nfd);\n }\n currentFile(name) {\n return (this.call(\"o"\
".\")).trim();\n }\n enumeratePlugins(type) {\n switch (type) {\n c"\
"ase \"bin\":\n return this.callj(\"Lij\");\n case \"io\":\n return thi"\
"s.callj(\"Loj\");\n case \"core\":\n return this.callj(\"Lcj\");\n cas"\
"e \"arch\":\n return this.callj(\"LAj\");\n case \"anal\":\n return th"\
"is.callj(\"Laj\");\n case \"lang\":\n return this.callj(\"Llj\");\n }\n"\
" return [];\n }\n enumerateModules() {\n return this.callj(\"dmmj"\
"\");\n }\n enumerateFiles() {\n return this.callj(\"oj\");\n }\n enum"\
"erateBinaries() {\n return this.callj(\"obj\");\n }\n enumerateMap"\
"s() {\n return this.callj(\"omj\");\n }\n enumerateClasses() {\n re"\
"turn this.callj(\"icj\");\n }\n enumerateSymbols() {\n return this"\
".callj(\"isj\");\n }\n enumerateExports() {\n return this.callj(\"i"\
"Ej\");\n }\n enumerateImports() {\n return this.callj(\"iij\");\n }\n"\
" enumerateLibraries() {\n return this.callj(\"ilj\");\n }\n enumer"\
"ateSections() {\n return this.callj(\"iSj\");\n }\n enumerateSegme"\
"nts() {\n return this.callj(\"iSSj\");\n }\n enumerateEntrypoints("\
") {\n return this.callj(\"iej\");\n }\n enumerateRelocations() {\n "\
"return this.callj(\"irj\");\n }\n enumerateFunctions() {\n return "\
"this.cmdj(\"aflj\");\n }\n enumerateFlags() {\n return this.cmdj(\""\
"fj\");\n }\n skip() {\n this.r2.cmd(\"dss\");\n }\n ptr(s) {\n return "\
"new NativePointer(s, this);\n }\n call(s) {\n return this.r2.cal"\
"l(s);\n }\n callj(s) {\n return JSON.parse(this.call(s));\n }\n cm"\
"d(s) {\n return this.r2.cmd(s);\n }\n cmdj(s) {\n return JSON.par"\
"se(this.cmd(s));\n }\n log(s) {\n return this.r2.log(s);\n }\n cli"\
"ppy(msg) {\n this.r2.log(this.r2.cmd(\"?E \" + msg));\n }\n ascii("\
"msg) {\n this.r2.log(this.r2.cmd(\"?ea \" + msg));\n }\n}\nexports."\
"R2PapiSync = R2PapiSync;\n// useful to call functions via dxc "\
"and to define and describe function signatures\nclass NativeFu"\
"nction {\n constructor() { }\n}\nexports.NativeFunction = Native"\
"Function;\n// uhm not sure how to map this into r2 yet\nclass N"\
"ativeCallback {\n constructor() { }\n}\nexports.NativeCallback ="\
" NativeCallback;\n/**\n * Class providing a way to work with 64"\
"bit pointers from Javascript, this API mimics the same\n * wel"\
"l-known promitive available in Frida, but it's baked by the c"\
"urrent session of r2.\n *\n * It is also possible to use this c"\
"lass via the global `ptr` function.\n *\n * @typedef NativePoin"\
"ter\n */\nclass NativePointer {\n constructor(s, api) {\n this.ap"\
"i = api ?? exports.R;\n this.addr = (\"\" + s).trim();\n }\n /**\n "\
"* Filter a string to be used as a valid flag name\n *\n * @para"\
"m {string} name of the symbol name\n * @returns {string} filte"\
"red name to be used as a flag\n */\n filterFlag(name) {\n return"\
" this.api.call(`fD ${name}`);\n }\n /**\n * Set a flag (name) at"\
" the offset pointed\n *\n * @param {string} name of the flag to"\
" set\n * @returns {string} base64 decoded string\n */\n setFlag("\
"name) {\n this.api.call(`f ${name}=${this.addr}`);\n }\n /**\n * "\
"Remove the flag in the current offset\n *\n */\n unsetFlag() {\n "\
"this.api.call(`f-${this.addr}`);\n }\n /**\n * Render an hexadec"\
"imal dump of the bytes contained in the range starting\n * in "\
"the current pointer and given length.\n *\n * @param {number} l"\
"ength optional amount of bytes to dump, using blocksize\n * @r"\
"eturns {string} string containing the hexadecimal dump of mem"\
"ory\n */\n hexdump(length) {\n const len = length === undefined "\
"? \"\" : \"\" + length;\n return this.api.cmd(`x${len}@${this.addr"\
"}`);\n }\n functionGraph(format) {\n if (format === \"dot\") {\n re"\
"turn this.api.cmd(`agfd@ ${this.addr}`);\n }\n if (format === \""\
"json\") {\n return this.api.cmd(`agfj@${this.addr}`);\n }\n if (f"\
"ormat === \"mermaid\") {\n return this.api.cmd(`agfm@${this.addr"\
"}`);\n }\n return this.api.cmd(`agf@${this.addr}`);\n }\n readByt"\
"eArray(len) {\n return JSON.parse(this.api.cmd(`p8j ${len}@${t"\
"his.addr}`));\n }\n readHexString(len) {\n return (this.api.cmd("\
"`p8 ${len}@${this.addr}`)).trim();\n }\n and(a) {\n const addr ="\
" this.api.call(`?v ${this.addr} & ${a}`);\n return new NativeP"\
"ointer(addr.trim());\n }\n or(a) {\n const addr = this.api.call("\
"`?v ${this.addr} | ${a}`);\n return new NativePointer(addr.tri"\
"m());\n }\n add(a) {\n const addr = this.api.call(`?v ${this.add"\
"r}+${a}`);\n return new NativePointer(addr);\n }\n sub(a) {\n con"\
"st addr = this.api.call(`?v ${this.addr}-${a}`);\n return new "\
"NativePointer(addr);\n }\n writeByteArray(data) {\n this.api.cmd"\
"(\"wx \" + data.join(\"\"));\n return this;\n }\n writeAssembly(inst"\
"ruction) {\n this.api.cmd(`wa ${instruction} @ ${this.addr}`);"\
"\n return this;\n }\n writeCString(s) {\n this.api.call(\"w \" + s)"\
";\n return this;\n }\n writeWideString(s) {\n this.api.call(\"ww \""\
" + s);\n return this;\n }\n /**\n * Check if it's a pointer to th"\
"e address zero. Also known as null pointer.\n *\n * @returns {b"\
"oolean} true if null\n */\n isNull() {\n return (this.toNumber()"\
") == 0;\n }\n /**\n * Compare current pointer with the passed on"\
"e, and return -1, 0 or 1.\n *\n * * if (this < arg) return -1;\n"\
" * * if (this > arg) return 1;\n * * if (this == arg) return 0"\
";\n *\n * @returns {number} returns -1, 0 or 1 depending on the"\
" comparison of the pointers\n */\n compare(a) {\n const bv = typ"\
"eof a === \"string\" || typeof a === \"number\"\n ? new NativePoin"\
"ter(a)\n : a;\n const dist = r2pipe_js_1.r2.call(`?vi ${this.ad"\
"dr} - ${bv.addr}`);\n if (dist[0] === \"-\") {\n return -1;\n }\n i"\
"f (dist[0] === \"0\") {\n return 0;\n }\n return 1;\n }\n /**\n * Che"\
"ck if it's a pointer to the address zero. Also known as null "\
"pointer.\n *\n * @returns {boolean} true if null\n */\n pointsToN"\
"ull() {\n const value = this.readPointer();\n return (value.com"\
"pare(0)) == 0;\n }\n toJSON() {\n const output = this.api.cmd(\"?"\
"vi \" + this.addr.trim());\n return output.trim();\n }\n toString"\
"() {\n return (this.api.cmd(\"?v \" + this.addr.trim())).trim();"\
"\n }\n toNumber() {\n return parseInt(this.toString());\n }\n writ"\
"ePointer(p) {\n }\n readRelativePointer() {\n return this.add(th"\
"is.readS32());\n }\n readPointer() {\n const address = this.api."\
"call(\"pvp@\" + this.addr);\n return new NativePointer(address);"\
"\n }\n readS8() {\n return parseInt(this.api.cmd(`pv1d@${this.ad"\
"dr}`));\n }\n readU8() {\n return parseInt(this.api.cmd(`pv1u@${"\
"this.addr}`));\n }\n readU16() {\n return parseInt(this.api.cmd("\
"`pv2d@${this.addr}`));\n }\n readU16le() {\n }\n readU16be() {\n }"\
"\n readS16() {\n }\n readS16le() {\n }\n readS16be() {\n }\n readS32"\
"() {\n // same as readInt32()\n }\n readU32() {\n }\n readU32le() "\
"{\n }\n readU32be() {\n }\n readU64() {\n // XXX: use bignum or st"\
"ring here\n return parseInt(this.api.cmd(`pv8u@${this.addr}`))"\
";\n }\n readU64le() {\n }\n readU64be() {\n }\n writeInt(n) {\n retu"\
"rn this.writeU32(n);\n }\n /**\n * Write a byte in the current o"\
"ffset, the value must be between 0 and 255\n *\n * @param {stri"\
"ng} n number to write in the pointed byte in the current addr"\
"ess\n * @returns {boolean} false if the operation failed\n */\n "\
"writeU8(n) {\n this.api.cmd(`wv1 ${n}@${this.addr}`);\n return "\
"true;\n }\n writeU16(n) {\n this.api.cmd(`wv2 ${n}@${this.addr}`"\
");\n return true;\n }\n writeU16be(n) {\n this.api.cmd(`wv2 ${n}@"\
"${this.addr}@e:cfg.bigendian=true`);\n return true;\n }\n writeU"\
"16le(n) {\n this.api.cmd(`wv2 ${n}@${this.addr}@e:cfg.bigendia"\
"n=false`);\n return true;\n }\n writeU32(n) {\n this.api.cmd(`wv4"\
" ${n}@${this.addr}`);\n return true;\n }\n writeU32be(n) {\n this"\
".api.cmd(`wv4 ${n}@${this.addr}@e:cfg.bigendian=true`);\n retu"\
"rn true;\n }\n writeU32le(n) {\n this.api.cmd(`wv4 ${n}@${this.a"\
"ddr}@e:cfg.bigendian=false`);\n return true;\n }\n writeU64(n) {"\
"\n this.api.cmd(`wv8 ${n}@${this.addr}`);\n return true;\n }\n wr"\
"iteU64be(n) {\n this.api.cmd(`wv8 ${n}@${this.addr}@e:cfg.bige"\
"ndian=true`);\n return true;\n }\n writeU64le(n) {\n this.api.cmd"\
"(`wv8 ${n}@${this.addr}@e:cfg.bigendian=false`);\n return true"\
";\n }\n readInt32() {\n return this.readU32();\n }\n readCString()"\
" {\n const output = this.api.cmd(`pszj@${this.addr}`);\n return"\
" JSON.parse(output).string;\n }\n readWideString() {\n const out"\
"put = this.api.cmd(`pswj@${this.addr}`);\n return JSON.parse(o"\
"utput).string;\n }\n readPascalString() {\n const output = this."\
"api.cmd(`pspj@${this.addr}`);\n return JSON.parse(output).stri"\
"ng;\n }\n instruction() {\n const output = this.api.cmdj(`aoj@${"\
"this.addr}`);\n return output[0];\n }\n disassemble(length) {\n c"\
"onst len = length === undefined ? \"\" : \"\" + length;\n return t"\
"his.api.cmd(`pd ${len}@${this.addr}`);\n }\n analyzeFunction() "\
"{\n this.api.cmd(\"af@\" + this.addr);\n return this;\n }\n analyze"\
"FunctionRecursively() {\n this.api.cmd(\"afr@\" + this.addr);\n r"\
"eturn this;\n }\n name() {\n return (this.api.cmd(\"fd \" + this.a"\
"ddr)).trim();\n }\n methodName() {\n // TODO: @ should be option"\
"al here, as addr should be passable as argument imho\n return "\
"(this.api.cmd(\"ic.@\" + this.addr)).trim();\n }\n symbolName() {"\
"\n // TODO: @ should be optional here, as addr should be passa"\
"ble as argument imho\n const name = this.api.cmd(\"isj.@\" + thi"\
"s.addr);\n return name.trim();\n }\n getFunction() {\n return thi"\
"s.api.cmdj(\"afij@\" + this.addr);\n }\n basicBlock() {\n return t"\
"his.api.cmdj(\"abj@\" + this.addr);\n }\n functionBasicBlocks() {"\
"\n return this.api.cmdj(\"afbj@\" + this.addr);\n }\n xrefs() {\n r"\
"eturn this.api.cmdj(\"axtj@\" + this.addr);\n }\n}\nexports.Native"\
"Pointer = NativePointer;\nvar R2Papi=R2PapiSync;\n";
"const v = this.cmd(\"e bin.baddr\");\n return new NativePointer("\
"v);\n }\n jsonToTypescript(name, a) {\n let str = `interface ${n"\
"ame} {\\n`;\n if (a.length && a.length > 0) {\n a = a[0];\n }\n fo"\
"r (const k of Object.keys(a)) {\n const typ = typeof a[k];\n co"\
"nst nam = k;\n str += ` ${nam}: ${typ};\\n`;\n }\n return `${str}"\
"}\\n`;\n }\n /**\n * Get the general purpose register size of the"\
" targize architecture in bits\n *\n * @returns {number} the reg"\
"size\n */\n getBits() {\n return +this.cmd(\"-b\");\n }\n /**\n * Get"\
" the name of the arch plugin selected, which tends to be the "\
"same target architecture.\n * Note that on some situations, th"\
"is info will be stored protected bby the AirForce.\n * When us"\
"ing the r2ghidra arch plugin the underlying arch is in `asm.c"\
"pu`:\n *\n * @returns {string} the name of the target architect"\
"ure.\n */\n getArch() {\n return this.cmdTrim(\"-a\");\n }\n callTri"\
"m(x) {\n const res = this.call(x);\n return res.trim();\n }\n cmd"\
"Trim(x) {\n const res = this.cmd(x);\n return res.trim();\n }\n /"\
"**\n * Get the name of the selected CPU for the current select"\
"ed architecture.\n *\n * @returns {string} the value of asm.cpu"\
"\n */\n getCpu() {\n // return this.cmd('-c');\n return this.cmdT"\
"rim(\"-e asm.cpu\"); // use arch.cpu\n }\n // TODO: setEndian, se"\
"tCpu, ...\n setArch(arch, bits) {\n this.cmd(\"-a \" + arch);\n if"\
" (bits !== undefined) {\n this.cmd(\"-b \" + bits);\n }\n }\n setFl"\
"agSpace(name) {\n this.cmd(\"fs \" + name);\n }\n demangleSymbol(l"\
"ang, mangledName) {\n return this.cmdTrim(\"iD \" + lang + \" \" +"\
" mangledName);\n }\n setLogLevel(level) {\n this.cmd(\"e log.leve"\
"l=\" + level);\n }\n /**\n * should return the id for the new map"\
" using the given file descriptor\n */\n // rename to createMap "\
"or mapFile?\n newMap(fd, vaddr, size, paddr, perm, name = \"\") "\
"{\n this.cmd(`om ${fd} ${vaddr} ${size} ${paddr} ${perm} ${nam"\
"e}`);\n }\n at(a) {\n return new NativePointer(a);\n }\n getShell("\
") {\n return new shell_js_1.R2Shell(this);\n }\n // Radare/Frida"\
"\n version() {\n const v = this.r2.cmd(\"?Vq\");\n return v.trim()"\
";\n }\n // Process\n platform() {\n const output = this.r2.cmd(\"u"\
"name\");\n return output.trim();\n }\n arch() {\n const output = t"\
"his.r2.cmd(\"uname -a\");\n return output.trim();\n }\n bits() {\n "\
"const output = this.r2.cmd(\"uname -b\");\n return output.trim()"\
";\n }\n id() {\n // getpid();\n return +this.r2.cmd(\"?vi:$p\");\n }"\
"\n // Other stuff\n printAt(msg, x, y) {\n // see pg, but pg is "\
"obrken :D\n }\n clearScreen() {\n this.r2.cmd(\"!clear\");\n return"\
" this;\n }\n getConfig(key) {\n if (key === \"\") {\n return new Er"\
"ror(\"Empty key\");\n }\n const exist = this.r2.cmd(`e~^${key} =`"\
");\n if (exist.trim() === \"\") {\n return new Error(\"Config key "\
"does not exist\");\n }\n const value = this.r2.call(\"e \" + key);"\
"\n return value.trim();\n }\n setConfig(key, val) {\n this.r2.cal"\
"l(\"e \" + key + \"=\" + val);\n return this;\n }\n getRegisterState"\
"ForEsil() {\n const dre = this.cmdj(\"dre\");\n return this.cmdj("\
"\"dre\");\n }\n getRegisters() {\n // this.r2.log(\"winrar\" + JSON."\
"stringify(JSON.parse(this.r2.cmd(\"drj\")),null, 2) );\n return "\
"this.cmdj(\"drj\");\n }\n resizeFile(newSize) {\n this.cmd(`r ${ne"\
"wSize}`);\n return this;\n }\n insertNullBytes(newSize, at) {\n i"\
"f (at === undefined) {\n at = \"$$\";\n }\n this.cmd(`r+${newSize}"\
"@${at}`);\n return this;\n }\n removeBytes(newSize, at) {\n if (a"\
"t === undefined) {\n at = \"$$\";\n }\n this.cmd(`r-${newSize}@${a"\
"t}`);\n return this;\n }\n seek(addr) {\n this.cmd(`s ${addr}`);\n"\
" return this;\n }\n currentSeek() {\n return new NativePointer(\""\
"$$\");\n }\n seekToRelativeOpcode(nth) {\n this.cmd(`so ${nth}`);"\
"\n return this.currentSeek();\n }\n getBlockSize() {\n return +th"\
"is.cmd(\"b\");\n }\n setBlockSize(a) {\n this.cmd(`b ${a}`);\n retu"\
"rn this;\n }\n countFlags() {\n return Number(this.cmd(\"f~?\"));\n"\
" }\n countFunctions() {\n return Number(this.cmd(\"aflc\"));\n }\n "\
"analyzeFunctionsWithEsil(depth) {\n this.cmd(\"aaef\");\n }\n anal"\
"yzeProgramWithEsil(depth) {\n this.cmd(\"aae\");\n }\n analyzeProg"\
"ram(depth) {\n if (depth === undefined) {\n depth = 0;\n }\n swit"\
"ch (depth) {\n case 0:\n this.cmd(\"aa\");\n break;\n case 1:\n this"\
".cmd(\"aaa\");\n break;\n case 2:\n this.cmd(\"aaaa\");\n break;\n cas"\
"e 3:\n this.cmd(\"aaaaa\");\n break;\n }\n return this;\n }\n enumera"\
"teThreads() {\n // TODO: use apt/dpt to list threads at iterat"\
"e over them to get the registers\n const regs0 = this.cmdj(\"dr"\
"j\");\n const thread0 = {\n context: regs0,\n id: 0,\n state: \"wai"\
"ting\",\n selected: true\n };\n return [thread0];\n }\n currentThre"\
"adId() {\n if (+this.cmd(\"e cfg.debug\")) {\n return +this.cmd(\""\
"dpt.\");\n }\n return this.id();\n }\n setRegisters(obj) {\n for (c"\
"onst r of Object.keys(obj)) {\n const v = obj[r];\n this.r2.cmd"\
"(\"dr \" + r + \"=\" + v);\n }\n }\n hex(s) {\n const output = this.r"\
"2.cmd(\"?v \" + s);\n return output.trim();\n }\n step() {\n this.r"\
"2.cmd(\"ds\");\n return this;\n }\n stepOver() {\n this.r2.cmd(\"dso"\
"\");\n return this;\n }\n math(expr) {\n return +this.r2.cmd(\"?v \""\
" + expr);\n }\n stepUntil(dst) {\n this.cmd(`dsu ${dst}`);\n }\n e"\
"numerateXrefsTo(s) {\n const output = this.call(\"axtq \" + s);\n"\
" return output.trim().split(/\\n/);\n }\n // TODO: rename to sea"\
"rchXrefsTo ?\n findXrefsTo(s, use_esil) {\n if (use_esil) {\n th"\
"is.call(\"/r \" + s);\n }\n else {\n this.call(\"/re \" + s);\n }\n }\n"\
" analyzeFunctionsFromCalls() {\n this.call(\"aac\");\n return thi"\
"s;\n }\n autonameAllFunctions() {\n this.call(\"aan\");\n return th"\
"is;\n }\n analyzeFunctionsWithPreludes() {\n this.call(\"aap\");\n "\
"return this;\n }\n analyzeObjCReferences() {\n this.cmd(\"aao\");\n"\
" return this;\n }\n analyzeImports() {\n this.cmd(\"af @ sym.imp."\
"*\");\n return this;\n }\n searchDisasm(s) {\n const res = this.ca"\
"llj(\"/ad \" + s);\n return res;\n }\n searchString(s) {\n const re"\
"s = this.cmdj(\"/j \" + s);\n return res;\n }\n searchBytes(data) "\
"{\n function num2hex(data) {\n return (data & 0xff).toString(16"\
");\n }\n const s = data.map(num2hex).join(\"\");\n const res = thi"\
"s.cmdj(\"/xj \" + s);\n return res;\n }\n binInfo() {\n try {\n retu"\
"rn this.cmdj(\"ij~{bin}\");\n }\n catch (e) {\n return {};\n }\n }\n "\
"// TODO: take a BinFile as argument instead of number\n select"\
"Binary(id) {\n this.call(`ob ${id}`);\n }\n openFile(name) {\n co"\
"nst ofd = this.call(\"oqq\");\n this.call(`o ${name}`);\n const n"\
"fd = this.call(\"oqq\");\n if (ofd.trim() === nfd.trim()) {\n ret"\
"urn new Error(\"Cannot open file\");\n }\n return parseInt(nfd);\n"\
" }\n openFileNomap(name) {\n const ofd = this.call(\"oqq\");\n thi"\
"s.call(`of ${name}`);\n const nfd = this.call(\"oqq\");\n if (ofd"\
".trim() === nfd.trim()) {\n return new Error(\"Cannot open file"\
"\");\n }\n return parseInt(nfd);\n }\n currentFile(name) {\n const "\
"v = this.call(\"o.\");\n return v.trim();\n }\n enumeratePlugins(t"\
"ype) {\n switch (type) {\n case \"bin\":\n return this.callj(\"Lij\""\
");\n case \"io\":\n return this.callj(\"Loj\");\n case \"core\":\n retu"\
"rn this.callj(\"Lcj\");\n case \"arch\":\n return this.callj(\"LAj\")"\
";\n case \"anal\":\n return this.callj(\"Laj\");\n case \"lang\":\n ret"\
"urn this.callj(\"Llj\");\n }\n return [];\n }\n enumerateModules() "\
"{\n return this.callj(\"dmmj\");\n }\n enumerateFiles() {\n return "\
"this.callj(\"oj\");\n }\n enumerateBinaries() {\n return this.call"\
"j(\"obj\");\n }\n enumerateMaps() {\n return this.callj(\"omj\");\n }"\
"\n enumerateClasses() {\n return this.callj(\"icj\");\n }\n enumera"\
"teSymbols() {\n return this.callj(\"isj\");\n }\n enumerateExports"\
"() {\n return this.callj(\"iEj\");\n }\n enumerateImports() {\n ret"\
"urn this.callj(\"iij\");\n }\n enumerateLibraries() {\n return thi"\
"s.callj(\"ilj\");\n }\n enumerateSections() {\n return this.callj("\
"\"iSj\");\n }\n enumerateSegments() {\n return this.callj(\"iSSj\");"\
"\n }\n enumerateEntrypoints() {\n return this.callj(\"iej\");\n }\n "\
"enumerateRelocations() {\n return this.callj(\"irj\");\n }\n enume"\
"rateFunctions() {\n return this.cmdj(\"aflj\");\n }\n enumerateFla"\
"gs() {\n return this.cmdj(\"fj\");\n }\n skip() {\n this.r2.cmd(\"ds"\
"s\");\n }\n ptr(s) {\n return new NativePointer(s, this);\n }\n cal"\
"l(s) {\n return this.r2.call(s);\n }\n callj(s) {\n const v = thi"\
"s.call(s);\n return JSON.parse(v);\n }\n cmd(s) {\n return this.r"\
"2.cmd(s);\n }\n cmdj(s) {\n const v = this.cmd(s);\n return JSON."\
"parse(v);\n }\n log(s) {\n return this.r2.log(s);\n }\n clippy(msg"\
") {\n const v = this.r2.cmd(\"?E \" + msg);\n this.r2.log(v);\n }\n"\
" ascii(msg) {\n const v = this.r2.cmd(\"?ea \" + msg);\n this.r2."\
"log(v);\n }\n}\nexports.R2PapiSync = R2PapiSync;\n// useful to ca"\
"ll functions via dxc and to define and describe function sign"\
"atures\nclass NativeFunction {\n constructor() { }\n}\nexports.Na"\
"tiveFunction = NativeFunction;\n// uhm not sure how to map thi"\
"s into r2 yet\nclass NativeCallback {\n constructor() { }\n}\nexp"\
"orts.NativeCallback = NativeCallback;\n/**\n * Class providing "\
"a way to work with 64bit pointers from Javascript, this API m"\
"imics the same\n * well-known promitive available in Frida, bu"\
"t it's baked by the current session of r2.\n *\n * It is also p"\
"ossible to use this class via the global `ptr` function.\n *\n "\
"* @typedef NativePointer\n */\nclass NativePointer {\n construct"\
"or(s, api) {\n this.api = api ?? exports.R;\n this.addr = (s =="\
" undefined) ? \"$$\" : (\"\" + s).trim();\n }\n /**\n * Copy N bytes"\
" from current pointer to the destination\n *\n * @param {string"\
"|NativePointer|number} destination address\n * @param {string|"\
"number} amount of bytes\n */\n copyTo(addr, size) {\n this.api.c"\
"all(`wf ${this.addr} ${size} @ ${addr}`);\n }\n /**\n * Copy N b"\
"ytes from given address to the current destination\n *\n * @par"\
"am {string|NativePointer|number} source address\n * @param {st"\
"ring|number} amount of bytes\n */\n copyFrom(addr, size) {\n thi"\
"s.api.call(`wf ${addr} ${size} @ ${this.addr}`);\n }\n /**\n * F"\
"ill N bytes in this address with zero\n *\n * @param {string|nu"\
"mber} amount of bytes\n */\n zeroFill(size) {\n this.api.call(`w"\
"0 ${size} @ ${this.addr}`);\n }\n /**\n * Filter a string to be "\
"used as a valid flag name\n *\n * @param {string} name of the s"\
"ymbol name\n * @returns {string} filtered name to be used as a"\
" flag\n */\n filterFlag(name) {\n return this.api.call(`fD ${nam"\
"e}`);\n }\n /**\n * Set a flag (name) at the offset pointed\n *\n "\
"* @param {string} name of the flag to set\n * @returns {string"\
"} base64 decoded string\n */\n setFlag(name) {\n this.api.call(`"\
"f ${name}=${this.addr}`);\n }\n /**\n * Remove the flag in the c"\
"urrent offset\n *\n */\n unsetFlag() {\n this.api.call(`f-${this."\
"addr}`);\n }\n /**\n * Render an hexadecimal dump of the bytes c"\
"ontained in the range starting\n * in the current pointer and "\
"given length.\n *\n * @param {number} length optional amount of"\
" bytes to dump, using blocksize\n * @returns {string} string c"\
"ontaining the hexadecimal dump of memory\n */\n hexdump(length)"\
" {\n const len = length === undefined ? \"\" : \"\" + length;\n ret"\
"urn this.api.cmd(`x${len}@${this.addr}`);\n }\n functionGraph(f"\
"ormat) {\n if (format === \"dot\") {\n return this.api.cmd(`agfd@"\
" ${this.addr}`);\n }\n if (format === \"json\") {\n return this.ap"\
"i.cmd(`agfj@${this.addr}`);\n }\n if (format === \"mermaid\") {\n "\
"return this.api.cmd(`agfm@${this.addr}`);\n }\n return this.api"\
".cmd(`agf@${this.addr}`);\n }\n readByteArray(len) {\n const v ="\
" this.api.cmd(`p8j ${len}@${this.addr}`);\n return JSON.parse("\
"v);\n }\n readHexString(len) {\n const v = this.api.cmd(`p8 ${le"\
"n}@${this.addr}`);\n return v.trim();\n }\n and(a) {\n const addr"\
" = this.api.call(`?v ${this.addr} & ${a}`);\n return new Nativ"\
"ePointer(addr.trim());\n }\n or(a) {\n const addr = this.api.cal"\
"l(`?v ${this.addr} | ${a}`);\n return new NativePointer(addr.t"\
"rim());\n }\n add(a) {\n const addr = this.api.call(`?v ${this.a"\
"ddr}+${a}`);\n return new NativePointer(addr);\n }\n sub(a) {\n c"\
"onst addr = this.api.call(`?v ${this.addr}-${a}`);\n return ne"\
"w NativePointer(addr);\n }\n writeByteArray(data) {\n this.api.c"\
"md(\"wx \" + data.join(\"\"));\n return this;\n }\n writeAssembly(in"\
"struction) {\n this.api.cmd(`wa ${instruction} @ ${this.addr}`"\
");\n return this;\n }\n writeCString(s) {\n this.api.call(\"w \" + "\
"s);\n return this;\n }\n writeWideString(s) {\n this.api.call(\"ww"\
" \" + s);\n return this;\n }\n /**\n * Check if it's a pointer to "\
"the address zero. Also known as null pointer.\n *\n * @returns "\
"{boolean} true if null\n */\n isNull() {\n const v = this.toNumb"\
"er();\n return v === 0;\n }\n /**\n * Compare current pointer wit"\
"h the passed one, and return -1, 0 or 1.\n *\n * * if (this < a"\
"rg) return -1;\n * * if (this > arg) return 1;\n * * if (this ="\
"= arg) return 0;\n *\n * @returns {number} returns -1, 0 or 1 d"\
"epending on the comparison of the pointers\n */\n compare(a) {\n"\
" const bv = typeof a === \"string\" || typeof a === \"number\"\n ?"\
" new NativePointer(a)\n : a;\n const dist = r2pipe_js_1.r2.call"\
"(`?vi ${this.addr} - ${bv.addr}`);\n if (dist[0] === \"-\") {\n r"\
"eturn -1;\n }\n if (dist[0] === \"0\") {\n return 0;\n }\n return 1;"\
"\n }\n /**\n * Check if it's a pointer to the address zero. Also"\
" known as null pointer.\n *\n * @returns {boolean} true if null"\
"\n */\n pointsToNull() {\n const value = this.readPointer();\n co"\
"nst v = value.compare(0);\n return v == 0;\n }\n toJSON() {\n con"\
"st output = this.api.cmd(\"?vi \" + this.addr.trim());\n return "\
"output.trim();\n }\n toString() {\n const v = this.api.cmd(\"?v \""\
" + this.addr.trim());\n return v.trim();\n }\n toNumber() {\n con"\
"st v = this.toString();\n return parseInt(v);\n }\n writePointer"\
"(p) {\n }\n readRelativePointer() {\n const v = this.readS32();\n"\
" return this.add(v);\n }\n readPointer() {\n const address = thi"\
"s.api.call(\"pvp@\" + this.addr);\n return new NativePointer(add"\
"ress);\n }\n readS8() {\n const v = this.api.cmd(`pv1d@${this.ad"\
"dr}`);\n return parseInt(v);\n }\n readU8() {\n const v = this.ap"\
"i.cmd(`pv1u@${this.addr}`);\n return parseInt(v);\n }\n readU16("\
") {\n const v = this.api.cmd(`pv2d@${this.addr}`);\n return par"\
"seInt(v);\n }\n readU16le() {\n const v = this.api.cmd(`pv2d@${t"\
"his.addr}@e:cfg.bigendian=false`);\n }\n readU16be() {\n const v"\
" = this.api.cmd(`pv2d@${this.addr}@e:cfg.bigendian=true`);\n }"\
"\n readS16() {\n return parseInt(v);\n }\n readS16le() {\n const v"\
" = this.api.cmd(`pv2d@${this.addr}@e:cfg.bigendian=false`);\n "\
"}\n readS16be() {\n const v = this.api.cmd(`pv2d@${this.addr}@e"\
":cfg.bigendian=true`);\n }\n readS32() {\n const v = this.api.cm"\
"d(`pv4d@${this.addr}`);\n return parseInt(v);\n }\n readU32() {\n"\
" const v = this.api.cmd(`pv4u@${this.addr}`);\n return parseIn"\
"t(v);\n }\n readU32le() {\n const v = this.api.cmd(`pv4u@${this."\
"addr}@e:cfg.bigendian=false`);\n }\n readU32be() {\n const v = t"\
"his.api.cmd(`pv4u@${this.addr}@e:cfg.bigendian=true`);\n }\n re"\
"adU64() {\n // XXX: use bignum or string here\n const v = this."\
"api.cmd(`pv8u@${this.addr}`);\n return parseInt(v);\n }\n readU6"\
"4le() {\n const v = this.api.cmd(`pv8u@${this.addr}@e:cfg.bige"\
"ndian=false`);\n }\n readU64be() {\n const v = this.api.cmd(`pv8"\
"u@${this.addr}@e:cfg.bigendian=true`);\n }\n writeInt(n) {\n ret"\
"urn this.writeU32(n);\n }\n /**\n * Write a byte in the current "\
"offset, the value must be between 0 and 255\n *\n * @param {str"\
"ing} n number to write in the pointed byte in the current add"\
"ress\n * @returns {boolean} false if the operation failed\n */\n"\
" writeU8(n) {\n this.api.cmd(`wv1 ${n}@${this.addr}`);\n return"\
" true;\n }\n writeU16(n) {\n this.api.cmd(`wv2 ${n}@${this.addr}"\
"`);\n return true;\n }\n writeU16be(n) {\n this.api.cmd(`wv2 ${n}"\
"@${this.addr}@e:cfg.bigendian=true`);\n return true;\n }\n write"\
"U16le(n) {\n this.api.cmd(`wv2 ${n}@${this.addr}@e:cfg.bigendi"\
"an=false`);\n return true;\n }\n writeU32(n) {\n this.api.cmd(`wv"\
"4 ${n}@${this.addr}`);\n return true;\n }\n writeU32be(n) {\n thi"\
"s.api.cmd(`wv4 ${n}@${this.addr}@e:cfg.bigendian=true`);\n ret"\
"urn true;\n }\n writeU32le(n) {\n this.api.cmd(`wv4 ${n}@${this."\
"addr}@e:cfg.bigendian=false`);\n return true;\n }\n writeU64(n) "\
"{\n this.api.cmd(`wv8 ${n}@${this.addr}`);\n return true;\n }\n w"\
"riteU64be(n) {\n this.api.cmd(`wv8 ${n}@${this.addr}@e:cfg.big"\
"endian=true`);\n return true;\n }\n writeU64le(n) {\n this.api.cm"\
"d(`wv8 ${n}@${this.addr}@e:cfg.bigendian=false`);\n return tru"\
"e;\n }\n readInt32() {\n return this.readU32();\n }\n readCString("\
") {\n const output = this.api.cmd(`pszj@${this.addr}`);\n retur"\
"n JSON.parse(output).string;\n }\n readWideString() {\n const ou"\
"tput = this.api.cmd(`pswj@${this.addr}`);\n return JSON.parse("\
"output).string;\n }\n readPascalString() {\n const output = this"\
".api.cmd(`pspj@${this.addr}`);\n return JSON.parse(output).str"\
"ing;\n }\n instruction() {\n const output = this.api.cmdj(`aoj@$"\
"{this.addr}`);\n return output[0];\n }\n disassemble(length) {\n "\
"const len = length === undefined ? \"\" : \"\" + length;\n return "\
"this.api.cmd(`pd ${len}@${this.addr}`);\n }\n analyzeFunction()"\
" {\n this.api.cmd(\"af@\" + this.addr);\n return this;\n }\n analyz"\
"eFunctionRecursively() {\n this.api.cmd(\"afr@\" + this.addr);\n "\
"return this;\n }\n name() {\n const v = this.api.cmd(\"fd \" + thi"\
"s.addr);\n return v.trim();\n }\n methodName() {\n // TODO: @ sho"\
"uld be optional here, as addr should be passable as argument "\
"imho\n const v = this.api.cmd(\"ic.@\" + this.addr);\n return v.t"\
"rim();\n }\n symbolName() {\n // TODO: @ should be optional here"\
", as addr should be passable as argument imho\n const name = t"\
"his.api.cmd(\"isj.@\" + this.addr);\n return name.trim();\n }\n ge"\
"tFunction() {\n return this.api.cmdj(\"afij@\" + this.addr);\n }\n"\
" basicBlock() {\n return this.api.cmdj(\"abj@\" + this.addr);\n }"\
"\n functionBasicBlocks() {\n return this.api.cmdj(\"afbj@\" + thi"\
"s.addr);\n }\n xrefs() {\n return this.api.cmdj(\"axtj@\" + this.a"\
"ddr);\n }\n}\nexports.NativePointer = NativePointer;\nvar R2Papi="\
"R2PapiSync;\n";

View File

@ -1113,7 +1113,8 @@ class R2PapiSync {
* @returns {NativePointer} address of the base of the binary
*/
getBaseAddress() {
return new NativePointer(this.cmd("e bin.baddr"));
const v = this.cmd("e bin.baddr");
return new NativePointer(v);
}
jsonToTypescript(name, a) {
let str = `interface ${name} {\n`;
@ -1433,7 +1434,8 @@ class R2PapiSync {
return parseInt(nfd);
}
currentFile(name) {
return (this.call("o.")).trim();
const v = this.call("o.");
return v.trim();
}
enumeratePlugins(type) {
switch (type) {
@ -1507,22 +1509,26 @@ class R2PapiSync {
return this.r2.call(s);
}
callj(s) {
return JSON.parse(this.call(s));
const v = this.call(s);
return JSON.parse(v);
}
cmd(s) {
return this.r2.cmd(s);
}
cmdj(s) {
return JSON.parse(this.cmd(s));
const v = this.cmd(s);
return JSON.parse(v);
}
log(s) {
return this.r2.log(s);
}
clippy(msg) {
this.r2.log(this.r2.cmd("?E " + msg));
const v = this.r2.cmd("?E " + msg);
this.r2.log(v);
}
ascii(msg) {
this.r2.log(this.r2.cmd("?ea " + msg));
const v = this.r2.cmd("?ea " + msg);
this.r2.log(v);
}
}
exports.R2PapiSync = R2PapiSync;
@ -1547,7 +1553,33 @@ exports.NativeCallback = NativeCallback;
class NativePointer {
constructor(s, api) {
this.api = api ?? exports.R;
this.addr = ("" + s).trim();
this.addr = (s == undefined) ? "$$" : ("" + s).trim();
}
/**
* Copy N bytes from current pointer to the destination
*
* @param {string|NativePointer|number} destination address
* @param {string|number} amount of bytes
*/
copyTo(addr, size) {
this.api.call(`wf ${this.addr} ${size} @ ${addr}`);
}
/**
* Copy N bytes from given address to the current destination
*
* @param {string|NativePointer|number} source address
* @param {string|number} amount of bytes
*/
copyFrom(addr, size) {
this.api.call(`wf ${addr} ${size} @ ${this.addr}`);
}
/**
* Fill N bytes in this address with zero
*
* @param {string|number} amount of bytes
*/
zeroFill(size) {
this.api.call(`w0 ${size} @ ${this.addr}`);
}
/**
* Filter a string to be used as a valid flag name
@ -1598,10 +1630,12 @@ class NativePointer {
return this.api.cmd(`agf@${this.addr}`);
}
readByteArray(len) {
return JSON.parse(this.api.cmd(`p8j ${len}@${this.addr}`));
const v = this.api.cmd(`p8j ${len}@${this.addr}`);
return JSON.parse(v);
}
readHexString(len) {
return (this.api.cmd(`p8 ${len}@${this.addr}`)).trim();
const v = this.api.cmd(`p8 ${len}@${this.addr}`);
return v.trim();
}
and(a) {
const addr = this.api.call(`?v ${this.addr} & ${a}`);
@ -1641,7 +1675,8 @@ class NativePointer {
* @returns {boolean} true if null
*/
isNull() {
return (this.toNumber()) == 0;
const v = this.toNumber();
return v === 0;
}
/**
* Compare current pointer with the passed one, and return -1, 0 or 1.
@ -1672,62 +1707,82 @@ class NativePointer {
*/
pointsToNull() {
const value = this.readPointer();
return (value.compare(0)) == 0;
const v = value.compare(0);
return v == 0;
}
toJSON() {
const output = this.api.cmd("?vi " + this.addr.trim());
return output.trim();
}
toString() {
return (this.api.cmd("?v " + this.addr.trim())).trim();
const v = this.api.cmd("?v " + this.addr.trim());
return v.trim();
}
toNumber() {
return parseInt(this.toString());
const v = this.toString();
return parseInt(v);
}
writePointer(p) {
}
readRelativePointer() {
return this.add(this.readS32());
const v = this.readS32();
return this.add(v);
}
readPointer() {
const address = this.api.call("pvp@" + this.addr);
return new NativePointer(address);
}
readS8() {
return parseInt(this.api.cmd(`pv1d@${this.addr}`));
const v = this.api.cmd(`pv1d@${this.addr}`);
return parseInt(v);
}
readU8() {
return parseInt(this.api.cmd(`pv1u@${this.addr}`));
const v = this.api.cmd(`pv1u@${this.addr}`);
return parseInt(v);
}
readU16() {
return parseInt(this.api.cmd(`pv2d@${this.addr}`));
const v = this.api.cmd(`pv2d@${this.addr}`);
return parseInt(v);
}
readU16le() {
const v = this.api.cmd(`pv2d@${this.addr}@e:cfg.bigendian=false`);
}
readU16be() {
const v = this.api.cmd(`pv2d@${this.addr}@e:cfg.bigendian=true`);
}
readS16() {
return parseInt(v);
}
readS16le() {
const v = this.api.cmd(`pv2d@${this.addr}@e:cfg.bigendian=false`);
}
readS16be() {
const v = this.api.cmd(`pv2d@${this.addr}@e:cfg.bigendian=true`);
}
readS32() {
// same as readInt32()
const v = this.api.cmd(`pv4d@${this.addr}`);
return parseInt(v);
}
readU32() {
const v = this.api.cmd(`pv4u@${this.addr}`);
return parseInt(v);
}
readU32le() {
const v = this.api.cmd(`pv4u@${this.addr}@e:cfg.bigendian=false`);
}
readU32be() {
const v = this.api.cmd(`pv4u@${this.addr}@e:cfg.bigendian=true`);
}
readU64() {
// XXX: use bignum or string here
return parseInt(this.api.cmd(`pv8u@${this.addr}`));
const v = this.api.cmd(`pv8u@${this.addr}`);
return parseInt(v);
}
readU64le() {
const v = this.api.cmd(`pv8u@${this.addr}@e:cfg.bigendian=false`);
}
readU64be() {
const v = this.api.cmd(`pv8u@${this.addr}@e:cfg.bigendian=true`);
}
writeInt(n) {
return this.writeU32(n);
@ -1810,11 +1865,13 @@ class NativePointer {
return this;
}
name() {
return (this.api.cmd("fd " + this.addr)).trim();
const v = this.api.cmd("fd " + this.addr);
return v.trim();
}
methodName() {
// TODO: @ should be optional here, as addr should be passable as argument imho
return (this.api.cmd("ic.@" + this.addr)).trim();
const v = this.api.cmd("ic.@" + this.addr);
return v.trim();
}
symbolName() {
// TODO: @ should be optional here, as addr should be passable as argument imho