diff --git a/asd.js b/asd.js index 585b837..cde1bac 100644 --- a/asd.js +++ b/asd.js @@ -1,4 +1,5 @@ import { replaceFunctions, Commands, CommandsByValue, u16_swap } from "./func_replacements.js"; +import { placeholderTypes, sprintf } from "./utils.js"; const hook_fn = (name_in_elf, enter, leave) => { var symbol_addr = DebugSymbol.fromName(name_in_elf).address; @@ -47,8 +48,8 @@ const hook___android_log_print = () => { // 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', ..]` + // console.log(fmt, types); // debug if crashes due to missing placeholder let o = { s: (x) => x.readCString(), @@ -98,6 +99,7 @@ const hook_udpsend = () => { } }, ); + let s = {}; hook_fn( "PktSeq_seqGet", @@ -110,6 +112,42 @@ const hook_udpsend = () => { console.log(data); }, ); + + let e = {}; + hook_fn( + "XqBytesEnc", + (args) => { + s.buf_ptr = args[0]; + s.m_buflen = args[1].toInt32(); + s.param3 = args[2].toInt32(); + s.buf_in = s.buf_ptr.readByteArray(s.m_buflen); + }, + (retval) => { + const bufout = s.buf_ptr.readByteArray(s.m_buflen); + console.log(`XqBytesEnc buflen: ${s.m_buflen}, param3: ${s.param3}, buf_in:`); + console.log(s.buf_in); + console.log(`bufout`); + console.log(bufout); + }, + ); + + let d = {}; + hook_fn( + "XqBytesDec", + (args) => { + s.buf_ptr = args[0]; + s.m_buflen = args[1].toInt32(); + s.param3 = args[2].toInt32(); + s.buf_in = s.buf_ptr.readByteArray(s.m_buflen); + }, + (retval) => { + const bufout = s.buf_ptr.readByteArray(s.m_buflen); + console.log(`XqBytesDec buflen: ${s.m_buflen}, param3: ${s.param3}, buf_in:`); + console.log(s.buf_in); + console.log(`bufout`); + console.log(bufout); + }, + ); }; const hook_in_out_buf = (sym, insize, outsize) => { @@ -190,22 +228,4 @@ function doHooks() { console.log("NO WORKING"); } } - -const matchy = /%[0-9.-]*([a-z])/g; -const replacy = /(.*?)%[0-9.-]*([a-z])/g; - -const placeholderTypes = (str) => { - // '%-16s, line %4d, %-16s:ret=%d,broadcast lan_seach to %s:%.3f!!!!' - // => - // [ 's', 'd', 's', 'd', 's', 'f' ] - return [...str.matchAll(matchy)].map((m) => m[1]); -}; -const sprintf = (str, values) => { - // '%-16s, line %4d, %-16s:ret=%d,broadcast lan_seach to %s:%.3f!!!!' + - // ["asd", 20, ...] - // => - // asd, line 20, ... - const matches = str.matchAll(replacy); - return [...matches].map((m, idx) => m[1] + values[idx].toString()).join(""); -}; setImmediate(doHooks); diff --git a/func_replacements.js b/func_replacements.js index a796be0..fb0dc0c 100644 --- a/func_replacements.js +++ b/func_replacements.js @@ -1,8 +1,45 @@ export const u16_swap = (x) => ((x & 0xff00) >> 8) | ((x & 0x00ff) << 8); +export const XqBytesDec = (inoutbuf, buflen, rotate) => { + let new_buf = new Uint8Array(buflen); + new_buf.fill(0x1); + for (let i = 0; i < buflen; i++) { + let b = inoutbuf.add(i).readU8(); + if ((b & 1) != 0) { + new_buf[i] = b - 1; + } else { + new_buf[i] = b + 1; + } + } + for (let i = rotate; i < buflen; i++) { + inoutbuf.add(i).writeU8(new_buf[i - rotate]); + } + for (let i = 0; i < rotate; i++) { + inoutbuf.add(i).writeU8(new_buf[buflen - rotate + i]); + } +}; +export const XqBytesEnc = (inoutbuf, buflen, rotate) => { + let new_buf = new Uint8Array(buflen); + new_buf.fill(0x1); + for (let i = 0; i < buflen; i++) { + let b = inoutbuf.add(i).readU8(); + if ((b & 1) != 0) { + new_buf[i] = b - 1; + } else { + new_buf[i] = b + 1; + } + } + for (let i = 0; i < buflen - rotate; i++) { + inoutbuf.add(i).writeU8(new_buf[i + rotate]); + } + for (let i = 0; i < rotate; i++) { + inoutbuf.add(buflen - rotate + i).writeU8(new_buf[i]); + } +}; + const swap_endianness_u16 = (ptr) => { const bytes = ptr.readU16(); - const swapped = [ (bytes & 0xff00) >> 8, bytes & 0x00ff ]; + const swapped = [(bytes & 0xff00) >> 8, bytes & 0x00ff]; return swapped; }; const swap_endianness_u32 = (ptr) => { @@ -43,28 +80,28 @@ const compare_buf = (a, b, len) => { }; export const Commands = { - Close : 0xf1f0, - LanSearchExt : 0xf132, - LanSearch : 0xf130, - P2PAlive : 0xf1e0, - P2PAliveAck : 0xf1e1, - Hello : 0xf100, - P2pRdy : 0xf142, - P2pReq : 0xf120, - LstReq : 0xf167, - DrwAck : 0xf1d1, - Drw : 0xf1d0, + Close: 0xf1f0, + LanSearchExt: 0xf132, + LanSearch: 0xf130, + P2PAlive: 0xf1e0, + P2PAliveAck: 0xf1e1, + Hello: 0xf100, + P2pRdy: 0xf142, + P2pReq: 0xf120, + LstReq: 0xf167, + DrwAck: 0xf1d1, + Drw: 0xf1d0, // From CSession_CtrlPkt_Proc, incomplete - PunchTo : 0xf140, - PunchPkt : 0xf141, - HelloAck : 0xf101, - RlyTo : 0xf102, - DevLgnAck : 0xf111, - P2PReqAck : 0xf121, - ListenReqAck : 0xf169, - RlyHelloAck : 0xf170, // always - RlyHelloAck2 : 0xf171, // if len >1?? + PunchTo: 0xf140, + PunchPkt: 0xf141, + HelloAck: 0xf101, + RlyTo: 0xf102, + DevLgnAck: 0xf111, + P2PReqAck: 0xf121, + ListenReqAck: 0xf169, + RlyHelloAck: 0xf170, // always + RlyHelloAck2: 0xf171, // if len >1?? }; export const CommandsByValue = Object.keys(Commands).reduce((acc, cur) => { @@ -72,7 +109,7 @@ export const CommandsByValue = Object.keys(Commands).reduce((acc, cur) => { return acc; }, {}); -export const reply_Drw = (inbuf, outbuf) => { +const reply_Drw = (inbuf, outbuf) => { /* -> cmd = inbuf+10 -> chan = inbuf+9 @@ -87,11 +124,11 @@ export const reply_Drw = (inbuf, outbuf) => { const chan = inbuf.add(9).readU16(); const cmd = inbuf.add(10).readU16(); const param2 = 0xd2; // ? - const half_len = 1; // FIXME - const bare_ack = Memory.alloc(half_len * 2 + 8); + const half_len = 1; // FIXME u16_swap(inbuf.add(0xc).readU16()); + const bare_ack = Memory.alloc(half_len * 2 + 8 + 4); // fixme +4 create_DrwAck(bare_ack, param2, chan, half_len, inbuf); const hdr_len = pack_P2pHdr(bare_ack, outbuf); - pack_DrwAck(bare_ack + 4, half_len * 2 + 4, outbuf.add(hdr_len)); + pack_DrwAck(bare_ack.add(4), half_len * 2 + 4, outbuf.add(hdr_len)); }; const pack_P2pHdr = (inbuf, out_buf) => { // shitty memcpy @@ -100,10 +137,10 @@ const pack_P2pHdr = (inbuf, out_buf) => { }; const writeCommand2 = (command, buf) => { - buf.writeByteArray([ (command & 0xff00) >> 8, command & 0xff ]); + buf.writeByteArray([(command & 0xff00) >> 8, command & 0xff]); }; const writeCommand4 = (command, buf) => { - buf.writeByteArray([ (command & 0xff00) >> 8, command & 0xff, 0x00, 0x00 ]); + buf.writeByteArray([(command & 0xff00) >> 8, command & 0xff, 0x00, 0x00]); }; const create_Close = (buf) => { writeCommand4(Commands.Close, buf); @@ -147,8 +184,6 @@ const create_P2pRdy = (outbuf, inbuf) => { return P2PRDY_SIZE + 4; }; -create_P2pRdy(new ArrayBuffer(16), ...); - const create_P2pReq = (outbuf, inbuf, m_s_addr, addr_fam) => { const P2PREQ_SIZE = 0x24; writeCommand2(Commands.P2pReq, outbuf); @@ -161,8 +196,7 @@ const create_P2pReq = (outbuf, inbuf, m_s_addr, addr_fam) => { 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 + outbuf.add(2 * 0x10).writeByteArray(swap_endianness_u32(m_s_addr.add(4))); // ip address return P2PREQ_SIZE + 4; }; @@ -192,8 +226,7 @@ const create_LstReq = (outbuf, inbuf) => { // 0xc * sizeof(short) outbuf.add(2 * 0xc).writeU32(inbuf.add(0x10).readU32()); - return LISTREQ_SIZE + - 4; // this is actually wrong (and unused) in the code -- it is 0x1c + return LISTREQ_SIZE + 4; // this is actually wrong (and unused) in the code -- it is 0x1c }; const create_DrwAck = (outbuf, idk_param2, channel, half_len, inbuf) => { @@ -210,15 +243,14 @@ const create_DrwAck = (outbuf, idk_param2, channel, half_len, inbuf) => { }; const dbg_create_Drw = (og_func) => { - const create_Drw = - (outbuf, idk_param2, idk_param3, idk_param4, copy_len, inbuf) => { - /// idk_param4 goes up by 0x100 per call + const create_Drw = (outbuf, idk_param2, idk_param3, idk_param4, copy_len, inbuf) => { + /// idk_param4 goes up by 0x100 per call - // console.log( - // `2: ${idk_param2.toString(16)} 3: ${idk_param3.toString(16)} 4: - // ${idk_param4.toString(16)} copylen: ${copy_len}`, - //); - /* + // console.log( + // `2: ${idk_param2.toString(16)} 3: ${idk_param3.toString(16)} 4: + // ${idk_param4.toString(16)} copylen: ${copy_len}`, + //); + /* * 2: ffffffd1 3: 0 4: 3100 copylen: 44 In buffer 0 1 2 3 4 5 6 7 8 9 A B C D E F @@ -237,22 +269,21 @@ const dbg_create_Drw = (og_func) => { ................ 00000030 01 01 01 01 */ - const copy_len_swapped = u16_swap(copy_len + 4); - writeCommand2(Commands.Drw, outbuf); - outbuf.add(2).writeU16(copy_len_swapped); - outbuf.add(8).writeU8(0xd1); - outbuf.add(10).writeU16(idk_param4); - outbuf.add(12).writeByteArray(inbuf.readByteArray(copy_len)); + const copy_len_swapped = u16_swap(copy_len + 4); + writeCommand2(Commands.Drw, outbuf); + outbuf.add(2).writeU16(copy_len_swapped); + outbuf.add(8).writeU8(0xd1); + outbuf.add(10).writeU16(idk_param4); + outbuf.add(12).writeByteArray(inbuf.readByteArray(copy_len)); - return copy_len + 8; - }; + return copy_len + 8; + }; return create_Drw; }; const dbg_pack_ClntPkt = (og_func) => { const pack_ClntPkt = (addr_fam, inbuf, outbuf) => { const cmd = u16_swap(inbuf.readU16()); - console.log(`pack_ClntPkt: cmd 0x${cmd.toString(16)} = ${ - CommandsByValue[cmd]}; fam ${addr_fam}; inbuf =>`); + console.log(`pack_ClntPkt: cmd 0x${cmd.toString(16)} = ${CommandsByValue[cmd]}; fam ${addr_fam}; inbuf =>`); // console.log(inbuf.readByteArray(16)); // const ret = og_func(addr_fam, inbuf, outbuf); @@ -260,19 +291,17 @@ const dbg_pack_ClntPkt = (og_func) => { // const new_outbuf = Memory.alloc(ret); const hdrLen = pack_P2pHdr(inbuf, outbuf); const packFn = { - [Commands.LanSearch] : () => hdrLen, - [Commands.LanSearchExt] : () => hdrLen, - [Commands.Close] : () => hdrLen, - [Commands.Hello] : () => hdrLen, - [Commands.P2pReq] : () => - hdrLen + pack_P2pReq4(inbuf.add(8), outbuf.add(hdrLen)), - [Commands.LstReq] : () => - hdrLen + pack_P2pId(inbuf.add(8), outbuf.add(hdrLen)), - [Commands.DrwAck] : () => { + [Commands.LanSearch]: () => hdrLen, + [Commands.LanSearchExt]: () => hdrLen, + [Commands.Close]: () => hdrLen, + [Commands.Hello]: () => hdrLen, + [Commands.P2pReq]: () => hdrLen + pack_P2pReq4(inbuf.add(8), outbuf.add(hdrLen)), + [Commands.LstReq]: () => hdrLen + pack_P2pId(inbuf.add(8), outbuf.add(hdrLen)), + [Commands.DrwAck]: () => { const pkt_size = u16_swap(inbuf.add(2).readU16()); return hdrLen + pack_DrwAck(inbuf.add(8), pkt_size, outbuf.add(hdrLen)); }, - [Commands.Drw] : () => { + [Commands.Drw]: () => { const pkt_size = u16_swap(inbuf.add(2).readU16()); return hdrLen + pack_Drw(inbuf.add(8), pkt_size, outbuf.add(hdrLen)); }, @@ -306,8 +335,7 @@ const pack_Drw = (inbuf, m_pkt_size, outbuf) => { outbuf.writeU8(inbuf.readU8()); outbuf.add(1).writeU8(inbuf.add(1).readU8()); outbuf.add(2).writeU16(inbuf.add(2).readU16()); - outbuf.add(4).writeByteArray( - inbuf.add(4).readByteArray(m_pkt_size - DRW_HDR_SIZE)); + outbuf.add(4).writeByteArray(inbuf.add(4).readByteArray(m_pkt_size - DRW_HDR_SIZE)); return m_pkt_size; }; @@ -319,8 +347,7 @@ const pack_DrwAck = (inbuf, m_pkt_size, outbuf) => { outbuf.writeU8(inbuf.readU8()); outbuf.add(1).writeU8(inbuf.add(1).readU8()); outbuf.add(2).writeU16(inbuf.add(2).readU16()); - outbuf.add(4).writeByteArray( - inbuf.add(4).readByteArray(m_pkt_size - DRW_ACK_HDR_SIZE)); + outbuf.add(4).writeByteArray(inbuf.add(4).readByteArray(m_pkt_size - DRW_ACK_HDR_SIZE)); return m_pkt_size; }; @@ -339,7 +366,7 @@ const pack_P2pReq4 = (inbuf, outbuf) => { return 0x24; }; -export const replace_func = (stub, ret, args) => { +const replace_func = (stub, ret, args) => { const name_in_elf = stub.name.replace("dbg_", ""); // UGH FIXME const symbol_addr = DebugSymbol.fromName(name_in_elf).address; if (symbol_addr == 0) { @@ -356,11 +383,9 @@ export const replace_func = (stub, ret, args) => { replacement_func = stub; } - console.log( - `Replacing ${name_in_elf}, signature "${ret} ${name_in_elf}(${args})"`); + console.log(`Replacing ${name_in_elf}, signature "${ret} ${name_in_elf}(${args})"`); - Interceptor.replace(symbol_addr, - new NativeCallback(replacement_func, ret, args)); + Interceptor.replace(symbol_addr, new NativeCallback(replacement_func, ret, args)); }; /* Send_Pkt_LanSearch = @@ -378,31 +403,40 @@ export const replace_func = (stub, ret, args) => { // CSession_CtrlPkt_Proc(struct, *cmd) == control? export const replaceFunctions = () => { const replacements = [ - [ create_P2pAlive, "uint8", [ "pointer" ] ], - [ create_P2pAliveAck, "uint8", [ "pointer" ] ], - [ create_LanSearch, "uint8", [ "pointer" ] ], - [ create_LanSearchExt, "uint8", [ "pointer" ] ], - [ create_Hello, "uint8", [ "pointer" ] ], - [ create_Close, "uint8", [ "pointer" ] ], - [ - dbg_create_Drw, "uint", - [ "pointer", "uint64", "uint8", "uint16", "uint32", "pointer" ] - ], - [ - create_DrwAck, "uint", - [ "pointer", "uint8", "uint8", "uint16", "pointer" ] - ], - [ create_P2pReq, "uint8", [ "pointer", "pointer", "pointer", "uint" ] ], - [ create_LstReq, "uint8", [ "pointer", "pointer" ] ], - [ create_P2pRdy, "uint8", [ "pointer", "pointer" ] ], - [ pack_P2pHdr, "uint8", [ "pointer", "pointer" ] ], - [ pack_Drw, "uint8", [ "pointer", "uint16", "pointer" ] ], - [ pack_DrwAck, "uint8", [ "pointer", "uint16", "pointer" ] ], - [ pack_P2pId, "uint32", [ "pointer", "pointer" ] ], - [ pack_P2pReq4, "uint64", [ "pointer", "pointer" ] ], - [ dbg_pack_ClntPkt, "uint32", [ "uint32", "pointer", "pointer" ] ], + [create_P2pAlive, "uint8", ["pointer"]], + [create_P2pAliveAck, "uint8", ["pointer"]], + [create_LanSearch, "uint8", ["pointer"]], + [create_LanSearchExt, "uint8", ["pointer"]], + [create_Hello, "uint8", ["pointer"]], + [create_Close, "uint8", ["pointer"]], + [dbg_create_Drw, "uint", ["pointer", "uint64", "uint8", "uint16", "uint32", "pointer"]], + [create_DrwAck, "uint", ["pointer", "uint8", "uint8", "uint16", "pointer"]], + [create_P2pReq, "uint8", ["pointer", "pointer", "pointer", "uint"]], + [create_LstReq, "uint8", ["pointer", "pointer"]], + [create_P2pRdy, "uint8", ["pointer", "pointer"]], + [pack_P2pHdr, "uint8", ["pointer", "pointer"]], + [pack_Drw, "uint8", ["pointer", "uint16", "pointer"]], + [pack_DrwAck, "uint8", ["pointer", "uint16", "pointer"]], + [pack_P2pId, "uint32", ["pointer", "pointer"]], + [pack_P2pReq4, "uint64", ["pointer", "pointer"]], + [dbg_pack_ClntPkt, "uint32", ["uint32", "pointer", "pointer"]], ]; replacements.forEach((x) => replace_func(...x)); return replacements.map((x) => x[0].name.replace("dbg_", "")); }; + +const setMemory = (m) => { + global.Memory = m; +}; +/* +module.exports = { + replaceFunctions, + u16_swap, + Commands, + CommandsByValue, + reply_Drw, + replace_func, + setMemory, +}; +*/ diff --git a/shim.js b/shim.js index c04ac52..6a3feda 100644 --- a/shim.js +++ b/shim.js @@ -37,3 +37,12 @@ DataView.prototype.readByteArray = function (len) { } return ret; }; + +const Memory = { + alloc: (len) => new DataView(new ArrayBuffer(len + 1)), + copy: (outbuf, inbuf, len) => outbuf.writeByteArray(inbuf.readByteArray(len)), +}; + +//module.exports = { +// Memory, +//}; diff --git a/tests/fn.test.js b/tests/fn.test.js new file mode 100644 index 0000000..51ff1df --- /dev/null +++ b/tests/fn.test.js @@ -0,0 +1,91 @@ +import "../shim.js"; + +import assert from "assert"; + +import { placeholderTypes, sprintf } from "../utils.js"; +import { XqBytesDec, XqBytesEnc } from "../func_replacements.js"; + +describe("debug_tools", () => { + it("parses printed data", () => { + const fmt = "string: %s, int: %d, float: %f, hexint: %02x, newline: \n\n last int: %d"; + const expected_placeholders = ["s", "d", "f", "x", "d"]; + const actual_placeholders = placeholderTypes(fmt); + assert.deepEqual(actual_placeholders, expected_placeholders); + }); + it("prints data back", () => { + const fmt = "string: %s, int: %d, float: %f, hexint: %02x, newline: \n\n last int: %d"; + const in_values = ["potato", 5, 3.5, 0x20, 999]; + const expected_string = "string: potato, int: 5, float: 3.5, hexint: 0x20, newline: \n\n last int: 999"; + assert.deepEqual(sprintf(fmt, in_values), expected_string); + }); +}); + +describe("module", () => { + const simple_enc_bytes = new Uint8Array([ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + ]); + const simple_dec_bytes = new Uint8Array([ + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]); + const long_enc_bytes = new Uint8Array([ + 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x43, 0x40, 0x55, 0x42, 0x37, 0x31, 0x38, 0x34, 0x32, 0x30, 0x44, 0x59, 0x4d, 0x57, 0x52, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x30, 0x33, 0x32, 0x35, 0x34, + 0x37, 0x36, 0x39, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x31, 0x2f, 0x33, 0x34, 0x34, 0x2f, 0x33, 0x34, 0x34, 0x2f, + 0x33, 0x34, 0x34, 0x01, 0x01, 0x01, 0x31, 0x2f, 0x31, 0x2f, 0x31, 0x2f, 0x31, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x31, 0x2f, 0x31, 0x2f, 0x31, 0x2f, 0x31, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x31, 0x2f, 0x31, 0x2f, 0x31, 0x2f, 0x31, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x31, 0x2f, 0x31, + 0x2f, 0x31, 0x2f, 0x31, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + ]); + const long_dec_bytes = new Uint8Array([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x41, 0x54, 0x43, 0x36, 0x30, 0x39, 0x35, 0x33, 0x31, 0x45, 0x58, 0x4c, 0x56, + 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x2e, 0x32, 0x35, 0x35, 0x2e, + 0x32, 0x35, 0x35, 0x2e, 0x32, 0x35, 0x35, 0x00, 0x00, 0x00, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]); + it("decrypts simple input", () => { + const in_buf = new DataView(simple_enc_bytes.buffer.slice(0)); + XqBytesDec(in_buf, simple_enc_bytes.byteLength, 4); // this mutates in_buf + assert.deepEqual(new Uint8Array(in_buf.buffer), simple_dec_bytes); + }); + it("decrypts more complex input", () => { + const in_buf = new DataView(long_enc_bytes.buffer.slice(0)); + XqBytesDec(in_buf, long_enc_bytes.byteLength, 4); // this mutates in_buf + assert.deepEqual(new Uint8Array(in_buf.buffer), long_dec_bytes); + }); + it("encrypts simple input", () => { + const in_buf = new DataView(simple_dec_bytes.buffer.slice(0)); + XqBytesEnc(in_buf, simple_dec_bytes.byteLength, 4); // this mutates in_buf + assert.deepEqual(new Uint8Array(in_buf.buffer), simple_enc_bytes); + }); + it("encrypts more complex input", () => { + const in_buf = new DataView(long_dec_bytes.buffer.slice(0)); + XqBytesEnc(in_buf, long_dec_bytes.byteLength, 4); // this mutates in_buf + assert.deepEqual(new Uint8Array(in_buf.buffer), long_enc_bytes); + }); + it("reverts Enc with Dec", () => { + const in_buf = new DataView(long_dec_bytes.buffer.slice(0)); + XqBytesEnc(in_buf, long_dec_bytes.byteLength, 4); // this mutates in_buf + assert.deepEqual(new Uint8Array(in_buf.buffer), long_enc_bytes); // ENC + XqBytesDec(in_buf, long_dec_bytes.byteLength, 4); // this mutates in_buf + assert.deepEqual(new Uint8Array(in_buf.buffer), long_dec_bytes); //DEC + }); +}); diff --git a/utils.js b/utils.js new file mode 100644 index 0000000..4653c46 --- /dev/null +++ b/utils.js @@ -0,0 +1,23 @@ +const matchy = /%[0-9.-]*([a-z])/g; +const replacy = /(?
.*?)%(?[0-9.-]+)*(?[a-z])/gs;
+
+export const placeholderTypes = (str) => {
+  // '%-16s, line %4d, %-16s:ret=%d,broadcast lan_seach to %s:%.3f!!!!'
+  // =>
+  // [ 's', 'd', 's', 'd', 's', 'f' ]
+  return [...str.matchAll(matchy)].map((m) => m[1]);
+};
+export const sprintf = (str, values) => {
+  // '%-16s, line %4d, %-16s:ret=%d,broadcast lan_seach to %s:%.3f!!!!' +
+  // ["asd", 20, ...]
+  // =>
+  // asd, line 20, ...
+  const matches = str.matchAll(replacy);
+  return [...matches]
+    .map((m, idx) => {
+      const cur = values[idx];
+      const val = m.groups.formatter == "x" ? `0x${cur.toString(16)}` : cur.toString();
+      return m.groups.pre + val;
+    })
+    .join("");
+};