yayazhi 发表于 2008-11-12 13:23:43

Armadillo v4.40加壳的Dll脱壳

【脱壳作者】 yayazhi
【作者邮箱】 [email protected]
【使用工具】 Ollyice,LordPE,ImportREC v1.7c,PEiD
【脱壳平台】 WinXP SP2
【脱壳目标】 Armadillo v4.40 加过壳的 Iplocal.dll 文件
【保护选项】 Standard protection only 仅仅标准保护 (单进程)
【加壳方式】 Armadillo v4.40
    这个壳迷糊了好长时间,看了unpackcn论坛上N多脱壳教程,今天终于搞定了,写个日记,一是为了勉励自己,作个纪念;二是给像我这样的菜鸟们留个教程。
--------------------------------------------------------------------------------
【脱壳内容】

一、准备工作
1 侦壳:用PEiD查壳 Armadillo 2.51 - 3.xx DLL Stub -> Silicon Realms Toolworks

OD 载入

下断点 HE OutputDebugStringA
Shift+F9 运行,中断下来。看堆栈:
0006E8A4   00AD5B30/CALL 到 OutputDebugStringA 来自 00AD5B2A
0006E8A8   0006F21C\String = "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
出现这个说明这个DLL是经过Armadillo 4.X压缩过
2 判断进程:DLL文件加壳应该是不可以双进程,所以这里是单进程方式

二 、脱壳

OD 重新载入

0090C897 >/$55            push    ebp<---------停在这里
0090C898|.8BEC          mov   ebp, esp
0090C89A|.53            push    ebx
0090C89B|.8B5D 08       mov   ebx, dword ptr
0090C89E|.56            push    esi
0090C89F|.8B75 0C       mov   esi, dword ptr
0090C8A2|.57            push    edi
0090C8A3|.8B7D 10       mov   edi, dword ptr
0090C8A6|.85F6          test    esi, esi
---------------------------------------------------------------

下断:BP GetModuleHandleA+5,Shift+F9运行,注意看堆栈:

---------------------------------------------------------------
00068EBC/0006915C
00068EC0|00AC5FC9返回到 00AC5FC9 来自 kernel32.GetModuleHandleA
00068EC4|00069010ASCII "kernel32.dll"
---------------------------------------------------------------

当堆栈变成上面的样子就可以返回了,清除断点后ALT+F9返回程序!

---------------------------------------------------------------
00AC5FC9    8B0D AC40AF00   mov   ecx, dword ptr <---------返回到这
00AC5FCF    89040E          mov   dword ptr , eax
00AC5FD2    A1 AC40AF00   mov   eax, dword ptr
00AC5FD7    391C06          cmp   dword ptr , ebx
00AC5FDA    75 16         jnz   short 00AC5FF2
00AC5FDC    8D85 B4FEFFFF   lea   eax, dword ptr
00AC5FE2    50            push    eax
00AC5FE3    FF15 BC62AE00   call    dword ptr     ;kernel32.LoadLibraryA
00AC5FE9    8B0D AC40AF00   mov   ecx, dword ptr
00AC5FEF    89040E          mov   dword ptr , eax
00AC5FF2    A1 AC40AF00   mov   eax, dword ptr
00AC5FF7    391C06          cmp   dword ptr , ebx
00AC5FFA    0F84 2F010000   je      00AC612F<--------------majic jump,改JMP
00AC6000    33C9            xor   ecx, ecx
00AC6002    8B07            mov   eax, dword ptr
00AC6004    3918            cmp   dword ptr , ebx
00AC6006    74 06         je      short 00AC600E
----------------------------------------------------------------
现在Alt+M打开内存查看窗口,看到这个DLL的给个区段
----------------------------------------------------------------
00870000   00001000   IPLocal                PE 头文件 //★下内存访问断点
00871000   00053000   IPLocal   CODE
008C4000   00003000   IPLocal   DATA      
008C7000   00003000   IPLocal   BSS      
----------------------------------------------------------------
现在F9运行程序,中断在下面地址
----------------------------------------------------------------
00AD9ED6    0348 3C         add   ecx, dword ptr 〈------中断在这
00AD9ED9    898D FCD7FFFF   mov   dword ptr , ecx
00AD9EDF    A1 FC00AF00   mov   eax, dword ptr
00AD9EE4    8985 B0AAFFFF   mov   dword ptr , eax
00AD9EEA    8B85 B0AAFFFF   mov   eax, dword ptr
00AD9EF0    8985 0CD8FFFF   mov   dword ptr , eax
00AD9EF6    8B85 FCD7FFFF   mov   eax, dword ptr
00AD9EFC    8B40 50         mov   eax, dword ptr
----------------------------------------------------------------
现在CTRL+S在整个区段搜索

mov edx,dword ptr ds:
add edx,dword ptr ds:
找到下面的地址
----------------------------------------------------------------
00ADFD81    8D74C1 D8       lea   esi, dword ptr
00ADFD85    33C0            xor   eax, eax
00ADFD87    3BCE            cmp   ecx, esi
00ADFD89    73 11         jnb   short 00ADFD9C
00ADFD8B    8B51 0C         mov   edx, dword ptr 〈--------找到这
00ADFD8E    0351 08         add   edx, dword ptr 〈-------在这下断
00ADFD91    3BD0            cmp   edx, eax
----------------------------------------------------------------
在上面地址下断以后,ALT+M取消内存断点,F9运行断下,继续F9,会在这多次
中断,看“寄存器”窗口的ECX 008702C0 ASCII ".reloc" 当出现这个的时候,
再看 下面,这个时候显示的就是重定位表RVA和大小
现在我们记下来,取消断点。
----------------------------------------------------------------
ds:=0000597C〈----大小

