wuhanqi 发表于 2009-7-2 15:34

手脱Armadillo 5.0 (Standard + Debug-Blocker).学习笔记.

【文章标题】: 手脱Armadillo 5.0 (Standard + Debug-Blocker).学习笔记.
【文章作者】: wuhanqi
【作者邮箱】: wuhanqi@qq.com
【软件名称】: 一个unpackme
【下载地址】: 自己搜索下载
【加壳方式】: Armadillo 5.0 (Standard + Debug-Blocker)
【编写语言】: Delphi
【使用工具】: OD.ImportREC.LordPE.Arma Detach.PEID 0.94.FastScanner 2.1
【操作平台】: 盗版XP3
【作者声明】: 小菜一个.高手别笑话我哦~嘿嘿.
--------------------------------------------------------------------------------
【详细过程】
废话不多说.进入正题.脱壳目标为一个unpackme.

FastScan 2.1 查壳为 Microsoft Visual C++ 8
PEID 0.94 查壳为 Armadillo V5.0X -> Silicon Realms Toolworks   * Sign.By.fly *

首先运行Armadillo Process Detach.将unpackme脱入Arma Detach中。
会显示内容如下:
DONE!
Child process ID: 000002C8
Entry point: 004A2DC2
Original bytes: E8E3

这时我们打开一个od.文件--附加.然后选中PID为2C8的进程.即为Armadillo的子进程.
我们载入后.F9.再F12.便断到如下代码处:
004A2DC2 >- EB FE         JMP SHORT <ModuleEntryPoint>
004A2DC4    40            INC EAX
004A2DC5    0000            ADD BYTE PTR DS:,AL
004A2DC7^ E9 16FEFFFF   JMP 004A2BE2
004A2DCC    6A 0C         PUSH 0C
004A2DCE    68 B0104D00   PUSH 004D10B0
004A2DD3    E8 44150000   CALL 004A431C
004A2DD8    8B4D 08         MOV ECX,DWORD PTR SS:
004A2DDB    33FF            XOR EDI,EDI
004A2DDD    3BCF            CMP ECX,EDI
004A2DDF    76 2E         JBE SHORT 004A2E0F
004A2DE1    6A E0         PUSH -20
004A2DE3    58            POP EAX
004A2DE4    33D2            XOR EDX,EDX
004A2DE6    F7F1            DIV ECX
004A2DE8    3B45 0C         CMP EAX,DWORD PTR SS:
入口点是一个跳转.其实是Arma Detach为了防止穿山甲检测.才修改了入口点.
我们根据Arma Detach给我们的数据:Original bytes: E8E3.将jmp那两个字节修改为E8E3.即可恢复正常的入口点.
004A2DC2 >E8 E3400000   CALL 004A6EAA
004A2DC7^ E9 16FEFFFF   JMP 004A2BE2
004A2DCC    6A 0C         PUSH 0C
004A2DCE    68 B0104D00   PUSH 004D10B0
004A2DD3    E8 44150000   CALL 004A431C
004A2DD8    8B4D 08         MOV ECX,DWORD PTR SS:
004A2DDB    33FF            XOR EDI,EDI
004A2DDD    3BCF            CMP ECX,EDI
004A2DDF    76 2E         JBE SHORT 004A2E0F
004A2DE1    6A E0         PUSH -20
004A2DE3    58            POP EAX
004A2DE4    33D2            XOR EDX,EDX
004A2DE6    F7F1            DIV ECX
004A2DE8    3B45 0C         CMP EAX,DWORD PTR SS:
接下来我们需要确认OD没有硬件断点.以及Alt+B确认没有任何切换断点.
然后我们下bp VirtualProtect.可以使我们来到穿山甲处理IAT的地址.
shift+f9运行程序.我们要注意堆栈的变化:
0012F648   0048E8F7/CALL to VirtualProtect from UnpackMe.0048E8F1
0012F64C   00EB1000|Address = 00EB1000
0012F650   0006C82C|Size = 6C82C (444460.)
0012F654   00000040|NewProtect = PAGE_EXECUTE_READWRITE
0012F658   0012F67C\pOldProtect = 0012F67C

0012F648   0048E8F7/CALL to VirtualProtect from UnpackMe.0048E8F1
0012F64C   00F1E000|Address = 00F1E000
0012F650   000088F4|Size = 88F4 (35060.)
0012F654   00000002|NewProtect = PAGE_READONLY
0012F658   0012F67C\pOldProtect = 0012F67C

