ximo 发表于 2008-6-21 22:30

菜鸟我的第一篇脱文:手脱Armadillo5.0双进程标准壳

【破文标题】手脱Armadillo5.0双进程标准壳
【破文作者】zk8891111(其实也就是我,呵呵)
【作者邮箱】178911980@163.com
【破解工具】OD,LordPE ImportREC
【破解平台】XP SP2
【原版下载】见附件
【破解声明】菜鸟练习笔记,无技术含量,有纪念意义
------------------------------------------------------------------------
【破解过程】最近一直在学习脱穿山甲的壳,今天抽空写个破文,当是学习笔记。高手就飘过了~

1、查壳:用PEID查壳结果为:Armadillo V5.00 -> Silicon Realms Toolworks *
    运行程序,打开资源管理器,很明显是双进程的
2、设置OD:忽略所有异常,用插件隐藏OD

3、开始脱壳,用OD载入

004A2DC2 A> E8 E3400000   call Armadill.004A6EAA   //停在这
004A2DC7 ^ E9 16FEFFFF   jmp Armadill.004A2BE2
004A2DCC6A 0C      push 0C
004A2DCE68 B0104D00   push Armadill.004D10B0
004A2DD3E8 44150000   call Armadill.004A431C
004A2DD88B4D 08       mov ecx,dword ptr ss:
004A2DDB33FF      xor edi,edi
004A2DDD3BCF      cmp ecx,edi
004A2DDF76 2E      jbe short Armadill.004A2E0F
004A2DE16A E0      push -20
(1) 把双进程变单进程:
下断点:BP OpenMutexA,SHIFT+F9

7C80EA3B k> 8BFF      mov edi,edi   //停在这
7C80EA3D55         push ebp
7C80EA3E8BEC      mov ebp,esp
7C80EA4051         push ecx
7C80EA4151         push ecx
7C80EA42837D 10 00   cmp dword ptr ss:,0
7C80EA4656         push esi
7C80EA470F84 D7540300    je kernel32.7C843F24


然后观察队栈窗口:

0012F720 0048EDAA /CALL 到 OpenMutexA 来自 Armadill.0048EDA4
0012F724 001F0001 |Access = 1F0001
0012F728 00000000 |Inheritable = FALSE
0012F72C 0012FD7C \MutexName = "1220::DA8B2CFD8D"
0012F730 6452266E记录数据为:0012FD7C,一会就会用到。

打开ALT+M内存镜像,找.code段的起始地址为00401000
于是,在反汇编窗口CTRL+G,来到00401000
然后输入下面代码:(大家做的时候其他的代码都不变,只改变第三句中的地址)

0040100060         pushad
004010019C         pushfd
0040100268 7CFD1200   push 12FD7C    //这里的地址就是刚才所记录的地址         
0040100733C0      xor eax,eax
0040100950         push eax
0040100A50         push eax
0040100B50         push eax
0040100CE8 4ED9407C   call kernel32.CreateMutexA
004010119D         popfd
0040101261         popad
00401013 - E9 23DA407C   jmp kernel32.OpenMutexA

接着在首句新建EIP,取消断点。

(2)处理IAT
这里有两种方法:
方法一:
下断点he GetModuleHandleA+9,SHIFT+F9多次,观察队栈,适当时机返回。

00129474 /0012EB88
00129478 |00EA5325 返回到 00EA5325 来自 kernel32.GetModuleHandleA
0012947C |00ED0C04 ASCII "kernel32.dll"
00129480 |00ED1AD0 ASCII "VirtualAlloc"

00129474 /0012EB88
00129478 |00EA5343 返回到 00EA5343 来自 kernel32.GetModuleHandleA
0012947C |00ED0C04 ASCII "kernel32.dll"
00129480 |00ED1AC4 ASCII "VirtualFree"

001291C0 /00129478
001291C4 |00E87F54 返回到 00E87F54 来自 kernel32.GetModuleHandleA
001291C8 |00129340 ASCII "kernel32.dll"

这时候就是返回时机了。
取消断点,ALT+F9,返回程序代码段,然后修改magic jump(不知道这里还可不可以叫magic jump)

