【脱文标题】 PEbundle V2.3脱壳 - 某算法注册机
【脱文作者】 weiyi75[Dfcg]
【作者邮箱】 weiyi75@sohu.com
【作者主页】 Dfcg官方大本营 --- www.chinadfcg.com
【使用工具】 Fi,Ollydbg,Loadpe,Imprec1.42
【脱壳平台】 Win2K
【软件名称】 keygen
【软件简介】 PEbundle v2.3 加壳的一个某算法注册机
【软件大小】 164KB
【下载地址】 本地下载
【加壳方式】 PEbundle v2.3
【保护方式】 压缩壳,IAT简单加密
【脱壳声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:
--------------------------------------------------------------------------------
【脱壳内容】
看过 PEbundle V2.3脱壳——唐诗三百首 V1.2 脱文,大家对PEbundle V2.3有些概念吧,特点是循环多。
既然有了前面的经验,就没必要慢慢跟踪了,首先找Oep。
OD设置忽略全部异常设置,载入程序,无须隐藏OD,因为PEbundle是个压缩壳。
00439000 > 9C pushfd //入口点
00439001 60 pushad
00439002 E8 02000000 call keygen.00439009
00439007 33C0 xor eax, eax
00439009 8BC4 mov eax, esp
0043900B 83C0 04 add eax, 4
0043900E 93 xchg eax, ebx
0043900F 8BE3 mov esp, ebx
00439011 8B5B FC mov ebx, dword ptr ds:[ebx-4]
00439014 81EB 07304000 sub ebx, keygen.00403007 ; ASCII "D$"
0043901A 87DD xchg ebp, ebx
0043901C 80BD DD3B4000 0>cmp byte ptr ss:[ebp+403BDD], 0
00439023 74 21 je short keygen.00439046
00439025 8D85 D6384000 lea eax, dword ptr ss:[ebp+4038D6]
0043902B 50 push eax
0043902C FF95 B2384000 call dword ptr ss:[ebp+4038B2]
00439032 8D8D 2C3A4000 lea ecx, dword ptr ss:[ebp+403A2C]
00439038 51 push ecx
00439039 50 push eax
0043903A FF95 A2384000 call dword ptr ss:[ebp+4038A2]
....................................................................................
找Oep试试我的二次软硬断点结合法,这个方法只能找Oep,IAT无法避免加密。
命令行 d 12ffc0
0012FFC0 F8 FF 12 00 F5 87 E6 77 A8 16 55 00 56 00 00 00 ?.鯂鎤?U.V... //已经有数据了,没关系,还是下个硬件写入dword断点
0012FFD0 00 F0 FD 7F 00 02 00 00 C8 FF 12 00 00 02 00 00 .瘕...?....
0012FFE0 FF FF FF FF B4 F0 E7 77 C8 8E E6 77 00 00 00 00 答鐆葞鎤....
0012FFF0 00 00 00 00 00 00 00 00 00 90 43 00 00 00 00 .........怌.....
F9运行
硬件断点1
00439376 C3 retn
00439377 C8 000000 enter 0, 0
0043937B 57 push edi
0043937C 56 push esi
0043937D 8B75 08 mov esi, dword ptr ss:[ebp+8]
00439380 8B7D 0C mov edi, dword ptr ss:[ebp+C]
00439383 8A06 mov al, byte ptr ds:[esi]
00439385 3C 61 cmp al, 61
00439387 72 06 jb short keygen.0043938F
00439389 3C 7A cmp al, 7A
0043938B 77 02 ja short keygen.0043938F
0043938D 04 E0 add al, 0E0
0043938F 8A27 mov ah, byte ptr ds:[edi]
00439391 80FC 61 cmp ah, 61
00439394 72 08 jb short keygen.0043939E
00439396 80FC 7A cmp ah, 7A
00439399 77 03 ja short keygen.0043939E
0043939B 80C4 E0 add ah, 0E0
0043939E 46 inc esi
0043939F 47 inc edi
004393A0 837D 10 01 cmp dword ptr ss:[ebp+10], 1
004393A4 75 01 jnz short keygen.004393A7
...........................................................................
然后Alt+M 打开内存镜像窗口。
内存镜像,项目 12
地址=00401000 //Code 段下内存访问断点,F9运行
大小=0000D000 (53248.)
Owner=keygen 00400000
区段=.text
包含=code
类型=Imag 01001002
访问=R
初始访问=RWE
内存断点
0040D1EF /. 55 push ebp //OEP 入口,LoadPe脱壳
0040D1F0 |. 8BEC mov ebp, esp
0040D1F2 |. 6A FF push -1
0040D1F4 |. 68 10FD4000 push keygen.0040FD10
0040D1F9 |. 68 4ED34000 push keygen.0040D34E ; jmp to MSVCRT._except_handler3; SE handler
installation
0040D1FE |. 64:A1 0000000>mov eax, dword ptr fs:[0]
0040D204 |. 50 push eax
0040D205 |. 64:8925 00000>mov dword ptr fs:[0], esp
0040D20C |. 83EC 68 sub esp, 68
0040D20F |. 53 push ebx
0040D210 |. 56 push esi
0040D211 |. 57 push edi
0040D212 |. 8965 E8 mov dword ptr ss:[ebp-18], esp
0040D215 |. 33DB xor ebx, ebx
0040D217 |. 895D FC mov dword ptr ss:[ebp-4], ebx
0040D21A |. 6A 02 push 2
0040D21C |. FF15 54E44000 call dword ptr ds:[40E454] ; MSVCRT.__set_app_type
0040D222 |. 59 pop ecx
0040D223 |. 830D 70234100>or dword ptr ds:[412370], FFFFFFFF
0040D22A |. 830D 74234100>or dword ptr ds:[412374], FFFFFFFF
0040D231 |. FF15 50E44000 call dword ptr ds:[40E450] ; MSVCRT.__p__fmode
0040D237 |. 8B0D 64234100 mov ecx, dword ptr ds:[412364]
0040D23D |. 8908 mov dword ptr ds:[eax], ecx
0040D23F |. FF15 4CE44000 call dword ptr ds:[40E44C] ; MSVCRT.__p__commode
.........................................................................................
脱壳后发现程序不能运行,这时需要用Imprec修复引入函数表(Import Table)
Imprec选择进程,在Oep处填71B80,点IT自动搜索,然后点获输入信息,看到输入表有无效的,点显示无效按钮,提示有1个未修复的指针,这是垃
圾指针吗?直接Cut程序是无法运行的,删除这个指针程序可以运行,感觉不爽。为这个问题特地请教Jwh51。
不同的DLL之间一定要有个空间进行区别,所以很多壳就在这个空间内插入垃圾了,而同一个DLL之内是没有空余空间的.所以也无法插入垃圾了。
一般情况下,垃圾总是位于两个DLL之间,而这个指针位于Kernel32.dll之间, 所以这个指针不是垃圾指针,为什么这个指针删除仍然可以运行?这是因为在程序里API是按顺序排列的,排上去不并不一定马上就要用到。当然
,可能程序里没用到这个指针,就不会出错了。
那我们找找它是Kernel32.dll的哪个Api函数。
图中我们看到,40e078处的指针无法识别,这个用功能强大的OD下断点,基本上都能从堆栈获寄存器里找到加密指针。
还是命令行 d 40e078,然后对40e078下硬件写入dword断点,当加密指针时Od立刻会通知我们。
F9运行中断两次,第二次到这里中断。
硬件中断
00439BD4 ^E9 67FFFFFF jmp keygen.00439B40
00439BD9 F8 clc
00439BDA C3 retn
00439BDB F9 stc
00439BDC C3 retn
00439BDD 0000 add byte ptr ds:[eax], al
00439BDF 0000 add byte ptr ds:[eax], al
00439BE1 0000 add byte ptr ds:[eax], al
00439BE3 0000 add byte ptr ds:[eax], al
00439BE5 0000 add byte ptr ds:[eax], al
00439BE7 0000 add byte ptr ds:[eax], al
00439BE9 0000 add byte ptr ds:[eax], al
00439BEB 0000 add byte ptr ds:[eax], al
00439BED 0000 add byte ptr ds:[eax], al
00439BEF 0000 add byte ptr ds:[eax], al
..........................................................................................
0012FF80 00036000
0012FF84 00439B87 keygen.00439B87
0012FF88 004394AA keygen.004394AA
0012FF8C 77E705CF KERNEL32.LoadLibraryA //堆栈滚动条往上一点看到 KERNEL32.LoadLibraryA
0012FF90 00400000 keygen.00400000
0012FF94 00410A30 keygen.00410A30
0012FF98 00439ABC 返回到 keygen.00439ABC 来自 keygen.00439AC9
0012FF9C 004392C1 返回到 keygen.004392C1 来自 keygen.00439AAD
0012FFA0 005516A8
ECX 00410A30 keygen.00410A30
EDX 00400000 keygen.00400000
EBX 004110B8 ASCII "LoadLibraryA" //寄存器EBX中存放的加密指针
ESP 0012FF98
EBP 00036000
ESI 00410914 keygen.00410914
EDI 0040E07C keygen.0040E07C
EIP 00439BD4 keygen.00439BD4
C 1 ES 0023 32bit 0(FFFFFFFF)
P 1 CS 001B 32bit 0(FFFFFFFF)
A 0 SS 0023 32bit 0(FFFFFFFF)
Z 0 DS 0023 32bit 0(FFFFFFFF)
S 1 FS 0038 32bit 7FFDE000(FFF)
T 0 GS 0000 NULL
D 0
O 0 LastErr ERROR_SUCCESS (00000000)
EFL 00000287 (NO,B,NE,BE,S,PE,L,LE)
ST0 empty 0.0
ST1 empty 0.0
ST2 empty 0.0
ST3 empty 0.0
ST4 empty 0.0
ST5 empty 0.0
ST6 empty 0.0
ST7 empty -UNORM E330 00000020 00000000
3 2 1 0 E S P U O Z D I
FST 0000 Cond 0 0 0 0 Err 0 0 0 0 0 0 0 0 (GT)
FCW 027F Prec NEAR,53 Mask 1 1 1 1 1 1
..............................................................................
于是在Rva 0000E078 处填入 KERNEL32.LoadLibraryA
指针全部修复,修复程序,正常运行。
【脱壳总结】PEbundle V2.3手动脱壳一般用二次软硬断点结合法找OEP,IAT一般没有加密,加密指针也很容易用硬件访问断点找到答案。
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整,感谢Jwh51兄的耐心指点!