欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

对Asprotect脱壳的一点总结 (20千字)

对Asprotect脱壳的一点总结 (20千字)

对Asprotect脱壳的一点总结
@#$@#$ 熏倒 @#$@#$....
写作
【声明】
我写文章以交流为主,希望大家在转载时能保持文章的完整性。
【前言】
从我知道的情况来看,对Asprotect加壳的程序大致可以分为三类:(这种分类方法不具有权威性,只是我自己为了区别而已)
1、这类程序只检测SICE,SIWVID,SIWDEBUG,内存中可以得到完整的import table。一次跟踪可完成脱壳。
2、这类程序检测SICE,SIWVID,SIWDEBUG和BCHK,内存中也可以得到完整的import table。一次跟踪也可完成脱壳。
3、这类程序同 2 ,只是内存中无法得到完整的import table。因此需要其他手段来辅助得到import table。可能需要几次跟踪完成脱壳。
以上三类程序脱壳方式基本相同。因此我把跟踪过程中几个关键的特征说明一下。
【分析】
①寻找合适的中断进入加壳程序。(我称为找进入点)
(注:在跟踪之前,最好用ICEPatch修补你的SoftICE,否则你就要手动跳过防跟踪代码了)
对于 1 类程序,一般可以用以下方式进入:
Ctrl-D中断,进入SoftICE。下指令
bpx CreateFileA do "p ret"
然后按F5返回Windows,运行加壳程序,中断在我们所设下的中断处。
以后的跟踪可以直接继续,看见不远处有 ret 语句还可以按 F12 键快速返回到上一层调用中。
对于 2 、3 两类程序,一般可以用以下方式进入(操作方法同上,只是设下的断点不同)。这次我们设断点
bpint 3
以后的跟踪与上有些不同,在《找Entry Point的又一方法 -----针对Asprotect v1.0加壳的程序》一文中我已有说明,这里简要说明一下。
中断后一般你可以看到类似如下的屏幕:
015F:004BF23C  CC                  INT      3            <--你中断在此
015F:004BF23D  EB02                JMP      004BF241
015F:004BF23F  E9025DEB02          JMP      03374F46
015F:004BF244  E9FF33C05A          JMP      5B0C2648
015F:004BF249  59                  POP      ECX
015F:004BF24A  59                  POP      ECX
015F:004BF24B  648910              MOV      FS:[EAX],EDX
015F:004BF24E  EB0A                JMP      004BF25A
015F:004BF250  E91305FFFF          JMP      004AF768        <--注意这个跳转语句,int 3过后就要到这里继续了。
015F:004BF255  E8AA07FFFF          CALL      004AFA04
015F:004BF25A  8A1518514C00        MOV      DL,[004C5118]
015F:004BF260  8B45F8              MOV      EAX,[EBP-08]
把光标移到第五个Jmp语句以后,按F7键。好,以后的跟踪和上面的方法相同。
②检测CRC的地方
在按了几个 F12后,一般就到了检测CRC的代码地方,这里我们不需要做什么,只是让大家明白,如果你改到了程序某处,在这里就要关心一下了。
015F:004C6B74  EBF0                JMP      004C6B66
015F:004C6B76  8B45EC              MOV      EAX,[EBP-14]    <--注意此处
015F:004C6B79  3B45F0              CMP      EAX,[EBP-10]    <--注意此处
015F:004C6B7C  7443                JZ        004C6BC1        <--如果比较的结果相同,就跳转了,否则就到下面显示File corrupted! 的框框了
015F:004C6B7E  8A155CC94C00        MOV      DL,[004CC95C]
015F:004C6B84  8B45F8              MOV      EAX,[EBP-08]
015F:004C6B87  E848E4FFFF          CALL      004C4FD4
015F:004C6B8C  8945F4              MOV      [EBP-0C],EAX
015F:004C6B8F  837DF400            CMP      DWORD PTR [EBP-0C],00
015F:004C6B93  742C                JZ        004C6BC1
015F:004C6B95  8D85E4FEFFFF        LEA      EAX,[EBP-011C]
015F:004C6B9B  8D95E9FEFFFF        LEA      EDX,[EBP-0117]
大家注意其中三句的特征,以后跟踪时就知道这里是比较CRC的地方就行了。对于做inline patch的朋友就要记住了。
③获得 import table 和 Entry Point
在按过几下 F12 键后,就会来到类似如下代码的地方,这里我以ARPR.EXE来做例子,来一段段的分析一下,许多Asprotect加壳的程序都有这样一段,熟悉了特征以后,再对Asprotect脱壳你也可以很轻松了。
015F:004C6EAB  E828FAFFFF          CALL      004C68D8
015F:004C6EB0  33C0                XOR      EAX,EAX            <--你来到此处,一般 XOR EAX,EAX 是特征.
015F:004C6EB2  5A                  POP      EDX
015F:004C6EB3  59                  POP      ECX
015F:004C6EB4  59                  POP      ECX
015F:004C6EB5  648910              MOV      FS:[EAX],EDX
015F:004C6EB8  EB11                JMP      004C6ECB            <--跳到下一段
015F:004C6EBA  E9E900FFFF          JMP      004B6FA8
015F:004C6EBF  33C0                XOR      EAX,EAX
015F:004C6EC1  E89EEFFFFF          CALL      004C5E64
015F:004C6EC6  E87903FFFF          CALL      004B7244
以后我们重点关注几个Call调用,以后再跟踪这类Asprotect加壳的程序就有经验了。
015F:004C6ECB  33C0                XOR      EAX,EAX
015F:004C6ECD  55                  PUSH      EBP
015F:004C6ECE  68086F4C00          PUSH      004C6F08
015F:004C6ED3  64FF30              PUSH      DWORD PTR FS:[EAX]
015F:004C6ED6  648920              MOV      FS:[EAX],ESP
015F:004C6ED9  8B4508              MOV      EAX,[EBP+08]
015F:004C6EDC  8B00                MOV      EAX,[EAX]
015F:004C6EDE  50                  PUSH      EAX
015F:004C6EDF  B804464C00          MOV      EAX,004C4604
015F:004C6EE4  50                  PUSH      EAX
015F:004C6EE5  6A00                PUSH      00
015F:004C6EE7  8B4508              MOV      EAX,[EBP+08]
015F:004C6EEA  8D4824              LEA      ECX,[EAX+24]
015F:004C6EED  8B4508              MOV      EAX,[EBP+08]
015F:004C6EF0  8D500C              LEA      EDX,[EAX+0C]
015F:004C6EF3  8B4508              MOV      EAX,[EBP+08]
015F:004C6EF6  8B4008              MOV      EAX,[EAX+08]
015F:004C6EF9  E842F0FFFF          CALL      004C5F40            <--注意这个Call调用
015F:004C6EFE  33C0                XOR      EAX,EAX
015F:004C6F00  5A                  POP      EDX
015F:004C6F01  59                  POP      ECX
015F:004C6F02  59                  POP      ECX
015F:004C6F03  648910              MOV      FS:[EAX],EDX
015F:004C6F06  EB13                JMP      004C6F1B            <--跳到下一段
015F:004C6F08  E99B00FFFF          JMP      004B6FA8
015F:004C6F0D  66B80B00            MOV      AX,000B
015F:004C6F11  E84EEFFFFF          CALL      004C5E64
015F:004C6F16  E82903FFFF          CALL      004B7244
在以上要注意的Call调用处我们可以停下来,下指令
d 401000    (说明: 401000由来为 <Image Base>+<First Section RVA> )
我们可以看到在没有执行这个Call调用之前,数据窗口显示的为 ?? ??。这说明这段代码还没有加载到内存中。如果按 F10键执行这个调用过后,数据窗口就会显示各种十六进制数据。这说明这个Call调用的基本功能为加载数据。
(按上段)
015F:004C6F1B  33C0                XOR      EAX,EAX
015F:004C6F1D  55                  PUSH      EBP
015F:004C6F1E  68716F4C00          PUSH      004C6F71
015F:004C6F23  64FF30              PUSH      DWORD PTR FS:[EAX]
015F:004C6F26  648920              MOV      FS:[EAX],ESP
015F:004C6F29  8B4508              MOV      EAX,[EBP+08]
015F:004C6F2C  8B00                MOV      EAX,[EAX]
015F:004C6F2E  50                  PUSH      EAX
015F:004C6F2F  B8485E4C00          MOV      EAX,004C5E48
015F:004C6F34  50                  PUSH      EAX
015F:004C6F35  B85C5E4C00          MOV      EAX,004C5E5C
015F:004C6F3A  50                  PUSH      EAX
015F:004C6F3B  6A00                PUSH      00
015F:004C6F3D  B8645E4C00          MOV      EAX,004C5E64
015F:004C6F42  50                  PUSH      EAX
015F:004C6F43  B8A4894B00          MOV      EAX,004B89A4
015F:004C6F48  50                  PUSH      EAX
015F:004C6F49  8B4508              MOV      EAX,[EBP+08]
015F:004C6F4C  8B4020              MOV      EAX,[EAX+20]
015F:004C6F4F  50                  PUSH      EAX
015F:004C6F50  8B4508              MOV      EAX,[EBP+08]
015F:004C6F53  8D4824              LEA      ECX,[EAX+24]
015F:004C6F56  8B4508              MOV      EAX,[EBP+08]
015F:004C6F59  8B500C              MOV      EDX,[EAX+0C]
015F:004C6F5C  8B4508              MOV      EAX,[EBP+08]
015F:004C6F5F  8B4008              MOV      EAX,[EAX+08]
015F:004C6F62  E81DF1FFFF          CALL      004C6084            <--注意这个Call调用
015F:004C6F67  33C0                XOR      EAX,EAX
015F:004C6F69  5A                  POP      EDX
015F:004C6F6A  59                  POP      ECX
015F:004C6F6B  59                  POP      ECX
015F:004C6F6C  648910              MOV      FS:[EAX],EDX
015F:004C6F6F  EB13                JMP      004C6F84            <--跳到下一段
015F:004C6F71  E93200FFFF          JMP      004B6FA8
015F:004C6F76  66B80C00            MOV      AX,000C
015F:004C6F7A  E8E5EEFFFF          CALL      004C5E64
015F:004C6F7F  E8C002FFFF          CALL      004B7244
我们再来关注一下上面这个要注意的Call调用。如果你用 F10 键带过这个Call调用。会发现数据窗口的内容改变了。好我们再来看看 idata Section所在位置的情况,下指令
d 418000    (注:ARPR.EXE的Image Base为 400000,idata Section 的 RVA 为 18000)
可以看到数据窗口显示的全是 00,向下翻页,仍然是 00,这说明这个Call调用的功能可能是解压还原代码,并且初始化 idata Section。
(接上段)
015F:004C6F84  B84B894B00          MOV      EAX,004B894B
015F:004C6F89  40                  INC      EAX
015F:004C6F8A  890530DA4C00        MOV      [004CDA30],EAX
015F:004C6F90  B82B894B00          MOV      EAX,004B892B
015F:004C6F95  890534DA4C00        MOV      [004CDA34],EAX
015F:004C6F9B  FF0534DA4C00        INC      DWORD PTR [004CDA34]
015F:004C6FA1  33C0                XOR      EAX,EAX
015F:004C6FA3  55                  PUSH      EBP
015F:004C6FA4  6805704C00          PUSH      004C7005
015F:004C6FA9  64FF30              PUSH      DWORD PTR FS:[EAX]
015F:004C6FAC  648920              MOV      FS:[EAX],ESP
015F:004C6FAF  B8485E4C00          MOV      EAX,004C5E48
015F:004C6FB4  50                  PUSH      EAX
015F:004C6FB5  B8AC694B00          MOV      EAX,004B69AC
015F:004C6FBA  50                  PUSH      EAX
015F:004C6FBB  A130DA4C00          MOV      EAX,[004CDA30]
015F:004C6FC0  50                  PUSH      EAX
015F:004C6FC1  A134DA4C00          MOV      EAX,[004CDA34]
015F:004C6FC6  50                  PUSH      EAX
015F:004C6FC7  B8645E4C00          MOV      EAX,004C5E64
015F:004C6FCC  50                  PUSH      EAX
015F:004C6FCD  B894954B00          MOV      EAX,004B9594
015F:004C6FD2  50                  PUSH      EAX
015F:004C6FD3  B874954B00          MOV      EAX,004B9574
015F:004C6FD8  50                  PUSH      EAX
015F:004C6FD9  B834904B00          MOV      EAX,004B9034
015F:004C6FDE  50                  PUSH      EAX
015F:004C6FDF  8B4508              MOV      EAX,[EBP+08]
015F:004C6FE2  8B4020              MOV      EAX,[EAX+20]
015F:004C6FE5  50                  PUSH      EAX
015F:004C6FE6  B9E0944B00          MOV      ECX,004B94E0
015F:004C6FEB  8B4508              MOV      EAX,[EBP+08]
015F:004C6FEE  8B5014              MOV      EDX,[EAX+14]
015F:004C6FF1  8B4508              MOV      EAX,[EBP+08]
015F:004C6FF4  8B00                MOV      EAX,[EAX]
015F:004C6FF6  E8A5F5FFFF          CALL      004C65A0            <--注意这个Call调用
015F:004C6FFB  33C0                XOR      EAX,EAX            <--这里一般就是Dump import table的地方
015F:004C6FFD  5A                  POP      EDX
015F:004C6FFE  59                  POP      ECX
015F:004C6FFF  59                  POP      ECX
015F:004C7000  648910              MOV      FS:[EAX],EDX
015F:004C7003  EB13                JMP      004C7018            <--跳到下一段
015F:004C7005  E99EFFFEFF          JMP      004B6FA8
015F:004C700A  66B80D00            MOV      AX,000D
015F:004C700E  E851EEFFFF          CALL      004C5E64
015F:004C7013  E82C02FFFF          CALL      004B7244
我们来看看上面这个要注意的Call调用有什么作用。如果你用 F10 键带过这个Call调用,再看看数据窗口的变化,
我们向下翻页看看,这次不再是 00,变成各种数据。这说明这个Call调用的功能可能是还原 idata Section,因此在该调用后的 XOR EAX,EAX就是我们Dump出 import table的地方。对于前面划分出的三类程序中前两类,都可以在此处看到完整的 import table,是Dump出 import table的时候了,可以下指令
/dump <Image Base + idata Section RVA> <idata Section Size> <FileName>    (这是ICEDump 1.61的指令用法)
而对于第三类程序则要用其他方法。(补充说明:对于第三类程序的 import table重建问题由于我也没有找到一种统一的方法。只能不同情况不同对待。因此以后单独写文说明。)
如果你喜欢用 bpm 跟踪 idata Section的变化来做进入点。那么一般在按几个 F12键后,就在处了。
(接上段)
015F:004C7018  33C0                XOR      EAX,EAX
015F:004C701A  55                  PUSH      EBP
015F:004C701B  6838704C00          PUSH      004C7038
015F:004C7020  64FF30              PUSH      DWORD PTR FS:[EAX]
015F:004C7023  648920              MOV      FS:[EAX],ESP
015F:004C7026  8B4508              MOV      EAX,[EBP+08]
015F:004C7029  E8D6FCFFFF          CALL      004C6D04            <--注意这个Call调用
015F:004C702E  33C0                XOR      EAX,EAX
015F:004C7030  5A                  POP      EDX
015F:004C7032  59                  POP      ECX
015F:004C7033  648910              MOV      FS:[EAX],EDX
015F:004C7036  EB13                JMP      004C704B            <--跳到下一段
015F:004C7038  E96BFFFEFF          JMP      004B6FA8
015F:004C703D  66B81100            MOV      AX,0011
015F:004C7041  E81EEEFFFF          CALL      004C5E64
015F:004C7046  E8F901FFFF          CALL      004B7244
如果我们用 F10 键带过这个Call调用,会发现数据窗口的内容又有所变化。不过这次我们看到的数据都比较大。如果你进入此调用跟踪会发现它的作用就是获取idata Section中的各个函数的指针放入此处,如果你对可执行文件的加载机制有所了解的话,那么就知道这是加壳程序在做Windows的工作,把各个Fircc转换成真正函数入口指针。因此过了此处,你再就无法获得"干净"的import table了。
(接上段)
015F:004C704B  33C0                XOR      EAX,EAX
015F:004C704D  55                  PUSH      EBP
015F:004C704E  6884704C00          PUSH      004C7084
015F:004C7053  64FF30              PUSH      DWORD PTR FS:[EAX]
015F:004C7056  648920              MOV      FS:[EAX],ESP
015F:004C7059  B8645E4C00          MOV      EAX,004C5E64
015F:004C705E  50                  PUSH      EAX
015F:004C705F  8B4508              MOV      EAX,[EBP+08]
015F:004C7062  8B4810              MOV      ECX,[EAX+10]
015F:004C7065  8B4508              MOV      EAX,[EBP+08]
015F:004C7068  8B5004              MOV      EDX,[EAX+04]
015F:004C706B  8B4508              MOV      EAX,[EBP+08]
015F:004C706E  8B00                MOV      EAX,[EAX]
015F:004C7070  E833F6FFFF          CALL      004C66A8            <---注意此Call调用
015F:004C7075  A22CDA4C00          MOV      [004CDA2C],AL
015F:004C707A  33C0                XOR      EAX,EAX
015F:004C707D  59                  POP      ECX
015F:004C707E  59                  POP      ECX
015F:004C707F  648910              MOV      FS:[EAX],EDX
015F:004C7082  EB13                JMP      004C7097            <--跳到下一段
015F:004C7084  E91FFFFEFF          JMP      004B6FA8
015F:004C7089  66B80E00            MOV      AX,000E
015F:004C708D  E8D2EDFFFF          CALL      004C5E64
015F:004C7092  E8AD01FFFF          CALL      004B7244
对于此Call调用是什么作用,我现在还说不出来。如果你用 F10 键带来,一点事没有。但是如果你是一个好奇心太强的人,按 F8 键进入看个究竟的话,那么我恭喜你,你进入了 Asprotect 的圈套。也许你会在带过某个Call调用时程序运行了。因此你一定以为其中有 Entry Point ,于是重新来过,又进入那个Call调用看看,如此反复,也许你会某一层中发现 Entry Point,果真如此,那么我十分钦佩你的精神。我在跟踪到第四层时依然没有找到,就放弃了。至今我还没有弄明白这种圈套是怎么实现的。不过Asprotect作者一定很高兴他写的代码一行也没有浪费。
(接上段)
015F:004C7097  8B4508              MOV      EAX,[EBP+08]
015F:004C709A  8D4818              LEA      ECX,[EAX+18]
015F:004C709D  8B4508              MOV      EAX,[EBP+08]
015F:004C70A0  8B10                MOV      EDX,[EAX]
015F:004C70A2  8B4508              MOV      EAX,[EBP+08]
015F:004C70A5  8B401C              MOV      EAX,[EAX+1C]
015F:004C70A8  E887F6FFFF          CALL      004C6734            <---注意此Call调用
015F:004C70AD  5F                  POP      EDI
015F:004C70AE  5E                  POP      ESI
015F:004C70AF  5B                  POP      EBX
015F:004C70B0  5D                  POP      EBP
015F:004C70B1  C20400              RET      0004
如果你是个懒人,直接到此。那么我说你真有福气。这个Call调用一定要按 F8 键进入。其中你可以找到 Entry Point。
④获取整个内存映象
在进入Call调用后,对于前两类程序和后一类程序的情况有所不同
(注:这里以跟踪BrickShooter时截取的屏幕和跟踪ARPR时截取的屏幕做一比较)

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功