From 8d1abd2266140ffb5bd5811474f09b0d37540f5d Mon Sep 17 00:00:00 2001 From: DavidVentura Date: Thu, 18 Jan 2024 17:17:16 +0100 Subject: [PATCH] implement some more functions --- asd.js | 148 +++++++++++---------------------- func_replacements.js | 191 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 231 insertions(+), 108 deletions(-) diff --git a/asd.js b/asd.js index 2d57789..e941b8c 100644 --- a/asd.js +++ b/asd.js @@ -1,14 +1,14 @@ import { replaceFunctions } from "./func_replacements.js"; -function hook_fn(name_in_elf, enter, leave) { +const hook_fn = (name_in_elf, enter, leave) => { var symbol_addr = DebugSymbol.fromName(name_in_elf).address; - console.log(`${name_in_elf} addr is: ${symbol_addr}`); + console.log(`${name_in_elf} addr is: ${symbol_addr}, this is ${this}`); Interceptor.attach(symbol_addr, { onEnter: enter, onLeave: leave, }); console.log(`Hooked ${name_in_elf}`); -} +}; function hook_export_fn(name_in_elf, enter, leave) { var symbol_addr = Module.findExportByName("libvdp.so", name_in_elf); @@ -39,58 +39,13 @@ const hook_p2p_read = () => { ); }; -const hook_pack_ClntPkt = () => { - let sym = "pack_ClntPkt"; - hook_fn( - sym, - (args) => { - console.log(`onEnter ${sym}`); - - /* - * onEnter pack_ClntPkt - 2 0x7b5ef9c640 - onExit pack_ClntPkt, ret=24 - 0 1 2 3 4 5 6 7 8 9 A B C D E F - 0123456789ABCDEF 00000000 f1 67 00 14 42 41 54 43 00 00 00 00 00 09 4c - fb .g..BATC......L. 00000010 45 58 4c 56 53 00 00 00 EXLVS... - */ - // f1 30 00 00 heartbeat? - // int pack_ClntPkt(int m_type_or_len,ushort *pkt_buf,long - // something_out) - let m_ptype = args[0].toInt32(); - // type = 2 == LanSearch, LanSearchExt, ServerReq, Hello, DevQuery - // 2 = P2P? - // let m_buf = args[1].readByteArray(m_ptype); // len?? - let m_out = args[2]; - this.outBuf = args[2]; - this.inBuf = args[1]; - var trace = Thread.backtrace(this.context, Backtracer.ACCURATE).map( - DebugSymbol.fromAddress, - ); - for (var j in trace) { - console.log(trace[j]); - } - console.log(m_ptype); - }, - (retval) => { - console.log(`onExit ${sym}, ret=${retval.toInt32()}`); - console.log("out\n", this.outBuf.readByteArray(retval.toInt32())); - console.log("in\n", this.inBuf.readByteArray(retval.toInt32())); - console.log( - "############################################################", - ); - }, - ); -}; - const hook___android_log_print = () => { const sym = "__android_log_print"; hook_fn( sym, (args) => { - // (ushort *param_1,int param_2,undefined4 *param_3,undefined8 param_4 - let _prio = args[0].toInt32(); - let _tag = args[1].readCString(); + // let _prio = args[0].toInt32(); + // let _tag = args[1].readCString(); let fmt = args[2].readCString(); // console.log(fmt); // debug if crashes due to missing placeholder const types = placeholderTypes(fmt); // ['s', 'd', ..]` @@ -99,6 +54,8 @@ const hook___android_log_print = () => { s: (x) => x.readCString(), d: (x) => x.toInt32(), u: (x) => x.toInt32(), + z: (x) => x.toInt64(), + l: (x) => x.toInt64(), x: (x) => x.toInt32().toString(16), f: (x) => x.toFloat(), }; @@ -110,72 +67,63 @@ const hook___android_log_print = () => { () => {}, ); }; -const hook_pack_P2pId = () => { - var sym = "pack_P2pId"; - sym = "pack_P2pHdr"; - sym = "Send_Pkt"; - hook_fn( - sym, - (args) => { - console.log(`onEnter ${sym}`); - // (ushort *param_1,int param_2,undefined4 *param_3,undefined8 param_4 - let m_ptype = args[1].toInt32(); - let m_data = args[0].readByteArray(m_ptype); // len?? - let m_sock = args[2]; - let m_p4 = args[3]; - console.log(m_data, m_ptype, m_sock, m_p4); - }, - () => {}, - ); -}; -const hook_create_P2pRdy = () => { - var sym = "create_P2pRdy"; +const hook_in_out_buf = (sym, insize, outsize) => { + let obj = {}; hook_fn( sym, (args) => { - console.log(`onEnter ${sym}`); - // (ushort *param_1,int param_2,undefined4 *param_3,undefined8 param_4 - this.out = args[0]; // u16 ptr - let _in = args[1].readByteArray(2); - console.log("in", _in); + console.log(`onEnter ${sym} ${this}`); + obj.outbuf = args[0]; + obj.inbuf = args[1]; }, (retval) => { - console.log(`onExit ${sym}, retval ${retval}`); - console.log(this.out.readByteArray(0x18)); // _g_p2prdy_size = 0x14, retruns +4 + console.log(`${sym} done, dumping`); + console.log("in"); + console.log(obj.inbuf.readByteArray(insize)); + console.log("out"); + console.log(obj.outbuf.readByteArray(outsize)); + console.log("retval", retval); }, ); }; let indent = 0; -function doHooks() { - var libnative_addr = Module.findBaseAddress("libvdp.so"); + +function doReplaceFunctions() { // const prefixes = ["Send_Pkt*", "P2P*", "*RcvTh*", "parse_*"]; // "XQP2P*", // const prefixes = ["parse_*", "pack_*", "Send_Pkt*", "create_*"]; const prefixes = ["create_*"]; const spam = ["XQP2P_Check_Buffer", "P2P_ChannelBufferCheck"]; + + const replaced = replaceFunctions(); + + prefixes + .map((prefix) => DebugSymbol.findFunctionsMatching(prefix)) + .flat() + .map(DebugSymbol.fromAddress) + .filter((dbg) => !spam.includes(dbg.name)) + .map((dbg) => { + Interceptor.attach(dbg.address, { + onEnter: (args) => { + indent = indent + 1; + let flag = !replaced.includes(dbg.name) ? "[NOT REPLACED] " : ""; + console.log(" ".repeat(indent) + flag + dbg.name); + }, + onLeave: (retval) => { + indent = indent - 1; + }, + }); + console.log(`Hooked ${dbg.name}`); + }); +} +function doHooks() { + var libnative_addr = Module.findBaseAddress("libvdp.so"); if (libnative_addr) { hook___android_log_print(); - hook_create_P2pRdy; - const replaced = replaceFunctions(); - console.log(replaced); - prefixes - .map((prefix) => DebugSymbol.findFunctionsMatching(prefix)) - .flat() - .map(DebugSymbol.fromAddress) - .filter((dbg) => !spam.includes(dbg.name)) - .map((dbg) => { - Interceptor.attach(dbg.address, { - onEnter: (args) => { - indent = indent + 1; - let flag = replaced.includes(dbg.name) ? "[REPLACED] " : ""; - console.log(" ".repeat(indent) + flag + dbg.name); - }, - onLeave: (retval) => { - indent = indent - 1; - }, - }); - console.log(`Hooked ${dbg.name}`); - }); + // hook_create_P2pRdy(); + // hook_in_out_buf("create_LstReq", 0x1c, 0x1c); + hook_in_out_buf("create_P2pRdy", 0x1c, 0x1c); + doReplaceFunctions(); // hook_p2p_read(); // hook_pack_P2pId(); diff --git a/func_replacements.js b/func_replacements.js index 536481d..ee0de00 100644 --- a/func_replacements.js +++ b/func_replacements.js @@ -1,8 +1,18 @@ const pack_P2pHdr = (in_buf, out_buf) => { // shitty memcpy out_buf.writeByteArray(in_buf.readByteArray(4)); - //out_buf.writeU16(in_buf.readU16()); - //out_buf.add(2).writeU16(in_buf.add(2).readU16()); + // out_buf.writeU16(in_buf.readU16()); + // out_buf.add(2).writeU16(in_buf.add(2).readU16()); + return 4; +}; + +const create_Close = (buf) => { + buf.writeByteArray([0xf1, 0xf0, 0x00, 0x00]); + return 4; +}; + +const create_LanSearchExt = (buf) => { + buf.writeByteArray([0xf1, 0x32, 0x00, 0x00]); return 4; }; @@ -21,21 +31,166 @@ const create_P2pAlive = (buf) => { }; const create_Hello = (buf) => { - buf.writeU16(0xf1); - buf.add(2).writeU16(0x0); + buf.writeByteArray([0xf1, 0x0, 0x0, 0x0]); + return 4; }; -export const replace_func = (stub, ret, args) => { - const name_in_elf = stub.name; +const create_P2pRdy = (outbuf, inbuf) => { + // TODO: this is literlly the same as create_LstReq, just different command + /* + * in + 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF + 00000000 42 41 54 43 00 00 00 00 00 09 4c fb 45 58 4c 56 BATC......L.EXLV + 00000010 53 00 00 00 S... + + out + 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF + 00000000 f1 42 00 14 00 00 00 00 42 41 54 43 00 00 00 00 .B......BATC.... + 00000010 00 09 4c fb 45 58 4c 56 53 00 00 00 ..L.EXLVS... + retval 0x18 + */ + const P2PRDY_SIZE = 0x14; + outbuf.writeU16(0x42f1); + outbuf.add(2).writeU16(P2PRDY_SIZE << 8); + outbuf.add(8).writeU64(inbuf.readU64()); + outbuf.add(16).writeU64(inbuf.add(8).readU64()); + outbuf.add(2 * 0xc).writeU32(inbuf.add(16).readU32()); + return P2PRDY_SIZE + 4; +}; + +const create_P2pReq = (outbuf, inbuf, m_s_addr, addr_fam) => { + const P2PREQ_SIZE = 0x24; + + console.log("new p2preq"); + /* + P2P req addr_fam 2 m_s_addr + 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF + 00000000 02 00 00 00 c0 a8 01 64 00 00 00 00 00 00 00 00 .......d........ + + at byte 4 is c0 a8 01 64 which is 192 168 1 100 + + in + 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF + 00000000 42 41 54 43 00 00 00 00 00 09 4c fb 45 58 4c 56 BATC......L.EXLV + + mine + 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF + 00000000 f1 20 00 24 00 00 00 00 42 41 54 43 00 00 00 00 . .$....BATC.... + 00000010 00 09 4c fb 45 58 4c 56 53 00 00 00 00 00 00 00 ..L.EXLVS....... + 00000020 00 00 00 00 00 00 00 00 ........ + + original + 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF + 00000000 f1 20 00 24 00 00 00 00 42 41 54 43 00 00 00 00 . .$....BATC.... + 00000010 00 09 4c fb 45 58 4c 56 53 00 00 00 00 02 00 00 ..L.EXLVS....... + 00000020 64 01 a8 c0 00 00 00 00 d....... + + */ + + //let new_outbuf = Memory.alloc(0x2c); + outbuf.writeU16(0x20f1); + outbuf.add(2).writeU16(P2PREQ_SIZE << 8); + outbuf.add(8).writeU64(inbuf.readU64()); + outbuf.add(16).writeU64(inbuf.add(8).readU64()); + outbuf.add(2 * 0xc).writeU32(inbuf.add(16).readU32()); + + outbuf.add(2 * 0xe).writeByteArray(swap_endianness_u16(m_s_addr)); + outbuf.add(2 * 0xf).writeByteArray(swap_endianness_u16(m_s_addr.add(2))); + + outbuf.add(2 * 0x12).writeU64(0); + outbuf.add(2 * 0x10).writeByteArray(swap_endianness_u32(m_s_addr.add(4))); // ip address + + //og_func(outbuf, inbuf, m_s_addr, addr_fam); + //console.log("in"); + //console.log(inbuf.readByteArray(0x10)); + //console.log("mine"); + //console.log(new_outbuf.readByteArray(0x28)); + //console.log("original"); + //console.log(outbuf.readByteArray(0x28)); + + return P2PREQ_SIZE + 4; +}; +const dbg_create_P2pReq = (og_func) => { + return create_P2pReq; +}; + +const swap_endianness_u16 = (ptr) => { + const bytes = ptr.readU16(); + const swapped = [(bytes & 0xff00) >> 8, bytes & 0x00ff]; + return swapped; +}; +const swap_endianness_u32 = (ptr) => { + const bytes = ptr.readU32(); + const swapped = [ + (bytes & 0xff000000) >> 24, + (bytes & 0x00ff0000) >> 16, + (bytes & 0x0000ff00) >> 8, + bytes & 0x000000ff, + ]; + return swapped; +}; +const create_LstReq = (outbuf, inbuf) => { + /* original + in + 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0123456789ABCDEF 00000000 42 41 54 43 00 00 00 00 00 09 4c fb 45 58 4c 56 + BATC......L.EXLV 00000010 53 00 00 00 00 00 00 00 00 00 00 00 S........... + + out + 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0123456789ABCDEF 00000000 f1 67 00 14 00 00 00 00 42 41 54 43 00 00 00 00 + .g......BATC.... 00000010 00 09 4c fb 45 58 4c 56 53 00 00 00 ..L.EXLVS... + retval 0x18 + + */ + const LISTREQ_SIZE = 0x14; + outbuf.writeU16(0x67f1); + outbuf.add(2).writeU16(LISTREQ_SIZE << 8); + + // 4 * sizeof(short) + outbuf.add(8).writeU64(inbuf.readU64()); + // 8 * sizeof(short) + outbuf.add(16).writeU64(inbuf.add(8).readU64()); + // 8 * sizeof(short) + outbuf.add(2 * 0xc).writeU32(inbuf.add(0x10).readU32()); + + /* + let new_outbuf = Memory.alloc(0x1c); + og_func(new_outbuf, inbuf); + console.log("mine"); + console.log(outbuf.readByteArray(0x1c)); + console.log("original"); + console.log(new_outbuf.readByteArray(0x1c)); + */ + + return LISTREQ_SIZE + 4; // this is actually wrong (and unused) in the code -- it is 0x1c +}; + +export const replace_func = (stub, ret, args, pass_orig) => { + const name_in_elf = stub.name.replace("dbg_", ""); // UGH FIXME const symbol_addr = DebugSymbol.fromName(name_in_elf).address; if (symbol_addr == 0) { console.error(`Could not find ${name_in_elf}`); return; } + + const orig_func = new NativeFunction(symbol_addr, ret, args); + + let replacement_func; + if (pass_orig) { + replacement_func = stub(orig_func); + } else { + replacement_func = stub; + } + console.log( `Replacing ${name_in_elf}, signature "${ret} ${name_in_elf}(${args})"`, ); - Interceptor.replace(symbol_addr, new NativeCallback(stub, ret, args)); + + Interceptor.replace( + symbol_addr, + new NativeCallback(replacement_func, ret, args), + ); }; /* Send_Pkt_LanSearch = @@ -52,14 +207,34 @@ export const replace_func = (stub, ret, args) => { /* pack_ClntPkt = * pack_P2pHdr * pack_ - * RSLgnEx, RlyReq4, RlyPortAck, RlyPortExAck, RlyReqEx, Drw, HelloToAck, DrwAck, DevLgn4, LanSearchExtAck, P2pReq4, RSLGn + * RSLgnEx, RlyReq4, RlyPortAck, RlyPortExAck, RlyReqEx, Drw, HelloToAck, + * DrwAck, DevLgn4, LanSearchExtAck, P2pReq4, RSLGn + */ +/* + hard + [NOT REPLACED] create_Drw + [NOT REPLACED] create_DrwAck + [NOT REPLACED] create_P2pReq */ export const replaceFunctions = () => { const replacements = [ [create_P2pAlive, "uchar", ["pointer"]], [create_P2pAliveAck, "uchar", ["pointer"]], [create_LanSearch, "uchar", ["pointer"]], + [create_LanSearchExt, "uchar", ["pointer"]], [create_Hello, "uchar", ["pointer"]], + [create_Close, "uchar", ["pointer"]], + /* + [ + dbg_create_P2pReq, + "uchar", + ["pointer", "pointer", "pointer", "uint"], + true, + ], + */ + [create_P2pReq, "uchar", ["pointer", "pointer", "pointer", "uint"]], + [create_LstReq, "uchar", ["pointer", "pointer"]], + [create_P2pRdy, "uchar", ["pointer", "pointer"]], [pack_P2pHdr, "uchar", ["pointer", "pointer"]], ];