00E87F548B55 F4       mov edx,dword ptr ss:
00E87F578B0D 7CDFED00    mov ecx,dword ptr ds:
00E87F5D890491       mov dword ptr ds:,eax
00E87F608B55 F4       mov edx,dword ptr ss:
00E87F63A1 7CDFED00   mov eax,dword ptr ds:
00E87F68833C90 00      cmp dword ptr ds:,0
00E87F6C75 5C      jnz short 00E87FCA
00E87F6E8B4D F8       mov ecx,dword ptr ss:
00E87F718B51 08       mov edx,dword ptr ds:
00E87F7483E2 02       and edx,2
00E87F7774 38      je short 00E87FB1
00E87F79B8 0B000000   mov eax,0B
00E87F7EC1E0 02       shl eax,2
00E87F818B0D 04BBED00    mov ecx,dword ptr ds:   ; Armadill.004CB378
00E87F878B15 04BBED00    mov edx,dword ptr ds:   ; Armadill.004CB378
00E87F8D8B35 04BBED00    mov esi,dword ptr ds:   ; Armadill.004CB378
00E87F938B5E 78       mov ebx,dword ptr ds:
00E87F96335A 34       xor ebx,dword ptr ds:
00E87F99331C01       xor ebx,dword ptr ds:
00E87F9C83E3 10       and ebx,10
00E87F9FF7DB      neg ebx
00E87FA11BDB      sbb ebx,ebx
00E87FA3F7DB      neg ebx
00E87FA50FB6C3       movzx eax,bl
00E87FA885C0      test eax,eax
00E87FAA75 05      jnz short 00E87FB1
00E87FAC ^ E9 1BFFFFFF   jmp 00E87ECC
00E87FB18D8D C8FEFFFF    lea ecx,dword ptr ss:
00E87FB751         push ecx
00E87FB8FF15 D4E1EC00    call dword ptr ds:      ; kernel32.LoadLibraryA
00E87FBE8B55 F4       mov edx,dword ptr ss:
00E87FC18B0D 7CDFED00    mov ecx,dword ptr ds:
00E87FC7890491       mov dword ptr ds:,eax
00E87FCA8B55 F4       mov edx,dword ptr ss:
00E87FCDA1 7CDFED00   mov eax,dword ptr ds:
00E87FD2833C90 00      cmp dword ptr ds:,0
00E87FD675 05      jnz short 00E87FDD          //把他NOP掉吧!
00E87FD8 ^ E9 EFFEFFFF   jmp 00E87ECC
00E87FDDC785 BCFEFFFF 000000>mov dword ptr ss:,0

处理完后,直接拉到下面:

00E8824633348A       xor esi,dword ptr ds:
00E882498B45 F4       mov eax,dword ptr ss:
00E8824C8B0D 7CDFED00    mov ecx,dword ptr ds:
00E88252893481       mov dword ptr ds:,esi
00E88255 ^ E9 72FCFFFF   jmp 00E87ECC
00E8825AEB 03      jmp short 00E8825F//在这F2,SHIFT+F9,取消断点

接着返回到刚才修改的地方,撤消修改,IAT处理到此结束!

方法二:下断点:bp VirtualProtect,SHIFT+F9,观察队栈,找适当时机返回
返回的时机就是:当Size的值小于1000,且NewProtect为PAGE_READWRITE时


00129470 00EAA814 /CALL 到 VirtualProtect 来自 00EAA80E
00129474 0045F118 |Address = Armadill.0045F118
00129478 0000008C |Size = 8C (140.)
0012947C 00000004 |NewProtect = PAGE_READWRITE
00129480 0012C028 \pOldProtect = 0012C028

这个时候就可以返回了!

取消断点,ALT+F9

00EAA8146A 14      push 14    //返回到这
00EAA816E8 FBCA0000   call 00EB7316
00EAA81B83C4 04       add esp,4
00EAA81E8985 84ABFFFF    mov dword ptr ss:,eax
00EAA82483BD 84ABFFFF 00cmp dword ptr ss:,0
00EAA82B74 59      je short 00EAA886
00EAA82D8B0D EC53EE00    mov ecx,dword ptr ds:
00EAA833898D 10AAFFFF    mov dword ptr ss:,ecx
00EAA8398B95 74D8FFFF    mov edx,dword ptr ss:
00EAA83F0395 78D3FFFF    add edx,dword ptr ss:

接着CTRL+F,查找命令push 100(把整个短块前面的勾去掉)

00EAAA8768 00010000   push 100      //来到这
00EAAA8C8D8D 40C1FFFF    lea ecx,dword ptr ss:
00EAAA9251         push ecx
00EAAA938B95 40C2FFFF    mov edx,dword ptr ss:
00EAAA998B02      mov eax,dword ptr ds:
00EAAA9B50         push eax
00EAAA9CE8 2F7CFBFF   call 00E626D0    //跟随
00EAAAA183C4 0C       add esp,0C
00EAAAA48D8D 40C1FFFF    lea ecx,dword ptr ss:

然后跟随进入下面的一个CALL,然后把段首改为RETN

这样,同样可以阻止对IAT进行修改,达到目的!

(3)寻找OEP
同样有2种方法:
方法一:下断点bp CreateThread,SHIFT+F9

7C810657 k> 8BFF      mov edi,edi   //停在这里
7C81065955         push ebp
7C81065A8BEC      mov ebp,esp
7C81065CFF75 1C       push dword ptr ss:
7C81065FFF75 18       push dword ptr ss:
7C810662FF75 14       push dword ptr ss:
7C810665FF75 10       push dword ptr ss:
7C810668FF75 0C       push dword ptr ss:
7C81066BFF75 08       push dword ptr ss:
7C81066E6A FF      push -1
7C810670E8 D7FDFFFF   call kernel32.CreateRemoteThread
7C8106755D         pop ebp
7C810676C2 1800       retn 18