0012F648   0048E8F7/CALL to VirtualProtect from UnpackMe.0048E8F1
0012F64C   00F27000|Address = 00F27000
0012F650   00012AC4|Size = 12AC4 (76484.)
0012F654   00000004|NewProtect = PAGE_READWRITE
0012F658   0012F67C\pOldProtect = 0012F67C

0012F648   0048E8F7/CALL to VirtualProtect from UnpackMe.0048E8F1
0012F64C   00F3A000|Address = 00F3A000
0012F650   000024C0|Size = 24C0 (9408.)
0012F654   00000002|NewProtect = PAGE_READONLY
0012F658   0012F67C\pOldProtect = 0012F67C

0012F648   0048E8F7/CALL to VirtualProtect from UnpackMe.0048E8F1
0012F64C   00F3D000|Address = 00F3D000
0012F650   00006464|Size = 6464 (25700.)
0012F654   00000002|NewProtect = PAGE_READONLY
0012F658   0012F67C\pOldProtect = 0012F67C

00129470   00EF9946/CALL to VirtualProtect from 00EF9940
00129474   00401000|Address = UnpackMe.00401000
00129478   0005B000|Size = 5B000 (372736.)
0012947C   00000004|NewProtect = PAGE_READWRITE
00129480   0012C164\pOldProtect = 0012C164

00129470   00EF9991/CALL to VirtualProtect from 00EF998B
00129474   00401000|Address = UnpackMe.00401000
00129478   0005B000|Size = 5B000 (372736.)
0012947C   00000020|NewProtect = PAGE_EXECUTE_READ
00129480   0012C164\pOldProtect = 0012C164

00129470   00EF9946/CALL to VirtualProtect from 00EF9940
00129474   0045C000|Address = UnpackMe.0045C000
00129478   00002000|Size = 2000 (8192.)
0012947C   00000004|NewProtect = PAGE_READWRITE
00129480   0012C164\pOldProtect = 0012C164

00129470   00EF9991/CALL to VirtualProtect from 00EF998B
00129474   0045C000|Address = UnpackMe.0045C000
00129478   00002000|Size = 2000 (8192.)
0012947C   00000004|NewProtect = PAGE_READWRITE
00129480   0012C164\pOldProtect = 0012C164

00129470   00EF9946/CALL to VirtualProtect from 00EF9940
00129474   0045F000|Address = UnpackMe.0045F000
00129478   00003000|Size = 3000 (12288.)
0012947C   00000004|NewProtect = PAGE_READWRITE
00129480   0012C164\pOldProtect = 0012C164

00129470   00EF9991/CALL to VirtualProtect from 00EF998B
00129474   0045F000|Address = UnpackMe.0045F000
00129478   00003000|Size = 3000 (12288.)
0012947C   00000004|NewProtect = PAGE_READWRITE
00129480   0012C164\pOldProtect = 0012C164

