[软件]DLL Show 5.5
[资源来自]:911软件园http://www.down911.com/
[软件说明]:这是一个 32 位的工具,它能够显示你的硬盘上所有的 DLL 文件,你可以通过它了解应用程序的 ID 号、
优先使用权、版本号、与其它应用程序的链接等等,还包括一个搜索工具,你可以用它来定义动态的链接库、驱动器、ActiveX 控件
和其它用户控制属性。
[破解说明]:关于Armadillo脱壳的文章,DX们已经写了很多了,但是关于脱壳后手动修复IAT这部分一般讲的比较少,DX们一般都说直接CUT掉就
行了,但我碰到的CUT掉都不能运行,而这也逼得我研究了一下手动修复IAT的办法,有一点点不成熟的看法写出来给我这样的菜鸟一定的帮助了。
[破解过程]:
用PEID查看结果Armadillo 3.78 - 4.xx -> Silicon Realms Toolworks,然后使用Armadillo find protected 1.3 by vel查看结果为:
★ 目标为Armadillo保护
★ 特征识别 = DC6CDCDC
保护系统级别为 (标准版)
◆所用到的保护模式有◆
屏蔽调试器
【备份密钥设置】
不固定的备份密钥
【程序压缩设置】
较好/较慢地压缩方式
【其它保护设置】
运行程序利用进程查看器发现有两个进程,因此是双进程的。到此准备工作完成了。下面开始脱壳。
1 将自己作为子进程处理
使用Ollydbg_fix加载程序,忽略所有异常,在添加以下几个:
C0000005(ACCESS VIOLATION)
C000001D(ILLEGAL INSTRUCTION)
C000001E(INVALID LOCK SEQUENCE)
C0000096(PRIVILEGED INSTRUCTION)
停在如下代码:
00465000 D> 60 pushad
00465001 E8 00000000 call DLLShow.00465006
00465006 5D pop ebp
00465007 50 push eax
00465008 51 push ecx
00465009 0FCA bswap edx
0046500B F7D2 not edx
0046500D 9C pushfd
0046500E F7D2 not edx
00465010 0FCA bswap edx
00465012 EB 0F jmp short DLLShow.00465023
00465014 B9 EB0FB8EB mov ecx,EBB80FEB
BP OpenMutexA,F9运行,出现错误,Shift+F9,中断在下面代码处,
77E7AFA6 K> 55 push ebp
77E7AFA7 8BEC mov ebp,esp
77E7AFA9 51 push ecx
77E7AFAA 51 push ecx
77E7AFAB 837D 10 00 cmp dword ptr ss:[ebp+10],0
77E7AFAF 56 push esi
77E7AFB0 0F84 2DF40100 je KERNEL32.77E9A3E3
堆栈内容如下:
0012D778 0044B6BD /CALL 到 OpenMutexA 来自 DLLShow.0044B6B7
0012D77C 001F0001 |Access = 1F0001
0012D780 00000000 |Inheritable = FALSE
0012D784 0012DDB8 \MutexName = "3D8::DA5A3FFE89"
Ctrl+G填入00401000 然后输入下面的代码(mysqladm大虾的杰作,感谢):
00401000 60 PUSHAD
00401001 9C PUSHFD
00401002 68 B4FB1200 PUSH 12DDB8
00401007 33C0 XOR EAX,EAX
00401009 50 PUSH EAX
0040100A 50 PUSH EAX
0040100B E8 E694A677 CALL KERNEL32.CreateMutexA
00401010 9D POPFD
00401011 61 POPAD
00401012 - E9 8F9FA777 JMP KERNEL32.OpenMutexA
在00401000行新建起源,F9运行,再次中断在OpenMutexA函数的入口,取消断点。
2,避开IAT加密
下断点,HE GetModuleHandleA,F9运行,程序中断下来,注意观察堆栈,
F9运行直到堆栈出现下面内容:
00128CB0 00A80445 /CALL 到 GetModuleHandleA 来自 00A8043F
00128CB4 00A93D68 \pModule = "kernel32.dll"
00128CB8 00A94F30 ASCII "VirtualAlloc"
00128CB0 00A80462 /CALL 到 GetModuleHandleA 来自 00A8045C
00128CB4 00A93D68 \pModule = "kernel32.dll"
00128CB8 00A94F24 ASCII "VirtualFree"
此时小心了,F9 出现错误对话框,点击确定之后,Shift+F9,堆栈出现:
00128A28 00A699C1 /CALL 到 GetModuleHandleA 来自 00A699BB
00128A2C 00128B64 \pModule = "kernel32.dll"
取消硬件断点,ALT+F9返回:
00A699C1 8B0D 2091A900 mov ecx,dword ptr ds:[A99120]
00A699C7 89040E mov dword ptr ds:[esi+ecx],eax
00A699CA A1 2091A900 mov eax,dword ptr ds:[A99120]
00A699CF 393C06 cmp dword ptr ds:[esi+eax],edi
00A699D2 75 16 jnz short 00A699EA
00A699D4 8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C]
00A699DA 50 push eax
00A699DB FF15 D4E0A800 call dword ptr ds:[A8E0D4] ; KERNEL32.LoadLibraryA
00A699E1 8B0D 2091A900 mov ecx,dword ptr ds:[A99120]
00A699E7 89040E mov dword ptr ds:[esi+ecx],eax
00A699EA A1 2091A900 mov eax,dword ptr ds:[A99120]
00A699EF 393C06 cmp dword ptr ds:[esi+eax],edi
00A699F2 0F84 B3000000 je 00A69AAB ; Magic Jump
00A699F8 33C9 xor ecx,ecx
00A699FA 8B03 mov eax,dword ptr ds:[ebx]
00A699FC 3938 cmp dword ptr ds:[eax],edi
00A699FE 74 06 je short 00A69A06
00A69A00 41 inc ecx
00A69A01 83C0 0C add eax,0C
00A69A04 ^ EB F6 jmp short 00A699FC
00A69A06 8BC1 mov eax,ecx
00A69A08 C1E0 02 shl eax,2
00A69A0B 50 push eax
00A69A0C E8 3D3F0200 call 00A8D94E ; jmp to MSVCRT.operator new[]
在00A699F2处修改ZF标志位,就避开了IAT加密,然后F8运行到
00A69AAB 83C3 0C add ebx,0C
00A69AAE 83C6 04 add esi,4
00A69AB1 397B FC cmp dword ptr ds:[ebx-4],edi
00A69AB4 ^ 0F85 C3FEFFFF jnz 00A6997D
00A69ABA EB 03 jmp short 00A69ABF
00A69ABC D6 salc
00A69ABD D6 salc
在00A69ABA下断点,F9运行,中断在00A69ABA处,取消断点,此时IAT解密已经完成。
3 寻找OEP
用内存断点大法直抵OEP
Alt+M 查看内存,在401000开始的段上 下内存访问断点,F9运行,程序中断在OEP处:
00417AEF 55 push ebp
00417AF0 8BEC mov ebp,esp
00417AF2 6A FF push -1
00417AF4 68 30F44100 push DLLShow.0041F430
00417AF9 68 0C914100 push DLLShow.0041910C
00417AFE 64:A1 0000000>mov eax,dword ptr fs:[0]
00417B04 50 push eax
00417B05 64:8925 00000>mov dword ptr fs:[0],esp
00417B0C 83EC 58 sub esp,58
00417B0F 53 push ebx
00417B10 56 push esi
00417B11 57 push edi
00417B12 8965 E8 mov dword ptr ss:[ebp-18],esp
00417B15 FF15 A0F14100 call dword ptr ds:[41F1A0] ; KERNEL32.GetVersion
00417B1B 33D2 xor edx,edx
00417B1D 8AD4 mov dl,ah
00417B1F 8915 E0044300 mov dword ptr ds:[4304E0],edx
00417B25 8BC8 mov ecx,eax
00417B27 81E1 FF000000 and ecx,0FF
00417B2D 890D DC044300 mov dword ptr ds:[4304DC],ecx
00417B33 C1E1 08 shl ecx,8
00417B36 03CA add ecx,edx
00417B38 890D D8044300 mov dword ptr ds:[4304D8],ecx
00417B3E C1E8 10 shr eax,10
00417B41 A3 D4044300 mov dword ptr ds:[4304D4],eax
00417B46 33F6 xor esi,esi
00417B48 56 push esi
00417B49 E8 68140000 call DLLShow.00418FB6
00417B4E 59 pop ecx
00417B4F 85C0 test eax,eax
00417B51 75 08 jnz short DLLShow.00417B5B
00417B53 6A 1C push 1C
00417B55 E8 B0000000 call DLLShow.00417C0A
00417B5A 59 pop ecx
00417B5B 8975 FC mov dword ptr ss:[ebp-4],esi
00417B5E E8 33110000 call DLLShow.00418C96
00417B63 FF15 B4F14100 call dword ptr ds:[41F1B4] ; KERNEL32.GetCommandLineA
在00417AEF 处利用LordPE DUMP FULL完整的程序,然后利用ImportREC选中该程序,然后填入RVA=17AEF,点击“IAT自动搜索”,
然后点击“获得输入信息”,利用LEVEL 1 对于无效的指针进行追踪,然后将剩余指针CUT掉。然后修复,但是程序运行出错。
4 手动修复IAT(本文重点)
利用OD加载脱壳后的文件
一路F8和F7配合,发现程序在下面出错了,
0041323D FF15 0CF04100 call dword ptr ds:[<&advapi32.RegO>; advapi32.RegOpenKeyExA
00413243 8BF0 mov esi,eax
00413245 8B4424 04 mov eax,dword ptr ss:[esp+4]
00413249 85C0 test eax,eax
0041324B 74 07 je short DLLShow_.00413254
0041324D 50 push eax
0041324E FF15 18F04100 call dword ptr ds:[41F018] ;出错
00413254 33C0 xor eax,eax
00413256 85F6 test esi,esi
00413258 0F94C0 sete al
0041325B 5E pop esi
0041325C 59 pop ecx
0041325D C3 retn
这是利用ImportREC修复时,将RVA=1F018的指针剪切掉的原因,根据程序可以判断此处应该为advapi32.RegCloseKey。
重新打开ImportREC,修复时,将RVA=1F018改为advapi32.RegCloseKey修复完成后运行仍然有错,根据经验以及定位程序
00416D8F 68 84584200 push DLLShow_.00425884 ; ASCII "Software\Software by Design\%s\Version"
00416D94 51 push ecx
00416D95 C74424 1C 000000>mov dword ptr ss:[esp+1C],0
00416D9D FFD3 call ebx
00416D9F 83C4 0C add esp,0C
00416DA2 8D5424 14 lea edx,dword ptr ss:[esp+14]
00416DA6 8D4424 10 lea eax,dword ptr ss:[esp+10]
00416DAA 8B2D 04F04100 mov ebp,dword ptr ds:[41F004]
00416DB0 52 push edx
00416DB1 50 push eax
00416DB2 6A 00 push 0
00416DB4 6A 02 push 2
00416DB6 6A 00 push 0
00416DB8 68 D0A44200 push DLLShow_.0042A4D0
00416DBD 8D8C24 30010000 lea ecx,dword ptr ss:[esp+130]
00416DC4 6A 00 push 0
00416DC6 51 push ecx
00416DC7 68 02000080 push 80000002
00416DCC FFD5 call ebp ;出错
程序在00416DCC 出错,而EBP值00416DAA 8B2D 04F04100 mov ebp,dword ptr ds:[41F004],所以将RVA=1F004改为
advapi32.RegCreateKeyExA.
重新打开ImportREC,修复完成后,程序可以运行了。但是退出程序时出错了。
肯定还是修复有问题了。
经过分析退出时出错程序代码在如下位置:
0040C635 68 FF000000 push 0FF
0040C63A 52 push edx
0040C63B 56 push esi
0040C63C FF15 CCF24100 call dword ptr ds:[41F2CC] ;出错
0040C642 8D8424 08010000 lea eax,dword ptr ss:[esp+108]
0040C649 8D4C24 08 lea ecx,dword ptr ss:[esp+8]
0040C64D 50 push eax
0040C64E 51 push ecx
0040C64F 56 push esi
0040C650 E8 2B800000 call DLLShow_.00414680
0040C655 8B3D 60F24100 mov edi,dword ptr ds:[<&user32.Get>; USER32.GetDlgItemTextA
根据经验和自己分析,RVA=1F2CC应为USER32.GetWindowTextA.
重新打开ImportREC,修复完成后,程序可以运行了。但是退出程序时,点击YES按钮时,程序出错了,
0040C5CC FF15 78F24100 call dword ptr ds:[41F278] ;出错
0040C5D2 B8 01000000 mov eax,1
0040C5D7 5E pop esi
0040C5D8 C2 1000 retn 10
很明显RVA=1F278应为USER32.dll!EndDialog被我们剪切掉了。
重新打开ImportREC,将
RVA=1F004改为advapi32.RegCreateKeyExA.
RVA=1F018改为advapi32.RegCloseKey
RVA=1F2CC改为USER32.GetWindowTextA
RVA=1F278改为USER32.dll!EndDialog
其它指针都CUT掉。
修复后可以正常运行来。
但是利用PEID查看仍然显示:
Armadillo 1.xx - 2.xx -> Silicon Realms Toolworks。难道是脱壳不成功?NO,要对自己有信心了。打开LordPE,选中脱壳后的文件,点击
“Sections”,看到没有,第一个Section“text”的VOffset为1000,第二个Section“rdata”的VOffset为1F000,将BaseOfCode修改为1000,
然后将BaseOfData修改为1F000,再次用PEID打开仍然显示Armadillo 1.xx - 2.xx -> Silicon Realms Toolworks,但是用FI查看程序已经显示
MicroSoft Visual C++ v6.0了,搞定。
5 给程序减肥
再次打开LordPE,选中脱壳后的程序,点击“Sections”,在".adata"和"pdata"上右键,选择"wipe section header",然后,设置LordPE的
"Options",选中“Realign File...”、“Wipe Relocation”和“Valid PE”三项,然后Rebuild PE。程序从916KB变成了454KB,减肥成功。
收工了。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)