功能: 内嵌quickjs bytecode的程序, 程序带了符号表
思路: 下载quickjs源码, 修改源码(读取bytecode时输出反汇编结果)
https://github.com/horhof/quickjs/archive/20200119.zip
较新版的quickjs-opcode.h中 少了个opcode(get_super_ctor)
20200119这个版本正常;
太旧的也不行, 少的opcode更多
// bytecode的位置: .data:00458040 unsigned char qjsc_s[988]; // 编译选项: -DCONFIG_BIGNUM -DDUMP_BYTECODE=1 // quickjs.c JS_ReadObjectRec(...) { // ... case BC_TAG_FUNCTION_BYTECODE: // ... js_dump_function_bytecode(ctx, b); // << break; // ... } int main(int argc, char *argv[]) { const char *name = "5ADACAEBF4B4A8A4"; const char *sn = "31430057b0557020141973402736"; memcpy(&qjsc_s[23], name, strlen(name)); memcpy(&qjsc_s[40], sn, strlen(sn)); JSRuntime *rt = JS_NewRuntime(); JSContext *ctx = JS_NewContextRaw(rt); JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL); JS_AddIntrinsicBaseObjects(ctx); JS_AddIntrinsicBigInt(ctx); js_std_add_helpers(ctx, argc, argv); js_std_eval_binary(ctx, qjsc_s, sizeof(qjsc_s), 0); js_std_loop(ctx); JS_FreeContext(ctx); JS_FreeRuntime(rt); return 0; }
bytecode 反汇编结果
s:1: function: <eval> locals: 0: var <ret> stack_size: 6 opcodes: check_define_var un,0 check_define_var sn,0 check_define_var s,0 check_define_var i,0 check_define_var j,0 check_define_var k,0 check_define_var l,0 check_define_var m,0 check_define_var n,0 check_define_var i,0 define_var un,0 define_var sn,0 define_var s,0 define_var i,0 define_var j,0 define_var k,0 define_var l,0 define_var m,0 define_var n,0 define_var i,0 push_atom_value "5ADACAEBF4B4A8A4" dup put_var un put_loc0 0: "<ret>" push_atom_value "31430057b0557020141973402736****" dup put_var sn put_loc0 0: "<ret>" push_const8 0: 0n dup put_var m put_loc0 0: "<ret>" undefined put_loc0 0: "<ret>" push_0 0 dup put_var i drop 163: get_var i get_var un get_length lt if_false8 243 get_var m push_const8 1: 43n mul dup put_var m put_loc0 0: "<ret>" get_var m get_var BigInt get_var un get_field2 charCodeAt get_var i call_method 1 call1 1 add dup put_var m put_loc0 0: "<ret>" get_var i post_inc put_var i drop goto8 163 243: get_var Number get_var m push_const8 2: 127n mod call1 1 dup put_var l put_loc0 0: "<ret>" push_const8 3: 0n dup put_var n put_loc0 0: "<ret>" push_0 0 dup put_var s put_loc0 0: "<ret>" push_0 0 dup put_var k put_loc0 0: "<ret>" undefined put_loc0 0: "<ret>" push_0 0 dup put_var i drop 299: get_var i get_var sn get_length lt if_false 644 get_var sn get_field2 charCodeAt get_var i call_method 1 dup put_var j put_loc0 0: "<ret>" undefined put_loc0 0: "<ret>" get_var j push_i8 48 gte dup if_false8 363 drop get_var j push_i8 57 lte 363: dup if_true8 388 drop get_var j push_i8 97 gte if_false 644 get_var j push_i8 102 lte 388: if_false 644 get_var k post_inc put_var k put_loc0 0: "<ret>" get_var j push_i8 48 sub dup put_var j put_loc0 0: "<ret>" undefined put_loc0 0: "<ret>" get_var j push_i8 9 gt if_false8 447 get_var j push_i8 39 sub dup put_var j put_loc0 0: "<ret>" 447: get_var s push_i8 16 mul dup put_var s put_loc0 0: "<ret>" get_var s get_var j add dup put_var s put_loc0 0: "<ret>" undefined put_loc0 0: "<ret>" get_var k push_2 2 mod push_0 0 eq if_false 629 get_var s get_var l xor dup put_var s put_loc0 0: "<ret>" undefined put_loc0 0: "<ret>" get_var s push_4 4 sar push_i8 9 gt dup if_true8 541 drop get_var s push_i8 16 mod push_i8 9 gt 541: if_false8 554 push_const8 4: 0n dup put_var n put_loc0 0: "<ret>" goto8 644 554: get_var s push_4 4 sar push_i8 10 mul get_var s push_i8 16 mod add dup put_var s put_loc0 0: "<ret>" get_var n push_const8 5: 100n mul dup put_var n put_loc0 0: "<ret>" get_var n get_var BigInt get_var s call1 1 add dup put_var n put_loc0 0: "<ret>" push_0 0 dup put_var s put_loc0 0: "<ret>" goto8 629 629: get_var i post_inc put_var i drop goto16 299 644: undefined put_loc0 0: "<ret>" get_var m get_var n eq if_false8 670 push_const8 6: 18071254662143010n dup put_var n put_loc0 0: "<ret>" goto8 679 670: push_const8 7: 24706849372394394n dup put_var n put_loc0 0: "<ret>" 679: push_empty_string dup put_var s put_loc0 0: "<ret>" undefined put_loc0 0: "<ret>" 689: get_var n push_const8 8: 0n gt if_false8 756 get_var s get_var String get_field2 fromCharCode get_var Number get_var n push_const8 9: 127n mod call1 1 call_method 1 add dup put_var s put_loc0 0: "<ret>" get_var n push_const8 10: 127n div dup put_var n put_loc0 0: "<ret>" goto8 689 756: get_var print get_var s call1 1 set_loc0 0: "<ret>" return Success!
简化得到
function verify_sn() { var un,sn,s,i,j,k,l,m,n; un = "5ADACAEBF4B4A8A4"; sn = "31430057b0557020141973402736"; m = 0n; for (i = 0; i < un.length; i += 1) { m *= 43n; m += BigInt(un.charCodeAt(i)); } l = Number(m % 127n); n = 0n s = 0 k = 0 for (i = 0; i < sn.length;i += 1) { j = sn.charCodeAt([i]); if ((j >= 0x30 && j <= 0x39) || (j >= 0x61 && j <= 0x66)) { k += 1; j -= 0x30; if (j > 9) { j -= 0x27; } s *= 16; s += j; if ((k % 2) != 0) { continue; } s ^= l; s_high = (s >> 4) & 0x0F; s_low = s & 0x0F; if (s_high > 9 || s_low > 9) { n = 0; break; } n *= 100n; n += BigInt(s_high * 10 + s_low); s = 0; } } if (m == n) { n = 18071254662143010n; } else { n = 24706849372394394n; } s = ''; while (n > 0) { s += String.fromCharCode(Number(n % 127n)); n /= 127n; } console.log(s); } verify_sn();
计算sn
def hex2bin(s): return s.decode('hex') def bin2hex(s): return s.encode('hex') def get_sn(): # un = '5ADACAEBF4B4A8A4' # sn = '31430057b0557020141973402736' un = 'KCTFKCTFKCTFKCTF' m = 0 for i in range(len(un)): m *= 43 m += ord(un[i]) xor_key = m % 127 s = '%d' % m if (len(s) % 2) == 1: s = '0' + s print s s = hex2bin(s) r = '' for i in range(len(s)): r += chr(ord(s[i]) ^ xor_key) r = bin2hex(r) print('%s' % r) return get_sn()