00129470   00EFA814/CALL to VirtualProtect from 00EFA80E
00129474   0045F118|Address = UnpackMe.0045F118
00129478   0000008C|Size = 8C (140.)    <<--我们一直shift+f9.直到size显示为8c.这样.我们就到了关键处.
0012947C   00000004|NewProtect = PAGE_READWRITE
00129480   0012C028\pOldProtect = 0012C028
我们需要注意的是.在此之前断下来的VM都是EXE在执行IAT的处理.我们所需要断下来的地方是开始读写IAT的地方.
为什么我们需要当size为8c的时候返回呢?这里size 8c所代表的是1000个字节以上的意思.
即.如果我们的应用程序大小超过了1000个字节.那么便会显示8c.如果超过了2000个字节.那么便会显示16c.以此类推...
(我也不知道我解释清楚没...哎.语文功底不好...)
Let's go on!
此时我们Ctrl+f9.或F8.回到VM处!!
我们看下回到了哪里...
00EFA814    6A 14         PUSH 14                            <<--这里有像之前穿山甲版本一样的push 14.
00EFA816    E8 FBCA0000   CALL 00F07316
00EFA81B    83C4 04         ADD ESP,4
00EFA81E    8985 84ABFFFF   MOV DWORD PTR SS:,EAX
00EFA824    83BD 84ABFFFF 0>CMP DWORD PTR SS:,0
00EFA82B    74 59         JE SHORT 00EFA886
00EFA82D    8B0D EC53F300   MOV ECX,DWORD PTR DS:
00EFA833    898D 10AAFFFF   MOV DWORD PTR SS:,ECX
00EFA839    8B95 74D8FFFF   MOV EDX,DWORD PTR SS:
00EFA83F    0395 78D3FFFF   ADD EDX,DWORD PTR SS:
00EFA845    8B85 84ABFFFF   MOV EAX,DWORD PTR SS:
00EFA84B    8910            MOV DWORD PTR DS:,EDX
哈哈.既然又像以前一样了.那我们也就好办了.
现在我们需要寻找push 100.这条命令.重点是这条命令下面的call的地址.call所调用的地址就是移动处理IAT的地址!
我们把滚轮向下滚...来到这里:
00EFAA7B    8B85 40C2FFFF   MOV EAX,DWORD PTR SS:
00EFAA81    8378 08 00      CMP DWORD PTR DS:,0
00EFAA85    74 4A         JE SHORT 00EFAAD1
00EFAA87    68 00010000   PUSH 100                   <<---我们要找的PUSH 100
00EFAA8C    8D8D 40C1FFFF   LEA ECX,DWORD PTR SS:
00EFAA92    51            PUSH ECX
00EFAA93    8B95 40C2FFFF   MOV EDX,DWORD PTR SS:
00EFAA99    8B02            MOV EAX,DWORD PTR DS:
00EFAA9B    50            PUSH EAX
00EFAA9C    E8 2F7CFBFF   CALL 00EB26D0            <<---关键F7入!
00EFAAA1    83C4 0C         ADD ESP,0C
00EFAAA4    8D8D 40C1FFFF   LEA ECX,DWORD PTR SS:
00EFAAAA    51            PUSH ECX
跟进 CALL 00EB26D0来到:
00EB26D0    55            PUSH EBP          <<---不管他.直接retn.避开处理IAT!
00EB26D1    8BEC            MOV EBP,ESP
00EB26D3    83EC 2C         SUB ESP,2C
00EB26D6    833D 00A6F200 0>CMP DWORD PTR DS:,0
此时我们删除VirtualProtect断点.通过下bp CreateThread 寻找真正的OEP!
下好断点后.shift+f9!断下来后Crtl+f9回到VM!来到这里:
00EE364C    50            PUSH EAX
00EE364D    FF15 84E2F100   CALL DWORD PTR DS:               ; KERNEL32.CloseHandle
00EE3653    5E            POP ESI
00EE3654    5B            POP EBX
00EE3655    8BE5            MOV ESP,EBP
00EE3657    5D            POP EBP
00EE3658    C3            RETN
继续Crtl+F9!!
00EFF1C5    B9 04A6F200   MOV ECX,0F2A604
00EFF1CA    E8 B136FBFF   CALL 00EB2880
00EFF1CF    E9 25010000   JMP 00EFF2F9
00EFF1D4    E8 073CFDFF   CALL 00ED2DE0
00EFF1D9    C705 3877F200 1>MOV DWORD PTR DS:,0F21C10
00EFF1E3    E8 A894FDFF   CALL 00ED8690
00EFF1E8    6A 00         PUSH 0
00EFF1EA    E8 2143FEFF   CALL 00EE3510
00EFF1EF    83C4 04         ADD ESP,4               <<---出来后到这里!!
00EFF1F2    B9 B8B4F200   MOV ECX,0F2B4B8
00EFF1F7    E8 B4BFFBFF   CALL 00EBB1B0
00EFF1FC    0FB6D0          MOVZX EDX,AL
00EFF1FF    85D2            TEST EDX,EDX
00EFF201    74 0C         JE SHORT 00EFF20F
00EFF203    6A 01         PUSH 1
00EFF205    B9 B8B4F200   MOV ECX,0F2B4B8
00EFF20A    E8 11A6FCFF   CALL 00EC9820
00EFF20F    C705 3877F200 0>MOV DWORD PTR DS:,0F21C08
00EFF219    B9 04A6F200   MOV ECX,0F2A604
00EFF21E    E8 5D36FBFF   CALL 00EB2880
00EFF223    C745 F0 0000000>MOV DWORD PTR SS:,0
00EFF22A    8D45 E8         LEA EAX,DWORD PTR SS:
00EFF22D    50            PUSH EAX
00EFF22E    68 10F3EF00   PUSH 0EFF310
00EFF233    FF15 74B1F200   CALL DWORD PTR DS:
这样我们就到了VM中Armadillo 运行程序的地方!
我们向下拉.寻找call ecx.找到的第一个call ecx不是重点.我们需要的是第二个!!
00EFF29B    8B48 14         MOV ECX,DWORD PTR DS:
00EFF29E    51            PUSH ECX
00EFF29F    8B55 08         MOV EDX,DWORD PTR SS:
00EFF2A2    8B42 10         MOV EAX,DWORD PTR DS:
00EFF2A5    50            PUSH EAX
00EFF2A6    8B4D F4         MOV ECX,DWORD PTR SS:
00EFF2A9    2B4D E0         SUB ECX,DWORD PTR SS:
00EFF2AC    FFD1            CALL ECX                           <<---第一个ECX.不重要.忽略!
00EFF2AE    8945 FC         MOV DWORD PTR SS:,EAX
00EFF2B1    EB 46         JMP SHORT 00EFF2F9
00EFF2B3    8B55 08         MOV EDX,DWORD PTR SS:
00EFF2B6    833A 01         CMP DWORD PTR DS:,1
00EFF2B9    75 3E         JNZ SHORT 00EFF2F9
00EFF2BB    A1 04BBF200   MOV EAX,DWORD PTR DS:
00EFF2C0    8B0D 04BBF200   MOV ECX,DWORD PTR DS:            ; UnpackMe.004CB378
00EFF2C6    8B50 68         MOV EDX,DWORD PTR DS:
00EFF2C9    3351 34         XOR EDX,DWORD PTR DS:
00EFF2CC    A1 04BBF200   MOV EAX,DWORD PTR DS:
00EFF2D1    3350 60         XOR EDX,DWORD PTR DS:
00EFF2D4    8955 DC         MOV DWORD PTR SS:,EDX
00EFF2D7    8B4D 08         MOV ECX,DWORD PTR SS:
00EFF2DA    8B51 04         MOV EDX,DWORD PTR DS:
00EFF2DD    52            PUSH EDX
00EFF2DE    8B45 08         MOV EAX,DWORD PTR SS:
00EFF2E1    8B48 08         MOV ECX,DWORD PTR DS:
00EFF2E4    51            PUSH ECX
00EFF2E5    6A 00         PUSH 0
00EFF2E7    8B55 08         MOV EDX,DWORD PTR SS:
00EFF2EA    8B42 0C         MOV EAX,DWORD PTR DS:
00EFF2ED    50            PUSH EAX
00EFF2EE    8B4D F4         MOV ECX,DWORD PTR SS:
00EFF2F1    2B4D DC         SUB ECX,DWORD PTR SS:
00EFF2F4    FFD1            CALL ECX                            <<----第二个ECX.重要.跟进飞向OEP!!
00EFF2F6    8945 FC         MOV DWORD PTR SS:,EAX
00EFF2F9    8B45 FC         MOV EAX,DWORD PTR SS:
00EFF2FC    5E            POP ESI
00EFF2FD    8BE5            MOV ESP,EBP
00EFF2FF    5D            POP EBP
00EFF300    C3            RETN
此时我们运行LordPE.纠正一下映像大小.完整dump一下子进程.注意.PID一定要为2C8的进程!!!
dump好之后.运行ImportREC.载入PID为2C8的进程!输入OEP:5B52C.获取输入表.有12个无效指针.直接剪掉!然后修复程序.
修复后程序可运行啦~哈哈~
FastScan查壳为 Borland Delphi 2006
PEID 查壳为 Borland Delphi 6.0


