接上一篇《360加固逆向脱壳之过反调试》 http://bbs.pediy.com/showthread.php?t=213214 想着只写了一半不到,下定决心,把剩下的写完。不过还是没能把nativa protect void onCreate给找到,
不过还好有了大致到思路(在最后的总结里面)
那么,在过完反调试后, 在 case 29下断点(case 29是这个壳的一个函数调用的地方,他是根据指针的变化调用不同的函数的),会来到这里如下面代码:
libjiagu.so:ACC12390 ; ---------------------------------------------------------------------------
libjiagu.so:ACC12390 STMFD SP!, {R4-R7,LR}
libjiagu.so:ACC12394 LDR R4, =(unk_ACC18EB0 - 0xACC123A8)
libjiagu.so:ACC12398 SUB SP, SP, #0x9C
libjiagu.so:ACC1239C MOV R7, R0
libjiagu.so:ACC123A0 LDR R4, [PC,R4] ; unk_ACC18EB0
libjiagu.so:ACC123A4 LDR R3, [R4]
libjiagu.so:ACC123A8 MOV R6, R1
libjiagu.so:ACC123AC MOV R2, #0x94
libjiagu.so:ACC123B0 MOV R1, #0
libjiagu.so:ACC123B4 MOV R0, SP
libjiagu.so:ACC123B8 STR R3, [SP,#0x94]
libjiagu.so:ACC123BC BL memset_0
libjiagu.so:ACC123C0 LDR R3, =0x6F732E2A
libjiagu.so:ACC123C4 MOV R2, #0
libjiagu.so:ACC123C8 MOV R0, SP
libjiagu.so:ACC123CC STR R3, [SP,#0xC]
libjiagu.so:ACC123D0 STRB R2, [SP,#0x10]
libjiagu.so:ACC123D4 STR R7, [SP]
libjiagu.so:ACC123D8 STR R6, [SP,#4]
libjiagu.so:ACC123DC BL unk_ACC0EDF4 // 主要是调用了 DT_INIT_ARRAY 函数,并且在里面有复制 checkSigal report 等函数
// 并且用多次调用了 mmap mmprotect 函数 开辟了新的空间 , 并且调用 DT_INIT_ARRAY, 并且调用__aeabi_atexit
libjiagu.so:ACC123E0 LDR R3, =(dword_ACC55380 - 0xACC123F0)
libjiagu.so:ACC123E4 LDR R1, =(aMakekey - 0xACC123F4)
libjiagu.so:ACC123E8 ADD R3, PC, R3 ; dword_ACC55380
libjiagu.so:ACC123EC ADD R1, PC, R1 ; "makekey"
libjiagu.so:ACC123F0 STR R0, [R3]
libjiagu.so:ACC123F4 BL unk_ACC0EE28
libjiagu.so:ACC123F8 SUBS R12, R0, #0
libjiagu.so:ACC123FC BEQ loc_ACC12424
libjiagu.so:ACC12400 BIC R0, R12, #0xFF0
libjiagu.so:ACC12404 BIC R0, R0, #0xF
libjiagu.so:ACC12408 MOV R1, #0x1000
libjiagu.so:ACC1240C MOV R2, #3
libjiagu.so:ACC12410 MOV R7, #0x7D
libjiagu.so:ACC12414 SVC 0
libjiagu.so:ACC12418 LDR R3, =(unk_ACC18ECC - 0xACC12424)
libjiagu.so:ACC1241C LDR R3, [PC,R3] ; unk_ACC18ECC
libjiagu.so:ACC12420 STR R3, [R12]
libjiagu.so:ACC12424
libjiagu.so:ACC12424 loc_ACC12424 ; CODE XREF: libjiagu.so:_Z10__fun_a_17PcjS_Rii+73Cj
libjiagu.so:ACC12424 LDR R3, =(dword_ACC55380 - 0xACC12434)
libjiagu.so:ACC12428 LDR R1, =(aJni_onload - 0xACC12438)
libjiagu.so:ACC1242C ADD R3, PC, R3 ; dword_ACC55380
libjiagu.so:ACC12430 ADD R1, PC, R1 ; "JNI_OnLoad"
libjiagu.so:ACC12434 LDR R0, [R3]
libjiagu.so:ACC12438 BL unk_ACC0EE28
libjiagu.so:ACC1243C LDR R1, [SP,#0x94]
libjiagu.so:ACC12440 LDR R3, =(dword_ACC5537C - 0xACC12450)
libjiagu.so:ACC12444 LDR R2, [R4]
libjiagu.so:ACC12448 ADD R3, PC, R3 ; dword_ACC5537C
libjiagu.so:ACC1244C CMP R1, R2
libjiagu.so:ACC12450 STR R0, [R3]
libjiagu.so:ACC12454 BNE loc_ACC12460
libjiagu.so:ACC12458 ADD SP, SP, #0x9C
libjiagu.so:ACC1245C LDMFD SP!, {R4-R7,PC}
libjiagu.so:ACC12460 ; ---------------------------------------------------------------------------、
走完 libjiagu.so 后,单步的话,会来到 libjiagu.so 开始处,然后继续单步,会来到DebugXX代码处:
我的是Debug78,如下(每次调试,可能地址不一样,不过反编译代码是一样的):
debug078:AC5D3DC2 ; ---------------------------------------------------------------------------
debug078:AC5D3DC2 MOVS R3, R4
debug078:AC5D3DC4 MOVS R0, R5
debug078:AC5D3DC6 MOVS R2, #0
debug078:AC5D3DC8 ADDS R3, #0x14
debug078:AC5D3DCA
debug078:AC5D3DCA loc_AC5D3DCA ; CODE XREF: debug078:AC5D3DD2j
debug078:AC5D3DCA LDRB R1, [R0]
debug078:AC5D3DCC ADDS R0, #1
debug078:AC5D3DCE ADDS R2, R2, R1
debug078:AC5D3DD0 CMP R0, R3
debug078:AC5D3DD2 BNE loc_AC5D3DCA
debug078:AC5D3DD4 MOVS R3, #0
debug078:AC5D3DD6 MOVS R0, R3
debug078:AC5D3DD8 LSLS R2, R2, #0x18
debug078:AC5D3DDA LSRS R2, R2, #0x18
debug078:AC5D3DDC
debug078:AC5D3DDC loc_AC5D3DDC ; CODE XREF: debug078:AC5D3DEEj
debug078:AC5D3DDC ADDS R1, R4, R0
debug078:AC5D3DDE LDRB R1, [R1,#4]
debug078:AC5D3DE0 ADDS R0, #1
debug078:AC5D3DE2 EORS R1, R2
debug078:AC5D3DE4 ORRS R1, R2
debug078:AC5D3DE6 ADDS R3, R3, R1
debug078:AC5D3DE8 LSLS R3, R3, #0x18
debug078:AC5D3DEA LSRS R3, R3, #0x18
debug078:AC5D3DEC CMP R0, #0x10
debug078:AC5D3DEE BNE loc_AC5D3DDC
debug078:AC5D3DF0 MOVS R0, #1
debug078:AC5D3DF2 STRB R3, [R4,#0x18]
debug078:AC5D3DF4 POP {R3-R7,PC}
debug078:AC5D3DF4 ; ---------------------------------------------------------------------------
开始时这个函数主要完成的事情有: 从 [email]data@app@com.example.test360_2_1.apk@classes.dex[/email]:ACC7BA90 复制一段 字符串到 内存
开头表现形式为:
"9RRTRRRBRRR....
..j64`ebf0304aaj
kk"9RR^RRRpRRR31
&;$;&+.3?71=?|7*
3?">7|&7!&adb.`|
.3;<.1&;$;&+"9RR
XRRRXRRR3>>=%76.
;5.gbbcjefjk"9RR
URRRrRRR3"9.?6g6
74k`e`474bfdj3a0
kadb473001ckj1f"
9RRZRRR[RRR1:719
.'?gbb`ac`dd"9RR
VRRRWRRR1=="....
然后并解密,解密后为:
k..........APPKE
Yxxxxxxxxxxxxxxx
xpk......"...act
ivityNamecom.exa
mple.test360_2.M
ainActivitypk...
.......allowedSi
g-500187489pk...
... ...apk-md5de
fxxxxxxxxxxxxxxx
xxxxxxxxxxxxx4pk
..........checkS
um500231266pk...
.......coopQIHOO
pk..........fast
Level0pk........
..jcrash1pk.....
.....jiaguVersio
n1.3.0.0pk......
....mark0pk.....
.....ncrash1pk..
........opt1pk..
........pkgcom.e
xample.test360_2
pk..........pkl1
pk..........prot
ect-time2016-08-
03 15:23:46pk...
.......rrs1pk...
.......sig287368
684pk...... ...s
tubAppNamecom/qi
hoo/util/StubApp
1691710958pk....
......update1pk.
.........version
Code1pk.........
.versionName1.0p
k..........x861a
pk.y"
然后在把其中的一些字符复制到其他内存地方(具体为什么要复制,不个人猜想是为了写程序方便: 流程为,把源加密数据,解密到临时空间,然后复制到dex)
然后就开始调用 Check_FindClass Check_GetStaticFieldID Check_RegisterNatives 等 用来注册函数,
代码如下:
debug078:AC5BC73C ; ---------------------------------------------------------------------------
debug078:AC5BC73C
debug078:AC5BC73C loc_AC5BC73C ; CODE XREF: debug078:loc_AC5BF746p
debug078:AC5BC73C PUSH {R3-R7,LR}
debug078:AC5BC73E MOVS R6, R1
debug078:AC5BC740 LDR R3, [R0]
debug078:AC5BC742 LDR R1, =(aComQihooUtilSt - 0xAC5BC74C)
debug078:AC5BC744 MOVS R4, R0
debug078:AC5BC746 LDR R3, [R3,#0x18] // libdvm.so:_Z18dvmUseCheckedJniVmP9JavaVMExt+8139(Check_FindClass)
debug078:AC5BC748 ADD R1, PC ; "com/qihoo/util/StartActivity"
debug078:AC5BC74A BLX R3 // R0=一个地址,R1="com/qihoo/util/StartActivity", R2=0x80000000 R3 函数也就是Check_FindClass
debug078:AC5BC74C SUBS R5, R0, #0 // R0=1E400041,R1=gDvmJni
debug078:AC5BC74E BEQ loc_AC5BC7AC
debug078:AC5BC750 MOVS R3, #0x90
debug078:AC5BC752 LDR R2, [R4]
debug078:AC5BC754 LSLS R3, R3, #2
debug078:AC5BC756 MOVS R0, R4
debug078:AC5BC758 LDR R7, [R2,R3] // libdvm.so:_Z18dvmUseCheckedJniVmP9JavaVMExt+3645
debug078:AC5BC75A LDR R2, =(aMentryactivity - 0xAC5BC764) // R2 = "mEntryActivity"
debug078:AC5BC75C LDR R3, =(aLjavaLangStr_0 - 0xAC5BC766) // R3 = "Ljava/lang/String;"
debug078:AC5BC75E MOVS R1, R5
debug078:AC5BC760 ADD R2, PC ; "mEntryActivity"
debug078:AC5BC762 ADD R3, PC ; "Ljava/lang/String;"
debug078:AC5BC764 BLX R7 // 调用 libdvm.so中的 Check_GetStaticFieldID 函数
debug078:AC5BC766 SUBS R7, R0, #0
debug078:AC5BC768 BEQ loc_AC5BC7B8
debug078:AC5BC76A MOVS R3, #0xA7
debug078:AC5BC76C LDR R2, [R4]
debug078:AC5BC76E LSLS R3, R3, #2
debug078:AC5BC770 MOVS R0, R4
debug078:AC5BC772 LDR R3, [R2,R3]
debug078:AC5BC774 MOVS R1, R6
debug078:AC5BC776 BLX R3 // R3 = libdvm.so:_Z18dvmUseCheckedJniVmP9JavaVMExt+29A1 = Check_NewStringUTF
debug078:AC5BC778 MOVS R3, #0x9A
debug078:AC5BC77A MOVS R6, R0
debug078:AC5BC77C LDR R2, [R4]
debug078:AC5BC77E LSLS R3, R3, #2
debug078:AC5BC780 MOVS R0, R4
debug078:AC5BC782 LDR R3, [R2,R3]
debug078:AC5BC784 MOVS R1, R5
debug078:AC5BC786 MOV R12, R3
debug078:AC5BC788 MOVS R2, R7
debug078:AC5BC78A MOVS R3, R6
debug078:AC5BC78C BLX R12 // R12 = libdvm.so:_Z18dvmUseCheckedJniVmP9JavaVMExt+30CD = Check_SetStaticObjectField
debug078:AC5BC78E CMP R6, #0
debug078:AC5BC790 BEQ loc_AC5BC7C4
debug078:AC5BC792 LDR R3, [R4]
debug078:AC5BC794 MOVS R1, R6
debug078:AC5BC796 LDR R3, [R3,#0x5C]
debug078:AC5BC798 MOVS R0, R4
debug078:AC5BC79A BLX R3 // 调用 Check_DeleteLocalRef
debug078:AC5BC79C MOVS R6, #1
debug078:AC5BC79E
debug078:AC5BC79E loc_AC5BC79E ; CODE XREF: debug078:AC5BC7C2j
debug078:AC5BC79E ; debug078:AC5BC7C6j
debug078:AC5BC79E LDR R3, [R4]
debug078:AC5BC7A0 MOVS R0, R4
debug078:AC5BC7A2 LDR R3, [R3,#0x5C]
debug078:AC5BC7A4 MOVS R1, R5
debug078:AC5BC7A6 BLX R3 // 调用 Check_DeleteLocalRef 函数
debug078:AC5BC7A8
debug078:AC5BC7A8 loc_AC5BC7A8 ; CODE XREF: debug078:AC5BC7B6j
debug078:AC5BC7A8 MOVS R0, R6
debug078:AC5BC7AA POP {R3-R7,PC}
debug078:AC5BC7AC ; -------------------------------------------------------------------------
debug078:AC5C5DEC ; =============== S U B R O U T I N E =======================================
debug078:AC5C5DEC
debug078:AC5C5DEC
debug078:AC5C5DEC sub_AC5C5DEC ; CODE XREF: sub_AC5C5DEC+Cp
debug078:AC5C5DEC ; sub_AC5C5DEC+14p ...
debug078:AC5C5DEC PUSH {R3-R5,LR}
debug078:AC5C5DEE CMP R1, #0
debug078:AC5C5DF0 BEQ locret_AC5C5E1C
debug078:AC5C5DF2 MOVS R4, R1
debug078:AC5C5DF4 MOVS R5, R0
debug078:AC5C5DF6 LDR R1, [R1]
debug078:AC5C5DF8 BL sub_AC5C5DEC
debug078:AC5C5DFC MOVS R0, R5
debug078:AC5C5DFE LDR R1, [R4,#4]
debug078:AC5C5E00 BL sub_AC5C5DEC
debug078:AC5C5E04 MOVS R5, R4
debug078:AC5C5E06 MOVS R0, R4
debug078:AC5C5E08 ADDS R5, #0x10
debug078:AC5C5E0A ADDS R0, #0x1C
debug078:AC5C5E0C BL sub_AC5C5C40
debug078:AC5C5E10 MOVS R0, R5
debug078:AC5C5E12 BL sub_AC5C5C40
debug078:AC5C5E16 MOVS R0, R4
debug078:AC5C5E18 BL sub_AC5EE4C8
debug078:AC5C5E1C
debug078:AC5C5E1C locret_AC5C5E1C ; CODE XREF: sub_AC5C5DEC+4j
debug078:AC5C5E1C POP {R3-R5,PC}
debug078:AC5C5E1C ; End of function sub_AC5C5DEC
debug078:AC5C5E1C
debug078:AC5C5E1C ; --------------------------------------------------
// 在调用这个函数之前,有memcamp,malloc函数等
debug078:AC5BF20C ; ---------------------------------------------------------------------------
debug078:AC5BF20C
debug078:AC5BF20C loc_AC5BF20C ; CODE XREF: debug078:AC5BF5D2j
debug078:AC5BF20C MOV R3, R9
debug078:AC5BF20E LDR R3, [R3]
debug078:AC5BF210 MOV R0, R9
debug078:AC5BF212 LDR R3, [R3,#0x50]
debug078:AC5BF214 MOVS R1, #0
debug078:AC5BF216 BLX R3 // Check_PopLocalFrame
debug078:AC5BF218 MOV R3, R11
debug078:AC5BF21A LDR R2, [SP,#0x84]
debug078:AC5BF21C LDR R3, [R3]
debug078:AC5BF21E LDR R0, [SP,#0x10]
debug078:AC5BF220 CMP R2, R3
debug078:AC5BF222 BEQ loc_AC5BF226
debug078:AC5BF224 B loc_AC5BF910
debug078:AC5BF226 ; --------------------------------------------------------------------
debug078:AC5BAB98 ; ---------------------------------------------------------------------------
debug078:AC5BAB98
debug078:AC5BAB98 loc_AC5BAB98 ; CODE XREF: debug078:AC5BAB92j
debug078:AC5BAB98 LDR R4, [SP,#0x24]
debug078:AC5BAB9A MOVS R0, R4
debug078:AC5BAB9C BL loc_AC5C349C
debug078:AC5BABA0 LDR R3, [R4]
debug078:AC5BABA2 LDR R1, =(aDalvikSystemDe - 0xAC5BABAC)
debug078:AC5BABA4 MOVS R0, R4
debug078:AC5BABA6 LDR R3, [R3,#0x18]
debug078:AC5BABA8 ADD R1, PC ; "dalvik/system/DexFile"
debug078:AC5BABAA BLX R3 // Check_FindClass()
debug078:AC5BABAC MOVS R3, #0xE2
debug078:AC5BABAE MOVS R5, R0
debug078:AC5BABB0 LDR R2, [R4]
debug078:AC5BABB2 LSLS R3, R3, #1
debug078:AC5BABB4 MOVS R0, R4
debug078:AC5BABB6 LDR R6, [R2,R3]
debug078:AC5BABB8 LDR R2, =(aGetclassnameli - 0xAC5BABC2)
debug078:AC5BABBA LDR R3, =(aILjavaLangStri - 0xAC5BABC4)
debug078:AC5BABBC MOVS R1, R5
debug078:AC5BABBE ADD R2, PC ; "getClassNameList"
debug078:AC5BABC0 ADD R3, PC ; "(I)[Ljava/lang/String;"
debug078:AC5BABC2 BLX R6 // getClassNameList R0(B88F0F28) R1(52B00019) R2("getClassNameList") R3("(I)[Ljava/lang/String;")
debug078:AC5BABC4 CMP R0, #0
debug078:AC5BABC6 BNE loc_AC5BABCC
debug078:AC5BABC8 BL loc_AC5BB3B6
debug078:AC5BABCC ; --------------------------------------------------------
写在最后,其实在第一次调用 Check_FindClass 的时候,dex已经解密了,可以按 ctrl+s 在最上方,有两处debugXX内存段。第一处为原APK的dex
第二处为 360加固壳的dex。不过现在解密的dex中的onCreate函数是用 native protect void onCreate 表示的。
也就是说,onCreate函数 是隐藏在so中的,可是我一直没有找到onCreate函数。所以有了上面的函数注册,也就是调用 Check_RegisterNatives 函数注册。
那么如此一来,可以再 FindClass 或者 RegisterNatives 函数下断点,看看注册了哪些函数,并记录下函数的地址,然后跟进进去,就可以找到具体的代码(个人猜想,暂时还没有去做)。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!