本文为看雪论坛精华文章
看雪论坛作者ID:juice4fun
MouseController__CollectCoin
方法中, 找到偏移0x4652AC这里,使用gg修改器将CMP W0, #0x3E8
这条指令修改为CMP W0, #0
之后随便吃一个金币得到flag。./fs -l 0.0.0.0:2394
命令切换监听端口,为了保证万无一失,将工作目录从tmp文件夹移到别的地方取,这样一来就能够成功过掉这一大类的检测。blr x8
就是调用点,读取完代码段的校验和之后返回值会存储在x0寄存器中,因此可以按照此为线索往下面拉,, 看到0x7B320处有一个cmp w0, w8
. 之后一个b跳转到0x7AF00处。function PatchCode(addr, value){
Memory.protect(addr, 4, 'rwx');
addr.writeInt(value);
}PatchCode(libsec2023.base.add(0x7B320), 0x2a0803e0);//过crc32
1db29b949927d377f0270e1161964bb0b9fc004f7125b6956d057e09a7c2fadf77df04bbcae93aa0000
字符串, 之后将s2的字符串与前面初始化的某个数组使用strcmp
函数进行比较, 经过hook获取发现该数组是一个恒定不变的字符串25f6b048b4f32e3ce9175bb64930f65101a706ae74988a4ec87b4d5ec7feb9223ab782bcf1ec9d7fee750
。刚开始看到这个字符串想到了哈希, 但是具体是什么还需要进入sub_9e93c函数查看。......
9f934 mov x27, x1 ; x27 = 0x81d8ae82 --> 0x7ce2ef7850
9f938 adrp x3, #0x7ced00b000 ; x3 = 0x3762f4b5 --> 0x7ced00b000
9f93c add x1, x1, x8 ;
9f940 ldr x8, [sp, #8] ; x8 = 0x0 --> 0x7ce2ef7470
9f944 add x0, sp, #0x20 ; x0 = 0x767ac01f --> 0x7ce2ef73e0
9f948 mov x2, #-1 ; x2 = 0x471527a8 --> 0xffffffffffffffff
9f94c add x3, x3, #0x64b ; x3 = 0x7ced00b000 --> 0x7ced00b64b (%.08x)
9f950 ldr w4, [x8, x9, lsl #2] ; x4 = 0x22cd9db --> 0x0 (null)
9f954 ldr w8, [sp, #0x24] ; x8 = 0x7ce2ef7470 --> 0xeecf7326
9f958 adrp x9, #0x7ced030000 ; x9 = 0x1f --> 0x7ced030000 (U!3})
9f95c ldr x9, [x9, #0xa68] ; x9 = 0x7ced030000 --> 0x7cb537824c
9f960 str w8, [sp, #0x20] ; str = 0xeecf7326
9f964 mov w8, #0x89f0 ; x8 = 0xeecf7326 --> 0x89f0
9f968 movk w8, #0x37c2, lsl #16 ; x8 = 0x89f0 --> 0x37c289f0
9f96c add x8, x9, x8 ; x8 = 0x37c289f0 --> 0x7cecfa0c3c
9f970 blr x8 ; x0 = 0x7ce2ef73e0 --> 0x8 x1 = 0x7ce2ef7850 --> 0x7ce2ef6b83 x2 = 0xffffffffffffffff --> 0x9 x3 = 0x7ced00b64b --> 0x7ce2ef7260 x4 = 0x0 --> 0x7ce2ef6b84 x5 = 0x50 --> 0x7ce2ef7858 x6 = 0x110 --> 0x30 x7 = 0x108 --> 0x30 x8 = 0x7cecfa0c3c --> 0xd55c7b4c8b012ca8 x9 = 0x7cb537824c --> 0xd55c7b4c8b012ca8 x10 = 0xcd53af93 --> 0x0 x11 = 0x7cecfa092c --> 0x2 x12 = 0x48 --> 0x0 x13 = 0x400 --> 0x7ffffff7 x14 = 0xc8 --> 0xeecf7326 x15 = 0xf0fc4d01 --> 0x0 x16 = 0xd1993aaf --> 0x7dd3e069a0 x17 = 0xb952cbee --> 0x7dd3d4bb94
9f974 ldr w8, [sp, #0x28] ; x8 = 0xd55c7b4c8b012ca8 --> 0x0 (null)
9f978 ldr w9, [sp, #0x2c] ; x9 = 0xd55c7b4c8b012ca8 --> 0x1f
9f97c ldr w10, [sp, #0x24] ; x10 = 0x0 --> 0xeecf7326
9f980 mov w11, #0x8ff8 ; x11 = 0x2 --> 0x8ff8
9f984 mov w4, #0xd9db ; x4 = 0x7ce2ef6b84 --> 0xd9db
9f988 mov w3, #0xf4b5 ; x3 = 0x7ce2ef7260 --> 0xf4b5
9f98c mov w2, #0x27a8 ; x2 = 0x9 --> 0x27a8
9f990 mov w0, #0xc01f ; x0 = 0x8 --> 0xc01f
9f994 mov w17, #0xcbee ; x17 = 0x7dd3d4bb94 --> 0xcbee
9f998 mov w16, #0x3aaf ; x16 = 0x7dd3e069a0 --> 0x3aaf
9f99c mov w15, #0x4d01 ; x15 = 0x0 --> 0x4d01
9f9a0 mov x1, x27 ; x1 = 0x7ce2ef6b83 --> 0x7ce2ef7850 (00000000)
;这里能看到生成了一串0, 这个0就是上面的br跳转得到的
9f9a4 mov w27, #0xae82 ; x27 = 0x7ce2ef7850 --> 0xae82
......
0x028a831a5bf4b902e95318e50c2075259f91094d08d84409e1b76eadfa0865d1278acc90fa7c6cf6acb375
. 这个算法是离散对数问题, y为已知的25f6b048b4f32e3ce9175bb64930f65101a706ae74988a4ec87b4d5ec7feb9223ab782bcf1ec9d7fee750
, 其逆算法也就是求得输入数字x. 其中x的范围已知是和0xffff00ffffff按位与之后的结果,那么最简单的逆算法就是爆破枚举。#include <iostream>
#include <gmpxx.h>//这里使用了gmp库来计算大整数, 会暴力输出所有满足的解
//这里得到的解是原始输入int64 & 0xffff00ffffff之后应当满足的部分
void GetAns() {
mpz_class z("0x28a831a5bf4b902e95318e50c2075259f91094d08d84409e1b76eadfa0865d1278acc90fa7c6cf6acb375", 0);
mpz_class y("0x25f6b048b4f32e3ce9175bb64930f65101a706ae74988a4ec87b4d5ec7feb9223ab782bcf1ec9d7fee750", 0);
mpz_class j, x;
mpz_ui_pow_ui(j.get_mpz_t(), 2, 32); // j = 2^32
for (int i = 0x0; i <= 0xffff; i++) {
x = i;
x *= j; // x = i * 2^32
for (int k = 0; k <= 0xffffff; k++) {
x += k;
mpz_class result;
mpz_powm_ui(result.get_mpz_t(), x.get_mpz_t(), 17, z.get_mpz_t());
if (result == y) {
std::cout << x << std::endl;
}
}
}
return 0;
}
99ff0 add x0, sp, #0x18 ; x0 = 0x409 --> 0x7cda7e56f8
99ff4 add x5, sp, #0x10 ; x5 = 0x50 --> 0x7cda7e56f0
99ff8 add x8, x8, x25 ; x8 = 0x7d3ae73f70 --> 0x7ce3496970
99ffc mov x1, x20 ; x1 = 0x7cda7e5740 --> 0x7cda7e5750 (builtin)
9a000 mov x2, x21 ; x2 = 0x471527a8 --> 0x7cda7e5740 (vm_main.img)
9a004 mov x3, x22 ; x3 = 0x3762f4b5 --> 0x7ce350b698 (PK)
9a008 blr x8 ; x0 = 0x7cda7e56f8 --> 0x0 (null) x1 = 0x7cda7e5750 --> 0x984a295f x2 = 0x7cda7e5740 --> 0x2 x3 = 0x7ce350b698 --> 0xb x4 = 0x409 --> 0xa97ab639 x5 = 0x7cda7e56f0 --> 0x8095fb42 x6 = 0x110 --> 0xbcf7b136 x7 = 0x108 --> 0x4 x8 = 0x7ce3496970 --> 0xd55c7b4c8b012ca8 x10 = 0xeba2023a --> 0x38
x11 = 0x7 --> 0x68 x12 = 0x8 --> 0x7ce352dc90 x13 = 0x7ce349552c --> 0x73b4c850 x14 = 0x90409722 --> 0x9 x15 = 0x7a5cace1 --> 0xa x16 = 0x7ce349af04 --> 0xc x17 = 0x7ce349542c --> 0x8
9a00c ldr x8, [x23, #0x40] ; x8 = 0xd55c7b4c8b012ca8 --> 0x7d3ae771ec
9a010 add x0, sp, #0x18 ; x0 = 0x0 --> 0x7cda7e56f8
9a014 add x9, x8, x25 ; x9 = 0xd55c7b4c8b012ca8 --> 0x7ce3499bec (�)
9a018 add x8, sp, #0x70 ; x8 = 0x7d3ae771ec --> 0x7cda7e5750 (builtin)
9a01c blr x9 ; x0 = 0x7cda7e56f8 --> 0x7cda7e5750 x1 = 0x984a295f --> 0xb400007cd01e8000 x2 = 0x2 --> 0x7ce349bb84 x9 = 0x7ce3499bec --> 0x7d4c11878c x10 = 0x38 --> 0xffffffff973833f8
9a020 ldr x8, [x23, #0x48] ; x8 = 0x7cda7e5750 --> 0x7d3ae78a74
PK
,vm_main
,builtin
,PK是压缩包的magic标识, 有可能这里的br是执行了解压缩操作, 回溯查看这个PK的来源能够发现是sub_B59DC函数获取该地址的。a64.dat
和a64.sig
. 此处尚且知其具体含义, 继续阅读后面的汇编代码, 查看是如何使用该数据的,果不其然在0x96190附近看到了这样一段汇编记录。96178 ldp x0, x1, [sp, #0x28] ; x0 = 0x7cd4f5c5d8 --> 0x7cdde4b698 (PK) x1 = 0xc8 --> 0x409
9617c ldr x2, [sp, #0x20] ; x2 = 0xd0 --> 0x7cdde4b527 (a64.dat)
96180 add x3, sp, #0x58 ; x3 = 0x7cdde4b527 --> 0x7cd4f5c5d8
96184 add x8, x8, x26 ; x8 = 0x7ca616a9ec --> 0x7cddd933dc (���O��{���)
96188 mov w28, #0x178 ; x28 = 0x7cdde6e9e0 --> 0x178
9618c mov w26, #0xf8 ; x26 = 0x37c289f0 --> 0xf8
96190 blr x8 ; x0 = 0x7cdde4b698 --> 0x0 (null) x1 = 0x409 --> 0xb400007d323694c0 x2 = 0x7cdde4b527 --> 0x0 x3 = 0x7cd4f5c5d8 --> 0x1 x4 = 0x7cdde4b698 --> 0xb400007be73f08a3 x5 = 0x409 --> 0xb400007cb95ea4a3 x6 = 0x7cd4f5c6f0 --> 0x838b832b83258397 x7 = 0x108 --> 0x833d83178326832b x8 = 0x7cddd933dc --> 0xd55c7b4c8b012ca8 x9 = 0x7cdddd7140 --> 0xd55c7b4c8b012ca8 x10 = 0x58 --> 0x1 x11 = 0xeecf7326 --> 0x8f0ea10 x12 = 0xbf849a51 --> 0xb400007cb95ea4a0 x13 = 0xb4efdc76 --> 0x9fbfe4a5 x14 = 0x72e53092 --> 0x20 x15 = 0x2dc8ee0b --> 0x1ff x16 = 0x189b0123 --> 0x7dd3e069c0 x17 = 0x8265feb --> 0x7dd3dfa9fc
a64.dat
字符串, x3是某个数据. 使用ida进入该函数sub_523DC可以发现并没有被混淆. 那么大概率不是什么重要的函数, 根据参数猜测应该是从安装包中提取a64.dat
这个文件,使用frida hook查看参数和内存变化情况。a64.dat
的文件大小. 得知sub_523DC提取了a64.dat
文件之后, 继续往后面看汇编代码, 看看是如何使用该文件的。......
95fa8 add x0, sp, #0x58 ; x0 = 0xc0 --> 0x7cd4f5c5d8
95fac add x8, x8, x9 ; x8 = 0x7ca616b3dc --> 0x7cddd93dcc
95fb0 blr x8 ; x0 = 0x7cd4f5c5d8 --> 0x2a3 获取dat文件长度
......
9621c add x0, sp, #0x58 ; x0 = 0xc0 --> 0x7cd4f5c5d8
96220 add x8, x8, x28 ; x8 = 0x7ca616b3d4 --> 0x7cddd93dc4
96224 blr x8 ; x0 = 0x7cd4f5c5d8 --> 0xb400007cb95ea200 这里调用了一个函数获取文件内容的地址, 跟踪这个地址0xb400007cb95ea200
......
96248 ldp x5, x1, [sp, #0x10] ; x1 = 0xc8 --> 0x7cd4f5c740 (vm_main.img) x5 = 0xb400007cb95ea4a3 --> 0x7cd4f5c6f8
9624c ldr x4, [sp, #0x38] ; x4 = 0xb400007be73f08a3 --> 0x7cd4f5c6f0
96250 mov w3, w0 ; x3 = 0x1 --> 0x2a3
96254 add x9, x9, x28 ; x9 = 0x7ca61ae928 --> 0x7cdddd7318
96258 mov x0, x8 ; x0 = 0x2a3 --> 0x7cd4f5c750 (builtin)
9625c mov x2, x27 ; x2 = 0xd0 --> 0xb400007cb95ea200 ( ")
96260 mov w23, #0x28 ; x23 = 0x7cdde6e9f0 --> 0x28
96264 mov w28, #0x178 ; x28 = 0x37c289f0 --> 0x178
96268 mov x27, x26 ; x27 = 0xb400007cb95ea200 --> 0x7cd4f5c750 (builtin)
9626c mov w26, #0xf8 ; x26 = 0x7cd4f5c750 --> 0xf8
96270 blr x9 ; x0 = 0x7cd4f5c750 --> 0x0 (null) x1 = 0x7cd4f5c740 --> 0x91844490 x2 = 0xb400007cb95ea200 --> 0x8a5b6c8a x3 = 0x2a3 --> 0x8614eee7 x4 = 0x7cd4f5c6f0 --> 0x7a5cace1 x5 = 0x7cd4f5c6f8 --> 0x6b8d117a x6 = 0x838b832b83258397 --> 0x5c68331f x7 = 0x833d83178326832b --> 0x3a59490c x8 = 0x7cd4f5c750 --> 0xd55c7b4c8b012ca8 x9 = 0x7cdddd7318 --> 0xd55c7b4c8b012ca8 x10 = 0x30 --> 0xcb036d0 x11 = 0x8f0ea10 --> 0x10e05d66 x12 = 0xbf849a51 --> 0xf244e8a7 x13 = 0xb4efdc76 --> 0xeb3e178a x14 = 0x72e53092 --> 0xd45ef95c 这里调用了sub_96318, 跟进去查看
......
;进入这个函数还是主要跟踪文件地址, 由于trace的log基址不同, 所以这里文件的地址和上面不一样
;一路跟进到96da8
97d9c add x0, sp, #0xb8 ; x0 = 0xa475f42f --> 0x7cdb8682c8
97da0 add x8, x8, x27 ; x8 = 0x7c7940ee0c --> 0x7cecf5b65c (h)
97da4 mov w3, #1 ; x3 = 0x8614eee7 --> 0x1
97da8 blr x8 ; x8 = 0x7cecf5b65c --> 0x1 sub_5A65C
;继续往下
97dac ldr x8, [x21, #8] ; x8 = 0x1 --> 0x7c7940ef58
97db0 add x0, sp, #0xb8 ;
97db4 add x8, x8, x27 ; x8 = 0x7c7940ef58 --> 0x7cecf5b7a8 (@� @�?�I)
97db8 blr x8 ; x0 = 0x7cdb8682c8 --> 0x20220118 x8 = 0x7cecf5b7a8 --> 0x1182220 x9 = 0x7cecf98d70 --> 0x118 x10 = 0xcb036d0 --> 0x20220118 x11 = 0x10e05d66 --> 0x1 x12 = 0xf244e8a7 --> 0x2022 x13 = 0xeb3e178a --> 0x1801 x14 = 0xd45ef95c --> 0x3 sub_5A7A8
;
;继续跟进
97f70 adrp x8, #0x7ced02e000 ; x8 = 0xeb3e178a --> 0x7ced02e000 (��^�|)
97f74 ldr x8, [x8, #0xa20] ; x8 = 0x7ced02e000 --> 0x7c7940ef58
97f78 mov w9, #0xc850 ; x9 = 0x7cecf98f70 --> 0xc850
97f7c movk w9, #0x73b4, lsl #16 ; x9 = 0xc850 --> 0x73b4c850
97f80 add x0, sp, #0xb8 ; x0 = 0xa475f42f --> 0x7cdb8682c8
97f84 add x8, x8, x9 ; x8 = 0x7c7940ef58 --> 0x7cecf5b7a8 (@� @�?�I)
97f88 blr x8 ; x0 = 0x7cdb8682c8 --> 0x1 x8 = 0x7cecf5b7a8 --> 0x10000 x9 = 0x73b4c850 --> 0x1 x10 = 0xcb036d0 --> 0x1 x11 = 0x10e05d66 --> 0x1 x12 = 0xf244e8a7 --> 0x0 x13 = 0xeb3e178a --> 0x100 x14 = 0xd45ef95c --> 0x7 sub_5A7A8
97f8c str wzr, [sp, #0x44] ; str = 0
97f90 str w0, [sp, #0x104] ; str = 0x1 这里是调用了上面的sub_5A7A8函数读取第二个int, 将其保存到栈中, 后面会继续用到, 所以标注起来
......
9779c add x0, sp, #0xb8 ; x0 = 0xa475f42f --> 0x7cdb8682c8
977a0 add x8, x8, x9 ; x8 = 0x7c7940f288 --> 0x7cecf5bad8 (�_���W��O��{���)
977a4 mov w1, wzr ; x1 = 0x91844490 --> 0x0 (null)
977a8 blr x8 ; x0 = 0x7cdb8682c8 --> 0xb400007d3ec291b0 (vm_main.img) x1 = 0x0 --> 0x50 x2 = 0x8a5b6c8a --> 0x168 x3 = 0x8614eee7 --> 0x140 x4 = 0x7a5cace1 --> 0x178 x5 = 0x6b8d117a --> 0xb x6 = 0x5c68331f --> 0x68 x7 = 0x3a59490c --> 0x5c9a8776 x8 = 0x7cecf5bad8 --> 0xd55c7b4c8b012ca8 x9 = 0x73b4c850 --> 0xd55c7b4c8b012ca8 x10 = 0xcb036d0 --> 0xf658b097 x11 = 0x10e05d66 --> 0x128 x12 = 0xf244e8a7 --> 0x78 x13 = 0xeb3e178a --> 0xe0 x14 = 0xd45ef95c --> 0xc246eb53 x15 = 0xbfb89f2d --> 0x7ced03f8ee x16 = 0xa5356f4c --> 0xa0 x17 = 0xa4ff4077 --> 0xa6667466
977ac str x0, [sp, #0x108] ; str = 0xb400007d3ec291b0 (vm_main.img)
977b0 ldr x8, [sp, #0x108] ; x8 = 0xd55c7b4c8b012ca8 --> 0xb400007d3ec291b0 (vm_main.img)
977b4 ldr w9, [sp, #0xf4] ; x9 = 0xd55c7b4c8b012ca8 --> 0xeecf7326
977b8 ldr w10, [sp, #0xf4] ; x10 = 0xf658b097 --> 0xeecf7326
vm_main.img
,__ff_11
,__ff_12
.;继续跟进
978c4 mov x1, x0 ; x1 = 0x91844490 --> 0xb400007bef75a300
978c8 add x0, sp, #0xb8 ; x0 = 0xb400007bef75a300 --> 0x7cdb8682c8
978cc add x8, x8, x27 ; x8 = 0x7c7940f228 --> 0x7cecf5ba78 (�O���{��C)
978d0 blr x8 ; x0 = 0x7cdb8682c8 --> 0x1 x1 = 0xb400007bef75a300 --> 0x83578390830c8340 x2 = 0x284 --> 0x83598390833d83f4 x3 = 0x8614eee7 --> 0xb400007bef75a500 x4 = 0x7a5cace1 --> 0xb400007bf780a79f x5 = 0x6b8d117a --> 0xb400007bef75a584 x6 = 0x5c68331f --> 0x83258397836e83df x7 = 0x3a59490c --> 0x8326832b838b832b x8 = 0x7cecf5ba78 --> 0x29f x9 = 0x7cecf98898 --> 0xd4fcb35983838361 x10 = 0xcb036d0 --> 0xd4fcea78d4fca104 x11 = 0x10e05d66 --> 0xd4fcea7883838383 x12 = 0xf244e8a7 --> 0x830c834083598390 x13 = 0xeb3e178a --> 0x833d83f483578390 x16 = 0xa5356f4c --> 0x7ced026c80 x17 = 0xa4ff4077 --> 0x7dd3d8ec40
;将前面那块地址存到[sp, #0x128]栈上
979e8 str x0, [sp, #0x128] ; str = 0xb400007bef75a300
......
9745c ldr w8, [sp, #0x144] ; x8 = 0x91844490 --> 0x0 (null)
97460 ldr x9, [sp, #0x128] ; x9 = 0x7cecf9845c --> 0xb400007bef75a300
97464 mov w27, #0x23 ; x27 = 0x2d0 --> 0x23
97468 ldrb w10, [x9, x8] ; x10 = 0xcb036d0 --> 0x4
9746c eor x10, x10, x27 ; x10 = 0x4 --> 0x27
97470 adrp x27, #0x7ced00b000 ; x27 = 0x23 --> 0x7ced00b000
97474 add x27, x27, #0x536 ; x27 = 0x7ced00b000 --> 0x7ced00b536
97478 ldrb w10, [x27, x10] ; x10 = 0x27 --> 0x23
9747c strb w10, [x9, x8] ;
import io a64Data = io.open("a64.dat", 'rb').read()
Mem_10A536Data = io.open("Mem_10A536.bin", 'rb').read()data = bytearray(0x284)
for i in range(0x284):
data[i] = Mem_10A536Data[a64Data[i+0x1b] ^ 0x23]
io.open("out.bin", "wb").write(data)
看雪ID:juice4fun
https://bbs.kanxue.com/user-home-831526.htm
# 往期推荐
3、安卓加固脱壳分享
球分享
球点赞
球在看