【目标程序】:加tElock变形壳的eiserver.dll。附件中含有dumped供参考。
【作者声明】:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【调试环境】:Win2000、Ollydbg1.10、LordPE、UltraEdit
―――――――――――――――――――――――――――――――――
【脱壳过程】:
在论坛上看有人发了个加壳的DLL,最近心情不太好,就拿来玩玩!
本文参考Fly大侠《用Ollydbg手脱tElock V0.98加壳的DLL》写成!
希望Fly兄不要见怪!^_^ ^_^ ^_^
―――――――――――――――――――――――――――――――――
一、双重Magic Jump:避开重定位和输入表加密
设置Ollydbg忽略除了“INT3中断”之外的所有其它异常选项。
老规矩:用IsDebug 1.4插件去掉Ollydbg的调试器标志。
007B1222 >^\E9 D9DDFFFF jmp eiserver.007AF000 //进入OD后停在这
007B1227 0000 add byte ptr ds:[eax],al
Shift+F9 运行,程序中断在INT3异常处
007AFD5A 90 nop //第3次中断在这里
007AFD5B 66:81C6 B7B9 add si,0B9B7
来到下面代码处下断
007B01B6 74 0F je short eiserver.007B01C7 //在这一行下断
007B01B8 FF95 181F4000 call dword ptr ss:[ebp+401F18]
007B01BE 6A 00 push 0
Shift+F9 断在这个跳转指令后 更改标志位 使之跳转 否则GAME OVER
清除这个断点,设置Ollydbg忽略所有异常选项。Ctrl+S在“整个段块”搜索命令序列:
mov ebx,edx
shr ebx,10
mov eax,dword ptr ds:[esi]
007B06BE 8BB5 00334000 mov esi,dword ptr ss:[ebp+403300]
//[ebp+403300]=[007B1300]=0001B000 ★ 这个0001B000就是重定位表的RVA!
007B06C4 85F6 test esi,esi
007B06C6 0F84 8B000000 je eiserver.007B0757
007B06CC 8B95 0C334000 mov edx,dword ptr ss:[ebp+40330C]
007B06D2 03F2 add esi,edx
007B06D4 2B95 10334000 sub edx,dword ptr ss:[ebp+403310]
//这里其实就是检测与映像基址是否相符,不符则重定位处理!★
007B06DA 74 7B je short eiserver.007B0757
//Magic Jump,可以第2次Load后在这里改标志位Z=1,使其跳转 ★
007B06DC 8BDA mov ebx,edx
007B06DE C1EB 10 shr ebx,10
007B06E1 8B06 mov eax,dword ptr ds:[esi]
007B06E3 85C0 test eax,eax
007B06E5 74 70 je short eiserver.007B0757
//重定位处理完毕后这里就跳转 在007B0757处下断
007B06E7 8B4E 04 mov ecx,dword ptr ds:[esi+4]
007B06EA 83E9 08 sub ecx,8
007B06ED D1E9 shr ecx,1
007B06EF 8BBD 0C334000 mov edi,dword ptr ss:[ebp+40330C]
007B06F5 03F8 add edi,eax
007B06F7 83C6 08 add esi,8
007B06FA 0FB706 movzx eax,word ptr ds:[esi]
007B06FD C1C8 0C ror eax,0C
007B0700 FEC8 dec al
007B0702 78 4C js short eiserver.007B0750
007B0704 74 0E je short eiserver.007B0714
007B0706 FEC8 dec al
007B0708 74 13 je short eiserver.007B071D
007B070A FEC8 dec al
007B070C 74 3C je short eiserver.007B074A
007B070E FEC8 dec al
007B0710 74 14 je short eiserver.007B0726
007B0712 EB 3C jmp short eiserver.007B0750
007B0714 C1E8 14 shr eax,14
007B0717 66:011C07 add word ptr ds:[edi+eax],bx
007B071B EB 33 jmp short eiserver.007B0750
007B071D C1E8 14 shr eax,14
007B0720 66:011407 add word ptr ds:[edi+eax],dx
007B0724 EB 2A jmp short eiserver.007B0750
007B0726 52 push edx
007B0727 C1E8 14 shr eax,14
007B072A 8BD8 mov ebx,eax
007B072C C1E0 10 shl eax,10
007B072F 66:8B16 mov dx,word ptr ds:[esi]
007B0732 66:81E2 FF0F and dx,0FFF
007B0737 66:8BC2 mov ax,dx
007B073A 5A pop edx
007B073B 8D8410 00800000 lea eax,dword ptr ds:[eax+edx+8000]
007B0742 89041F mov dword ptr ds:[edi+ebx],eax
007B0745 46 inc esi
007B0746 46 inc esi
007B0747 49 dec ecx
007B0748 EB 06 jmp short eiserver.007B0750
007B074A C1E8 14 shr eax,14
007B074D 011407 add dword ptr ds:[edi+eax],edx
007B0750 46 inc esi
007B0751 46 inc esi
007B0752 49 dec ecx
007B0753 ^ 7F A5 jg short eiserver.007B06FA
007B0755 ^ EB 8A jmp short eiserver.007B06E1
007B0757 8B95 0C334000 mov edx,dword ptr ss:[ebp+40330C]
//当我们中断在007B0757处时,重定位处理完毕。此时ESI=007ACC94,★ 就是重定位表的结束地址啦。
//得到重定位表信息:RVA=0001B000,大小=007ACC94-007AB0000=1C94
007B075D 8BB5 FC324000 mov esi,dword ptr ss:[ebp+4032FC]
//[ebp+4032FC]=[007B12FC]=00019000 ★ 这就是输入表的RVA啦。
007B0763 0BF6 or esi,esi
007B0765 0F84 30040000 je eiserver.007B0B9B
//第2个Magic Jump,改标志位Z=1,使其跳转,则不加密IAT
007B076B 03F2 add esi,edx
007B076D 83A5 FC334000 00 and dword ptr ss:[ebp+4033FC],0
007B0774 33C0 xor eax,eax
007B0776 8746 0C xchg dword ptr ds:[esi+C],eax
007B0779 0BC0 or eax,eax
007B077B 0F84 1A040000 je eiserver.007B0B9B
007B0781 35 78563412 xor eax,12345678
007B0786 E8 CD000000 call eiserver.007B0858
007B078B 03C2 add eax,edx
007B078D 8BD8 mov ebx,eax
007B078F 50 push eax
007B0790 FF95 7A324000 call dword ptr ss:[ebp+40327A]
007B0796 85C0 test eax,eax
007B0798 0F85 D7000000 jnz eiserver.007B0875
007B079E 53 push ebx
007B079F FF95 7F154000 call dword ptr ss:[ebp+40157F]
007B07A5 85C0 test eax,eax
007B07A7 0F85 C8000000 jnz eiserver.007B0875
007B07AD 8B95 0C334000 mov edx,dword ptr ss:[ebp+40330C]
咱们已经得到重定位表信息了,所以可以再次载入这个DLL,重复上面的步骤,避开重定位表加密!
―――――――――――――――――――――――――――――――――
二、第2区段内存断点法:快速直达OEP
当我们修改了以上两个Magic Jump,来到如下代码处时
007B0B9B 8BBD 04334000 mov edi,dword ptr ss:[ebp+403304]
007B0BA1 85FF test edi,edi
007B0BA3 EB 03 jmp short eiserver.007B0BA8
现在我们Alt+M打开 内存查看 窗口:
00790000 00001000 eiserver 00790000 (itself) PE header Imag 01001002 R RWE
00791000 00016000 eiserver 00790000 code Imag 01001002 R RWE
007A7000 00001000 eiserver 00790000 data Imag 01001002 R RWE
007A8000 00001000 eiserver 00790000 Imag 01001002 R RWE
在00791000第2区段上 F2设置断点!Shift+F9 运行,直接中断在OEP处!
007A69F0 55 push ebp
007A69F1 8BEC mov ebp,esp
007A69F3 83C4 C4 add esp,-3C
007A69F6 B8 20697A00 mov eax,eiserver.007A6920
007A69FB E8 04F3FEFF call eiserver.00795D04
用LordPE选中Ollydbg的loaddll.exe的进程,在下面的列表里选择eiserver.dll,然后完整脱壳,得到dumped.dll。
―――――――――――――――――――――――――――――――――
三、PE修正
//修正参数如下
入口点 OEP = 169F0
输入表 RVA = 19000
重定位 RVA = 1B000 大小 = 1C94
//用LordPE打开修正后的dumped.dll会发现输入表错误!
//不知道是否有现成的修复工具,只好分析一下,手工修复了!
―――――――――――――――――――――――――――――――――
四、修复输入表
这个被修改的壳对输入表进行了特殊处理,将原始的输入表进行了加密,并将函数指向了分配的一段内存中!
具体代码就不贴了(跳来跳去的太乱!)
1、对IID的处理
OrignalFistThunk TimeDataStamp ForwardChain Name FirstThunk
00000000 00000000 00000000 7856A734 89675605
Name = 0x34a75678 XOR 0x12345678 = 0x26930000 => 处理函数 = 0x000192C8 (RVA)
FirstThunk = 0x05566789 XOR 0x23456789 = 0x26130000 => 处理函数 = 0x000190C8 (RVA)
00000000 00000000 00000000 C8920100 C8900100
2、对IID指向的API函数指针的处理
如对第一个函数指针的处理
9A 78 C5 E2
0xE2C5789A XOR 0x3456789A = 0xD6930000 => 处理函数 => 0x000192D6 (RVA)
这个RVA是指向名称的,再减去2(函数名引用的两个字节) =0x000192D4 (RVA)
3、对DLL名称的处理
9个DLL名称未作处理!
4、对API函数名称的处理
EgoaqcDz`~bolb\urfz{{ =〉 DeleteCriticalSection
运算方法是:从字符串的第一个字符开始分别跟1,2,3,4...进行异或!
///////////////////////////////////////////
// 处理函数
///////////////////////////////////////////
007B0858 52 push edx
007B0859 51 push ecx
007B085A 53 push ebx
007B085B 33D2 xor edx,edx
007B085D B9 20000000 mov ecx,20
007B0862 33DB xor ebx,ebx
007B0864 D1F8 sar eax,1
007B0866 0F92C3 setb bl
007B0869 D3E3 shl ebx,cl
007B086B 03D3 add edx,ebx
007B086D ^ E2 F3 loopd short eiserver.007B0862
007B086F 8BC2 mov eax,edx
007B0871 5B pop ebx
007B0872 59 pop ecx
007B0873 5A pop edx
007B0874 C3 retn
获取整个输入表的处理方法后,就可以修复输入表了!可以直接跟踪时修改壳的代码,以壳解壳进行修复!
我懒得改,写了段小程序对 007A9000 到 007A9B50之间的数据进行处理,获得了修复后的输入表数据
UltraEdit 用修复后的输入表数据替换原来的错误输入表数据!
用OD载入, DLL初始化正常,DllLoader运行正常。脱壳完成!
―――――――――――――――――――――――――――――――――
五、后记:
也不知道这个DLL是个什么东东,但瞎忙活了一通,心情好多了 ^_^
清风幻影
2004-10-28
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课