本文为看雪论坛精华文章
看雪论坛作者ID:lxcoder
ida的效果:
ghidra的效果:
源码大概是这样子的:
__int64 __fastcall sub_2DB50(JNIEnv *param_1,_int64 param_2,int param_3,long param_4){
unsigned int v12 = 0;
long ret = 0;
long* ptr = (long*)malloc(0x20);
if(ptr != nullptr){
ptr[0] = 0LL;
ptr[1] = 0LL;
*(_DWORD *)ptr = param_3 / 10000;
v7 = param_3 % 10000 / 100;
*((_DWORD *)ptr + 1) = v7;
*((_DWORD *)ptr + 2) = param_3 % 100;
ptr[2] = param_1;
ptr[3] = param_4;
ret = sub_2BB3C(param_3 / 10000, v7, param_3 % 100, 1u, ptr, &v12);
}
free(ptr);
if(ret == 0 && v12 != 0){
//throw Exception
sub_E78C0(param_1, v12, 0x20aa97)
}
return ret;
}
LOAD:000000000002DBFC A9 75 91 52+ MOV W9, #0x68DB8BAD
LOAD:000000000002DBFC 69 1B AD 72
LOAD:000000000002DC04 A9 7E 29 9B SMULL X9, W21, W9
LOAD:000000000002DC08 1F 7D 00 A9 STP XZR, XZR, [X8]
LOAD:000000000002DC0C E8 1B 40 F9 LDR X8, [SP,#0x80+p]
LOAD:000000000002DC10 2C FD 7F D3 LSR X12, X9, #0x3F ; '?'
LOAD:000000000002DC14 29 FD 6C 93 ASR X9, X9, #0x2C ; ','
LOAD:000000000002DC18 20 01 0C 0B ADD W0, W9, W12
LOAD:000000000002DC1C 0A E2 84 52 MOV W10, #0x2710
LOAD:000000000002DC20 EB A3 90 52 MOV W11, #0x851F
LOAD:000000000002DC24 00 01 00 B9 STR W0, [X8]
LOAD:000000000002DC28 6B 3D AA 72 MOVK W11, #0x51EB,LSL#16
LOAD:000000000002DC2C 0A D4 0A 1B MSUB W10, W0, W10, W21
LOAD:000000000002DC30 E8 1B 40 F9 LDR X8, [SP,#0x80+p]
LOAD:000000000002DC34 4A 7D 2B 9B SMULL X10, W10, W11
LOAD:000000000002DC38 A9 7E 2B 9B SMULL X9, W21, W11
LOAD:000000000002DC3C 4B FD 7F D3 LSR X11, X10, #0x3F ; '?'
LOAD:000000000002DC40 4A FD 65 93 ASR X10, X10, #0x25 ; '%'
LOAD:000000000002DC44 41 01 0B 0B ADD W1, W10, W11
LOAD:000000000002DC48 01 05 00 B9 STR W1, [X8,#4]
LOAD:000000000002DC4C 2A FD 7F D3 LSR X10, X9, #0x3F ; '?'
LOAD:000000000002DC50 28 FD 65 93 ASR X8, X9, #0x25 ; '%'
LOAD:000000000002DC54 E9 1B 40 F9 LDR X9, [SP,#0x80+p]
LOAD:000000000002DC58 08 01 0A 0B ADD W8, W8, W10
LOAD:000000000002DC5C 8A 0C 80 52 MOV W10, #0x64 ; 'd'
LOAD:000000000002DC60 02 D5 0A 1B MSUB W2, W8, W10, W21
LOAD:000000000002DC64 22 09 00 B9 STR W2, [X9,#8]
>>> (1 << 0x2c) / (0x68db8bad - 1)
10000.000002510205
>>> (1 << 0x25) / (0x51eb85ef - 1)
99.99998491839733
LOAD:000000000002BB3C SUB SP, SP, #0x1B0
LOAD:000000000002BB40 STP X28, X27, [SP,#0x1A0+var_50]
LOAD:000000000002BB44 STP X26, X25, [SP,#0x1A0+var_40]
LOAD:000000000002BB48 STP X24, X23, [SP,#0x1A0+var_30]
LOAD:000000000002BB4C STP X22, X21, [SP,#0x1A0+var_20]
LOAD:000000000002BB50 STP X20, X19, [SP,#0x1A0+var_10]
LOAD:000000000002BB54 STP X29, X30, [SP,#0x1A0+var_s0]
LOAD:000000000002BB58 ADD X29, SP, #0x1A0
LOAD:000000000002BB5C MRS X26, #3, c13, c0, #2
LOAD:000000000002BB60 MOV W23, W1
LOAD:000000000002BB64 MOV W24, W0
LOAD:000000000002BB68 MOV W10, #0x2710
LOAD:000000000002BB6C MOV W12, #0x64 ; 'd'
LOAD:000000000002BB70 LDR X14, [X26,#0x28]
LOAD:000000000002BB74 MUL W15, W24, W10
LOAD:000000000002BB78 MUL W12, W23, W12
LOAD:000000000002BB7C MOV W22, W2
LOAD:000000000002BB80 MOV W13, #0xC600
LOAD:000000000002BB84 ADD W10, W15, W12
LOAD:000000000002BB88 MOV W8, #0x96
LOAD:000000000002BB8C SUB X9, X29, #-var_70
LOAD:000000000002BB90 MOVK W13, #0x53E,LSL#16
LOAD:000000000002BB94 ADD W10, W10, W22
LOAD:000000000002BB98 MOV X21, X4
LOAD:000000000002BB9C ADD W13, W10, W13
LOAD:000000000002BBA0 STUR X14, [X29,#var_58]
LOAD:000000000002BBA4 STUR W8, [X29,#var_70]
LOAD:000000000002BBA8 ADR X27, loc_2BBAC
LOAD:000000000002BBAC
LOAD:000000000002BBAC loc_2BBAC ; DATA XREF: sub_2BB3C+6C↑o
LOAD:000000000002BBAC LDRSW X4, =0xFFFFFE62
LOAD:000000000002BBB0 MOV X20, #0xAB
LOAD:000000000002BBB4 EOR X4, X4, X20
LOAD:000000000002BBB8 ADD X4, X4, #0x88
LOAD:000000000002BBBC MVN X4, X4
LOAD:000000000002BBC0 LDRSW X10, [X9]
LOAD:000000000002BBC4 EOR X4, X4, X10
LOAD:000000000002BBC8 ADD X27, X27, X4
LOAD:000000000002BBCC MOV X8, #0x62 ; 'b'
LOAD:000000000002BBD0 BR X27
LAB_0013dd1c XREF[1]: 0013dd00(j)
0013dd1c e8 03 00 90 adrp x8,0x1b9000
0013dd20 08 01 11 91 add x8,x8,#0x440
0013dd24 08 09 40 f9 ldr x8,[x8, #0x10]=>DAT_001b9450 = 000000000013DC94h
0013dd28 08 71 02 91 add x8,x8,#0x9c
0013dd2c 00 01 1f d6 br x8=>LAB_0013dd30
LOAD:000000000002BD58 loc_2BD58 ; DATA XREF: sub_2BB3C+3B0↓o
LOAD:000000000002BD58 ; LOAD:off_16FC38↓o
LOAD:000000000002BD58 E9 23 0A A9 STP X9, X8, [SP,#0x1A0+var_100]
LOAD:000000000002BD5C 88 36 40 F9 LDR X8, [X20,#(off_16FC28 - 0x16FBC0)] ; loc_2BD68
LOAD:000000000002BD60 FF 0F 00 F9 STR XZR, [SP,#0x1A0+var_188]
LOAD:000000000002BD64 08 2D 00 91 ADD X8, X8, #0xB
LOAD:000000000002BD68
LOAD:000000000002BD68 loc_2BD68 ; DATA XREF: sub_2BB3C+220↑o
LOAD:000000000002BD68 ; LOAD:off_16FC28↓o
LOAD:000000000002BD68 03 00 00 14 B loc_2BD74 ; loc_2BD74 ; Keypatch modified this from:
LOAD:000000000002BD68 ; BR X8
LAB_0013dd1c XREF[1]: 0013dd00(j)
0013dd1c e8 03 00 90 adrp x8,0x1b9000
0013dd20 08 01 11 91 add x8,x8,#0x440
0013dd24 08 09 40 f9 ldr x8,[x8, #0x10]=>DAT_001b9450 = 000000000013DC94h
0013dd28 08 71 02 91 add x8,x8,#0x9c
0013dd2c 00 01 1f d6 br x8=>LAB_0013dd30
LAB_00134638 XREF[1]: 00134604(j)
00134638 69 22 40 a9 ldp x9,x8,[x19]
0013463c a8 03 18 f8 stur x8,[x29, #local_90]
00134640 08 7d 40 92 and x8,x8,#0xffffffff
00134644 a9 a7 38 a9 stp x9,x9,[x29, #local_88]
00134648 a8 c3 17 b8 stur w8,[x29, #local_94]
0013464c e9 07 00 b4 cbz x9,LAB_00134748
00134650 c8 07 00 34 cbz w8,LAB_00134748
00134654 f6 09 00 90 adrp x22,0x270000
00134658 d6 82 01 91 add x22,x22,#0x60
0013465c c8 4a 40 f9 ldr x8,[x22, #0x90]=>DAT_002700f0 = 00000000001345FDh
00134660 08 ad 01 91 add x8,x8,#0x6b
00134664 00 01 1f d6 br x8=>LAB_00134668
可以看出,Ghidra已经通过自己的逻辑算出了常量地址,但是它并没有更新到返汇编结果中,patch后效果立马就出来了:
这种是间接跳,使用了全局变量进行跳转(大致含义就是全局变量0x270140这个地址中的内容+0xda计算出的结果就是call的地址),Ghidra这里识别为多种结果所以这种情况必需得上动态才能知道可能的结果了,不同流程可能结果会不一样。
typedef struct _StData{
void ** ppParamSt;
int sz;
}StData;
typedef struct _StParam1{
int param;
int unknow;
StData* pSD;
}StParam1;
typedef struct _StParam2{
int unknow;
int param;
long flag;
StData* pSD;
}StParam2;
typedef struct _StParam3{
long unknow;
int param;
int unknow;
long encryFuncAddr;
}StParam3;
long FUN_0012bb3c(int param_1, int param_2, int param_3, int param_4,
long *param_5, int *param_6)
{
int iVar1;
long lVar2;
StParam3 *pSVar3;
long local_1a8;
StParam1 *pSStack416;
long lStack408;
StParam2 *pSStack400;
long lStack392;
int local_17c;
long local_178;
int local_7c;
long *plStack120;
int *piStack112;
long local_68;
StData **pplVar1;
local_7c = 1;
plStack120 = param_5;
piStack112 = param_6;
local_178 = FUN_00168480(param_1 * 10000 + param_2 * 100 + param_3 + 88000000,
param_4, 0, &plStack120, &local_7c);
if (local_7c != 0) {
pplVar1 = (long **)0x279af0; //全局变量非常量
if (param_4 != 0) {
pplVar1 = (long **)&DAT_00279ae8; //全局变量非常量
}
iVar1 = (*pplVar1)->sz;
if(iVar1 < 1){
local_17c = 0x26b0;
}else{
for(local_1a8 = 0; local_1a8 < iVar1; local_1a8++){
pSStack416 = (StParam1*)(*pplVar1)->ppParamSt[local_1a8];
if(pSStack416->param == param_1){
goto LAB_JMP1;
}
}
pSStack416 = 0;
LAB_JMP1:
if(pSStack416 == 0){
local_17c = 0x26b0;
}else{
iVar1 = pSStack416->pSD->sz;
if(iVar1 < 1){
local_17c = 0x26b1;
}else{
for(lStack408 = 0; lStack408 < iVar1; lStack408++){
pSStack400 = (StParam2*)pSStack416->pSD->ppParamSt[lStack408];
if(pSStack400->param == param_2){
goto LAB_JMP2;
}
}
pSStack400 = 0;
LAB_JMP2:
if(pSStack400 == 0){
local_17c = 0x26b1;
}else{
iVar1 = pSStack400->pSD->sz;
if(iVar1 > 0){
for(lStack392 = 0; lStack392 < iVar1; lStack392++){
pSVar3 = (StParam3*)pSStack400->pSD->ppParamSt[lStack392];
if(pSVar3 != 0 && pSVar3->param == param_3){
local_178 = (*(func*)(pSStack400->flag ^ pSVar3->encryFuncAddr))(param_5, param_6);
return local_178;
}
}
}
local_17c = 0x26b2;
}
}
}
}
if (param_6 != (int *)0x0) {
*param_6 = local_17c + (param_2 * 100 + param_1 * 10000 + param_3) * 10000;
}
local_178 = 0;
}
return local_178;
}
//跟踪函数
//param0:跟踪的模块
//param1:激活trace的hook点,主要是做条件判定,符合条件的才trace
//param2-param3:跟踪的代码块区间,主要用来控制trace的指令区间
//param4:是否步入(超出模块的不跟),默认False,开True容易触发time校验导至挂掉
// trace_entry("libsgmainso-6.5.82.so", base.add(0x2db50), 0x2bb3c, 0x2befc)
//同上,跟踪所有bl指令,并打印参数信息,快束定位这个挺好使,这里测试是字符串,其它的可以做适当调整
// trace_entry_bl("libsgmainso-6.5.82.so", base.add(0x2db50), 0x2db50, 0x2DCF0, true)
//跟踪所有逻辑指令,比如lsl/lsr等,打印偏移/VA及详细指令信息,实际使用效果不好,干扰太多
// trace_entry_logic("libsgmainso-6.5.82.so", base.add(0x2db50), 0x2db50, 0x2DCF0, true)
//同上
//param4:为在指定地址的指令执行时调用回调
//param5:回调函数
//函数功能主要是处理在特殊地址执行时相关数据的打印
// trace_callback("libsgmainso-6.5.82.so", 0x2db50, 0x2bb3c, 0x2befc, 0x2bc84, function(context) {
// var insn = Instruction.parse(context.pc)
// var insnStr = insn.toString().padEnd(25, " ")
// var strLog = insn.address.sub(g_baseAddr) + " " + insn.address + ":\t" + insnStr + "\t" + " " + getOpInfo(context, insn)
// console.log(strLog)
//
// })
x0:0x7ec5a203e0, x1:0x1ec, x2:0x1ec, x3:0x0, x4:0x0, x5:0x0, x6:0x0, x7:0x7ea70754f4
0xe73ac 0x7ea70f43ac: blr x8 -->(libart.so!0x32d3a4 _ZN3art3JNI12NewByteArrayEP7_JNIEnvi) x8:0x7ecf7133a4
x0:0x7ec5a203e0, x1:0x49, x2:0x0, x3:0x1ec, x4:0x7e53030800, x5:0x7ea7a7b348, x6:0x0, x7:0x7ea70754f4
arg4:enxH+QwhGIL9C/JrXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXjm6o=
0xe7414 0x7ea70f4414: blr x8 -->(libart.so!0x32d424 _ZN3art3JNI18SetByteArrayRegionEP7_JNIEnvP11_jbyteArrayiiPKa) x8:0x7ecf713424
do {
uVar11 = puVar6[1];
uVar10 = *puVar6;
local_880 = CONCAT17((byte)((ulong)local_870 >> 0x38) ^
(byte)((uVar10 & 0xffffff0000000000) >> 0x38),
CONCAT16((byte)((ulong)local_870 >> 0x30) ^
(byte)((uVar10 & 0xffffff0000000000) >> 0x30),
CONCAT15((byte)((ulong)local_870 >> 0x28) ^
(byte)(uVar10 >> 0x28),
CONCAT14((byte)((ulong)local_870 >> 0x20) ^
(byte)(uVar10 >> 0x20),
CONCAT13((byte)((ulong)local_870
>> 0x18) ^
(byte)(uVar10 >> 0x18),
CONCAT12((byte)((ulong)
local_870 >> 0x10) ^ (byte)(uVar10 >> 0x10),
CONCAT11((byte)((ulong)local_870 >> 8) ^
(byte)(uVar10 >> 8),
(byte)local_870 ^ (byte)uVar10)))))));
uStack2168 = CONCAT17((byte)((ulong)uStack2152 >> 0x38) ^
(byte)((uVar11 & 0xffffff0000000000) >> 0x38),
CONCAT16((byte)((ulong)uStack2152 >> 0x30) ^
(byte)((uVar11 & 0xffffff0000000000) >> 0x30),
CONCAT15((byte)((ulong)uStack2152 >> 0x28) ^
(byte)(uVar11 >> 0x28),
CONCAT14((byte)((ulong)uStack2152 >> 0x20)
^ (byte)(uVar11 >> 0x20),
CONCAT13((byte)((ulong)uStack2152
>> 0x18) ^
(byte)(uVar11 >> 0x18),
CONCAT12((byte)((ulong)
uStack2152 >> 0x10) ^ (byte)(uVar11 >> 0x10),
CONCAT11((byte)((ulong)uStack2152 >> 8) ^
(byte)(uVar11 >> 8),
(byte)uStack2152 ^ (byte)uVar11)))))));
FUN_001c792c(auStack592,puVar9,&local_880);
uStack2152 = puVar9[1];
local_870 = *puVar9;
puVar9 = puVar9 + 2;
uVar8 = uVar8 - 1;
puVar6 = puVar6 + 2;
} while (uVar8 != 0);
local_9a8 = local_9a8 & 0xfffffff0;
local_2a0 = param_1;
puStack664 = param_2;
do {
uVar19 = puStack664[1];
uVar16 = *puStack664;
local_2a8 = local_2a8 - 4;
uVar17 = (undefined)((ulong)uVar16 >> 0x20);
uVar8 = (ulong)CONCAT16((char)((ulong)uVar16 >> 0x28),
(uint6)((uint)(CONCAT12(uVar17,(short)uVar16) & 0xff00ff) << 0x18 |
(uint)(byte)((ulong)uVar16 >> 8) << 0x10));
uVar9 = (ulong)CONCAT16((char)((ulong)uVar19 >> 0x28),
(uint6)CONCAT11((char)uVar19,(char)((ulong)uVar19 >> 8)) << 0x10);
uVar15 = CONCAT15((char)((ulong)uVar16 >> 0x30),
(uint5)CONCAT12((char)(uVar8 >> 0x18),
CONCAT11((char)(uVar8 >> 0x10),
(char)((ulong)uVar16 >> 0x10))) << 8);
uVar8 = (ulong)CONCAT16((char)(uVar8 >> 0x30),uVar15);
uVar18 = CONCAT15((char)((ulong)uVar19 >> 0x30),
(uint5)CONCAT12((char)(uVar9 >> 0x18),
CONCAT11((char)(uVar9 >> 0x10),
(char)((ulong)uVar19 >> 0x10))) << 8);
uVar9 = (ulong)CONCAT16((char)(uVar9 >> 0x30),uVar18);
local_2a0[1] = ((ulong)CONCAT41((uint)(byte)((ulong)uVar19 >> 0x20) << 0x18,(char)uVar19) &
0xffffffff00) << 0x18 |
(ulong)CONCAT16((char)((uVar9 & 0xffffffff00000000) >> 0x30),
CONCAT15((char)((uVar9 & 0xffffffff00000000) >> 0x28),
CONCAT14((char)((ulong)uVar19 >> 0x38),
CONCAT13((char)(uVar9 >> 0x18),
if ((param_1 != (uint *)0x0 && param_2 != (undefined *)0x0) && param_3 != (uint *)0x0) {
uVar9 = (param_3[3] & 0xff00ff00) >> 8 | (param_3[3] & 0xff00ff) << 8;
uVar9 = (uVar9 >> 0x10 | uVar9 << 0x10) ^ param_1[3];
local_d0 = param_1 + 0x24;
uVar10 = (*param_3 & 0xff00ff00) >> 8 | (*param_3 & 0xff00ff) << 8;
uVar10 = (uVar10 >> 0x10 | uVar10 << 0x10) ^ *param_1;
uVar11 = (param_3[1] & 0xff00ff00) >> 8 | (param_3[1] & 0xff00ff) << 8;
uVar11 = (uVar11 >> 0x10 | uVar11 << 0x10) ^ param_1[1];
uVar12 = (param_3[2] & 0xff00ff00) >> 8 | (param_3[2] & 0xff00ff) << 8;
uVar12 = (uVar12 >> 0x10 | uVar12 << 0x10) ^ param_1[2];
uVar14 = *(uint *)(&DAT_002bca7c + (ulong)(uVar10 >> 0x18) * 4) ^ param_1[4] ^
*(uint *)(&DAT_002bce7c + (ulong)(uVar11 >> 0x10 & 0xff) * 4) ^
*(uint *)(&DAT_002bd27c + (ulong)(uVar12 >> 8 & 0xff) * 4) ^
*(uint *)(&DAT_002bd67c + (ulong)(uVar9 & 0xff) * 4);
uVar1 = *(uint *)(&DAT_002bca7c + (ulong)(uVar12 >> 0x18) * 4) ^ param_1[6] ^
*(uint *)(&DAT_002bce7c + (ulong)(uVar9 >> 0x10 & 0xff) * 4) ^
*(uint *)(&DAT_002bd27c + (ulong)(uVar10 >> 8 & 0xff) * 4) ^
*(uint *)(&DAT_002bd67c + (ulong)(uVar11 & 0xff) * 4);
uVar2 = *(uint *)(&DAT_002bca7c + (ulong)(uVar11 >> 0x18) * 4) ^ param_1[5] ^
*(uint *)(&DAT_002bce7c + (ulong)(uVar12 >> 0x10 & 0xff) * 4) ^
*(uint *)(&DAT_002bd27c + (ulong)(uVar9 >> 8 & 0xff) * 4) ^
*(uint *)(&DAT_002bd67c + (ulong)(uVar10 & 0xff) * 4);
uVar9 = *(uint *)(&DAT_002bca7c + (ulong)(uVar9 >> 0x18) * 4) ^ param_1[7] ^
*(uint *)(&DAT_002bce7c + (ulong)(uVar10 >> 0x10 & 0xff) * 4) ^
*(uint *)(&DAT_002bd27c + (ulong)(uVar11 >> 8 & 0xff) * 4) ^
*(uint *)(&DAT_002bd67c + (ulong)(uVar12 & 0xff) * 4);
看雪ID:lxcoder
https://bbs.pediy.com/user-home-719948.htm
KCTF官网:https://ctf.pediy.com
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!