--------------------------------------------------------------------------------
【经验总结】
菜鸟最近才开始学各大强壳手脱方法.
学习一个国外高人的脱壳方法笔记.没什么技术含量.拉出来与大家分享一下而已.
献丑了.

--------------------------------------------------------------------------------
【版权声明】: 还不是踩在巨人的肩膀上说话?哪里来的版权.随便怎么样.哈哈~

                                                       2009年07月02日 15:27:41

iy0507 发表于 2009-7-2 18:40

顶顶顶 不懂果然需要继续学习了。

Register 发表于 2009-7-3 18:59

顶,好文
喜欢你的版权声明:P

suko 发表于 2009-7-3 22:31

好文好文

麻烦楼主做个动画。

lin440w2 发表于 2009-7-3 22:37

下来学习学习

wuhanqi 发表于 2009-7-4 00:28

汗.这都给加精华.太受宠若惊了...
回2楼的话:俺只是说实话而已.谁不是从前辈的经验的基础上一点点学来的呢?

cwres 发表于 2009-7-4 08:43

学习学习。

lbmx8 发表于 2009-7-5 16:13

下来学习,谢楼主。。。

sunny19831129 发表于 2010-4-18 21:20

什么东西呀
页: [1]
查看完整版本: 手脱Armadillo 5.0 (Standard + Debug-Blocker).学习笔记.