看雪论坛
发新帖

[原创]360加固逆向脱壳之过反调试--后续

坝坝虎 2016-10-21 11:27 9111
接上一篇《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 函数下断点,看看注册了哪些函数,并记录下函数的地址,然后跟进进去,就可以找到具体的代码(个人猜想,暂时还没有去做)。
本主题帖已收到 0 次赞赏,累计¥0.00
最新回复 (20)
1
hzqhacker 2016-10-21 12:08
2
大家都在逆360,正好证明了360加固保的强大!用户量绝对业界第一!
gugubupt 2016-10-21 12:11
3
mark
1
elianmeng 2016-10-21 12:18
4
MARK 我最近也在分析hander
cjxqhhh 2016-10-21 16:51
5
楼主强大
sherrydl 2016-10-22 20:39
6
逆向666,RegisterNatives 找onCreate地址是可以的的,然后你就可以跟下看下是怎么做的,现在vmp其实都是写了一套自己的解释器。
IceMaker 2016-10-23 19:27
7
good job!
无边 2016-10-30 18:56
8
大哥,发个测试样本呗
chicha 2016-10-30 19:23
9
Mark,谢谢分享
坝坝虎 2016-10-31 11:34
10
样本在上一篇: http://bbs.pediy.com/showthread.php?t=213214

不过现在我也贴出来

http://pan.baidu.com/s/1pKSP22n
七少月 2016-10-31 20:20
11
恭喜你,你的猜想是合理的
王小东 2016-11-21 09:28
12
逆向666,RegisterNatives 找onCreate地址是可以的的,然后你就可以跟下看下是怎么做的,现在vmp其实都是写了一套自己的解释器。
永哥呀 2016-11-23 09:28
13
七少你也搞360了啊
bwn 2017-2-27 13:59
14
现在读用4,4,傻瓜
1
奔跑的阿狸 2017-3-15 17:04
15
360是如何把dex中的代码抽取 成so的?
赵家死人军队 2017-3-17 16:29
16
楼主的问题解决了吗,有没有什么方法去解析onCreate在so文件里的读取,光得到dex都无法运行,就无法重新打包了,每次打包后运行都是直接报错退出
vurtneye 2017-3-27 09:29
17

....

vurtneye 2017-4-4 10:43
18

..

tDasm 2017-4-6 08:24
19
method  =  dvmFindDirectMethodByDescriptor(clazz,  methodName,  signature);

          if  (method  ==  NULL)

                  method  =  dvmFindVirtualMethodByDescriptor(clazz,  methodName,  signature);

          if  (method  ==  NULL)  {

                  LOGW("ERROR:  Unable  to  find  decl  for  native  %s.%s:%s  ",

                          clazz->descriptor,  methodName,  signature);

                  goto  bail;

          }
vurtneye 2017-4-8 00:44
20
tDasm method = dvmFindDirectMethodByDescriptor(clazz, methodName, signature); if (method == NULL) ...
这段代码有点不懂,获取到方法不难,就是不知道native  oncreate这个方法里面的实现。  本菜虚心请教
深海大石头 2017-6-1 11:52
21
求大神帮忙拖一个壳,有偿:加微信18589072870
返回



©2000-2017 看雪学院 | Based on Xiuno BBS | 知道创宇带宽支持 | 微信公众号:ikanxue
Time: 0.032, SQL: 10 / 京ICP备10040895号-17