edx=0005D000〈-------重定位RVA   
----------------------------------------------------------------
现在ALT+M
----------------------------------------------------------------
00870000   00001000   IPLocal                PE 头文件
00871000   00053000   IPLocal   CODE//★这里下 内存访问 断点
008C4000   00003000   IPLocal   DATA      
008C7000   00003000   IPLocal   BSS      
---------------------------------------------------------------
继续F9就到了OEP
---------------------------------------------------------------
008C324C    55            push    ebp〈------OEP
008C324D    8BEC            mov   ebp, esp
008C324F    83C4 C4         add   esp, -3C
008C3252    B8 24308C00   mov   eax, 008C3024
008C3257    E8 5C34FBFF   call    008766B8
008C325C    E8 4314FBFF   call    008746A4
008C3261    8D40 00         lea   eax, dword ptr
008C3264    0000            add   byte ptr , al
008C3266    0000            add   byte ptr , al
008C3268    0000            add   byte ptr , al
008C326A    0000            add   byte ptr , al

用LordPE选中Ollydbg的loaddll.exe的进程,在下面的列表里选择这个dll,然后完整脱壳,得到dumped.dll。

----------------------------------------------------------------------------------------
三、输入表

因为已经修改了Magic Jump,所以现在可以得到完整的输入表。随便从程序找个API调用:

在cpu窗口cttl+B输入FF25

找到008711F4- FF25 88A18C00   jmp   dword ptr                ; kernel32.GetStdHandle
跟随到数据窗口,在数据窗口中用长型地址的方式显示数据将看到许多函数:
008CA1187C809915kernel32.GetACP
008CA11C7C802442kernel32.Sleep
008CA1207C809AE4kernel32.VirtualFree
008CA1247C809A51kernel32.VirtualAlloc
008CA1287C809728kernel32.GetCurrentThreadId
008CA12C7C80977Akernel32.InterlockedDecrement
008CA1307C809766kernel32.InterlockedIncrement
008CA1347C80B9D1kernel32.VirtualQuery
008CA1387C80A0D4kernel32.WideCharToMultiByte
008CA13C7C809BF8kernel32.MultiByteToWideChar
008CA1407C80BDB6kernel32.lstrlenA
008CA1447C810111kernel32.lstrcpynA
008CA1487C801D4Fkernel32.LoadLibraryExA
008CA14C7C80A415kernel32.GetThreadLocale
008CA1507C801EEEkernel32.GetStartupInfoA
008CA1547C80ADA0kernel32.GetProcAddress
008CA1587C80B6A1kernel32.GetModuleHandleA
008CA15C7C80B4CFkernel32.GetModuleFileNameA
008CA1607C80D262kernel32.GetLocaleInfoA
008CA1647C812F1Dkernel32.GetCommandLineA
008CA1687C80ABDEkernel32.FreeLibrary
008CA16C7C8137D9kernel32.FindFirstFileA
008CA1707C80EDD7kernel32.FindClose
008CA1747C81CDDAkernel32.ExitProcess
008CA1787C810D87kernel32.WriteFile
008CA17C7C862E2Akernel32.UnhandledExceptionFilter
008CA1807C957A40ntdll.RtlUnwind
008CA1847C812A09kernel32.RaiseException
008CA1887C812F39kernel32.GetStdHandle
上下滚动窗口就可以很容易的找到IAT的开始和结束的地址

开始地址=008CA118
结束地址=008CA6E8
   但是现在直接用ImportREC选取IPlocal.dll,填入RVA=0005A114、大小=5D0,
却提示“不能载入当前进程相关数据信息!”
如果填入RVA=004CA118、大小=5D0,可以得到输入表,却无法完成修复抓取文件。
为什么呢?我发帖问过,fly老大说修改PE后再修复,还没搞懂....
    于是利用 FLY 老大的移花接木:再打开一个 Ollydbg,载入 Win98 的 NotePad.EXE,
然后把 8CA118-008CA6E8 的数据复制、粘贴进NotePad.EXE 的 004CA118-004CA6E8,
然后用 ImportREC 选择 NotePad.EXE 进程,填入 RVA=CA118、大小=5D0,得到输入表,
CUT掉无效指针,改OEP=5324C,就可以修复了。

四、修复
   再用LOADPE修复一下文件,重定位表RVA和大小,就写上我们上面看到的。
此时用Dll_Load加载,提示can't load this dll!,再用LordPE把“镜像基址”
改成870000,加载成功!为何?

到此脱壳成功,可以再优化一下,我就不废话了,好多教程上都有的。

五、参考教程
1.刹那恍惚《用OD手脱Armadillo v4.40 DLL壳》
2.jameshero《用Ollydbg手脱Armadillo加壳的Dll》
对两位表示感谢。

[ 本帖最后由 yayazhi 于 2008-11-12 13:25 编辑 ]
页: [1]
查看完整版本: Armadillo v4.40加壳的Dll脱壳