取消断点,ALT+F9返回
下面就单步跟吧!

00EAF2B1/EB 46      jmp short 00EAF2F9
00EAF2B3|8B55 08       mov edx,dword ptr ss:
00EAF2B6|833A 01       cmp dword ptr ds:,1
00EAF2B9|75 3E      jnz short 00EAF2F9
00EAF2BB|A1 04BBED00   mov eax,dword ptr ds:
00EAF2C0|8B0D 04BBED00    mov ecx,dword ptr ds:   ; Armadill.004CB378
00EAF2C6|8B50 68       mov edx,dword ptr ds:
00EAF2C9|3351 34       xor edx,dword ptr ds:
00EAF2CC|A1 04BBED00   mov eax,dword ptr ds:
00EAF2D1|3350 60       xor edx,dword ptr ds:
00EAF2D4|8955 DC       mov dword ptr ss:,edx
00EAF2D7|8B4D 08       mov ecx,dword ptr ss:
00EAF2DA|8B51 04       mov edx,dword ptr ds:
00EAF2DD|52         push edx
00EAF2DE|8B45 08       mov eax,dword ptr ss:
00EAF2E1|8B48 08       mov ecx,dword ptr ds:
00EAF2E4|51         push ecx
00EAF2E5|6A 00      push 0
00EAF2E7|8B55 08       mov edx,dword ptr ss:
00EAF2EA|8B42 0C       mov eax,dword ptr ds:
00EAF2ED|50         push eax
00EAF2EE|8B4D F4       mov ecx,dword ptr ss:
00EAF2F1|2B4D DC       sub ecx,dword ptr ss:
00EAF2F4|FFD1      call ecx       //这里就跳向OEP了!F7跟进即可!
00EAF2F6|8945 FC       mov dword ptr ss:,eax
00EAF2F9\8B45 FC       mov eax,dword ptr ss:


0045B52C55         push ebp   //这里就是OEP了!
0045B52D8BEC      mov ebp,esp
0045B52F83C4 F0       add esp,-10
0045B532B8 8CB24500   mov eax,Armadill.0045B28C
0045B537E8 C0ABFAFF   call Armadill.004060FC
0045B53CA1 C8D44500   mov eax,dword ptr ds:
0045B5418B00      mov eax,dword ptr ds:
0045B543E8 F893FFFF   call Armadill.00454940
0045B5488B0D B0D54500    mov ecx,dword ptr ds:   ; Armadill.0045EC88
0045B54EA1 C8D44500   mov eax,dword ptr ds:
0045B5538B00      mov eax,dword ptr ds:
0045B5558B15 B4AF4500    mov edx,dword ptr ds:   ; Armadill.0045B000
0045B55BE8 F893FFFF   call Armadill.00454958
0045B560A1 C8D44500   mov eax,dword ptr ds:
0045B5658B00      mov eax,dword ptr ds:
0045B567E8 6C94FFFF   call Armadill.004549D8
0045B56CE8 B38BFAFF   call Armadill.00404124
0045B5718D40 00       lea eax,dword ptr ds:

方法二:ALT+M,在00401000处F2,SHIFT+F9,然后单步走,
      同样可以找到下面地址:
         00EAF2F4|FFD1      call ecx       //这里就跳向OEP了!F7跟进即可!

4、用LordPE脱壳,然后用Import REC修复,剪掉无效的指针即可!
OK,脱壳文件能正常运行!
脱壳到此结束!

------------------------------------------------------------------------
【破解总结】早就听到穿山甲的大名,所以反复看教程,然后自己动手实践!
HOHO~~终于成功!说实话,真有点小兴奋!
不过这只是简单的保护方式,以后路还有很长要走!
菜鸟还要继续努力啊!不过,我会继续加油!
------------------------------------------------------------------------
【版权声明】转载请注明作者并保持文章的完整, 谢谢!

ydf001 发表于 2008-6-22 01:12

随便我看不懂.但是想学习.

山中斑虎 发表于 2008-6-22 04:13

我这么笨只能学简单的
有那位高手愿意免费教一下我吗

lchy 发表于 2008-6-22 09:19

这吗好的教程我咋就看不明白呢?菜鸟就是菜鸟

flyjmu 发表于 2008-6-22 11:09

太厉害了 跟着学习一遍

nxg6886368 发表于 2008-6-22 12:43

看不懂 蛮深奥的``但是 我会努力学的

cxz278444492 发表于 2008-6-24 04:19

天下无雪 发表于 2009-1-6 01:03

太感谢了,下来试试

a098 发表于 2010-3-3 07:25

跟着学习一遍

cz2181413 发表于 2010-3-3 07:38

这些东西太深奥咯!!看不懂。。
页: [1] 2 3
查看完整版本: 菜鸟我的第一篇脱文:手脱Armadillo5.0双进程标准壳