【文章标题】: 脱PECompact 2.5 Retail加的DLL壳
【文章作者】: hbqjxhw
【软件名称】: qtintf.dll
【软件大小】: 1.13M
【下载地址】: http://free5.ys168.com/?hbqjxhw
【加壳方式】: PECompact 2.5 Retail -> Jeremy Collake
【保护方式】: 加壳
【编写语言】: Borland C++ DLL Method 2
【使用工具】: OllyDBG、WinHex、PEiD、LordPE、PEditor、ImportREC、PEComAngela、Dll_LoadEx
【操作平台】: WinXP SP2
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
根据好多人求助没有PECompact 2.0以上加的DLL的文章,写下此篇以解燃眉之急。
又深入地学习了FLY大侠写的《用Ollydbg手脱PECompact加壳的DLL 》之后,才有下面的文章。
根据FLY大侠说的“很多兄弟都不喜欢脱DLL的壳,我也是这样。DLL比EXE多了个重定位表需要修复,况且单独一个DLL连脱壳后的测试都难以彻底进行。”
下面就重点讲一讲这壳在什么地方处理重定位表吧,其它的都非常简单了。
少说废话了,下面就开始
第一步:DUMP
00E037A8 > B8 F0051901 MOV EAX,qtintf.011905F0 ; 进入OD后停在这(与2.0以下的版本不同了)
00E037AD 50 PUSH EAX
00E037AE 64:FF35 0000000>PUSH DWORD PTR FS:[0]
00E037B5 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
00E037BC 33C0 XOR EAX,EAX-----------------------》4下之后到这里。
00E037BE 8908 MOV DWORD PTR DS:[EAX],ECX
00E037C0 50 PUSH EAX
00E037C1 45 INC EBP
00E037C2 43 INC EBX
按F8,4下之后看堆栈如下:
0006F8A0 0006F9BC 指向下一个 SEH 记录的指针
0006F8A4 011905F0 SE 处理器
0006F8A8 7C9211A7 返回到 ntdll.7C9211A7
0006F8AC 00D90000 ASCII "MZP"
0006F8B0 00000001
0006F8B4 00000000
0006F8B8 00E037A8 qtintf.<模块入口点>
其实这两处的011905F0我们要找的值
00E037A8 > B8 F0051901 MOV EAX,qtintf.011905F0------》这一处的
0006F8A4 011905F0 SE 处理器-----》还有这里的
Ctrl+G输入011905F0,来到了如下
011905F0 B8 75F318F1 MOV EAX,F118F375 ; 来到了这里,在此处下F2断点。F9运行到此处,去掉F2断点。
011905F5 8D88 9E120010 LEA ECX,DWORD PTR DS:[EAX+100012>
011905FB 8941 01 MOV DWORD PTR DS:[ECX+1],EAX
011905FE 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4]
01190602 8B52 0C MOV EDX,DWORD PTR DS:[EDX+C]
01190605 C602 E9 MOV BYTE PTR DS:[EDX],0E9
01190608 83C2 05 ADD EDX,5
0119060B 2BCA SUB ECX,EDX
0119060D 894A FC MOV DWORD PTR DS:[EDX-4],ECX
01190610 33C0 XOR EAX,EAX
01190612 C3 RETN
向下找到
0119068B 894E 14 MOV DWORD PTR DS:[ESI+14],ECX
0119068E FFD7 CALL EDI
01190690 8985 3F130010 MOV DWORD PTR SS:[EBP+1000133F],>
01190696 8BF0 MOV ESI,EAX
01190698 8B4B 14 MOV ECX,DWORD PTR DS:[EBX+14]
0119069B 5A POP EDX
0119069C EB 0C JMP SHORT qtintf.011906AA
0119069E 03CA ADD ECX,EDX
011906A0 68 00800000 PUSH 8000
011906A5 6A 00 PUSH 0
011906A7 57 PUSH EDI
011906A8 FF11 CALL DWORD PTR DS:[ECX]
011906AA 8BC6 MOV EAX,ESI
011906AC 5A POP EDX
011906AD 5E POP ESI
011906AE 5F POP EDI
011906AF 59 POP ECX
011906B0 5B POP EBX
011906B1 5D POP EBP
011906B2 FFE0 JMP EAX-------》找到这里,在此下硬件执行断点,F9到达此处,F8一下就到了OEP。
------------------------------JMP EAX-----------------------------------------
00E037A8 > /EB 10 JMP SHORT qtintf.00E037BA-------》这里就是要找的OEP了。
00E037AA |66:623A BOUND DI,DWORD PTR DS:[EDX]
00E037AD |43 INC EBX
00E037AE |2B2B SUB EBP,DWORD PTR DS:[EBX]
00E037B0 |48 DEC EAX
00E037B1 |4F DEC EDI
00E037B2 |4F DEC EDI
00E037B3 |4B DEC EBX
00E037B4 |90 NOP
00E037B5 -|E9 80DD0301 JMP 01E4153A
00E037BA \A1 07DD0301 MOV EAX,DWORD PTR DS:[103DD07]
00E037BF C1E0 02 SHL EAX,2
00E037C2 A3 0BDD0301 MOV DWORD PTR DS:[103DD0B],EAX
00E037C7 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8]
00E037CB A3 79DD0301 MOV DWORD PTR DS:[103DD79],EAX
00E037D0 FF1485 69DD0301 CALL DWORD PTR DS:[EAX*4+103DD69>
00E037D7 833D 79DD0301 0>CMP DWORD PTR DS:[103DD79],1
00E037DE 75 5E JNZ SHORT qtintf.00E0383E
00E037E0 803D 13DD0301 0>CMP BYTE PTR DS:[103DD13],0
大家看到没有
00E037A8 > B8 F0051901 MOV EAX,qtintf.011905F0---》程序载入的入口
00E037A8 > /EB 10 JMP SHORT qtintf.00E037BA----》OEP的入口
这两个是相同的。
用LordPE选中Ollydbg的loaddll.exe的进程,在下面的列表里选择qtintf.dll,然后完整脱壳,得到dumped.dll。
第二步:Import Table
在OEP附进随便找个CALL进入,找到一个函数调用
00E037E9 E8 A4FA2000 CALL qtintf.01013292 ; JMP 到 kernel32.GetVersion
就这个吧,进入之后就看到了IAT
011480C8 77DA6BF0 ADVAPI32.RegCloseKey----》这是IAT_Start
011480CC 77DA761B ADVAPI32.RegOpenKeyExA
011480D0 77DA7883 ADVAPI32.RegQueryValueExA
011480D4 00000000
011480D8 77DA6BF0 ADVAPI32.RegCloseKey
011480DC 77DA761B ADVAPI32.RegOpenKeyExA
011480E0 77DA7883 ADVAPI32.RegQueryValueExA
。。。。。。
01148A94 769E2A2F OLE32.RevokeDragDrop
01148A98 00000000
01148A9C 769ADCF8 OLE32.CoGetMalloc
01148AA0 769E3D23 OLE32.CoLockObjectExternal
01148AA4 76A803F1 OLE32.DoDragDrop
01148AA8 769AF6DA OLE32.OleInitialize
01148AAC 769E3373 OLE32.OleUninitialize
01148AB0 769AF61A OLE32.RegisterDragDrop
01148AB4 769C4BED OLE32.ReleaseStgMedium
01148AB8 769E2A2F OLE32.RevokeDragDrop----》这是IAT_End
IAT_Start=011480C8
IAT_End =01148AB8
运行ImportREC,选中Ollydbg的loaddll.exe的进程,然后点“选取DLL”,选择qtintf.dll,填入RVA=003B80C8、大小=9F4、OEP=000737A8 ,点“Get Import”。用PEditor纠正dumped.dll的DumpFixer,修正区块。FixDump!
第三步:Relocation Talbe
重载入DLL程序
来到第一步的这里:
Ctrl+G输入011905F0,来到了如下
011905F0 B8 75F318F1 MOV EAX,F118F375 ; 来到了这里,在此处下F2断点。F9运行到此处,去掉F2断点。
011905F5 8D88 9E120010 LEA ECX,DWORD PTR DS:[EAX+100012>
011905FB 8941 01 MOV DWORD PTR DS:[ECX+1],EAX
011905FE 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4]
01190602 8B52 0C MOV EDX,DWORD PTR DS:[EDX+C]
01190605 C602 E9 MOV BYTE PTR DS:[EDX],0E9
01190608 83C2 05 ADD EDX,5
0119060B 2BCA SUB ECX,EDX
0119060D 894A FC MOV DWORD PTR DS:[EDX-4],ECX
01190610 33C0 XOR EAX,EAX
01190612 C3 RETN
可以向下找到这个:
0119068E FFD7 CALL EDI----------》在这里下F2断点,进入看一看。
01190690 8985 3F130010 MOV DWORD PTR SS:[EBP+1000133F],>
01190696 8BF0 MOV ESI,EAX
01190698 8B4B 14 MOV ECX,DWORD PTR DS:[EBX+14]
0119069B 5A POP EDX
0119069C EB 0C JMP SHORT qtintf.011906AA
0119069E 03CA ADD ECX,EDX
011906A0 68 00800000 PUSH 8000
011906A5 6A 00 PUSH 0
011906A7 57 PUSH EDI
011906A8 FF11 CALL DWORD PTR DS:[ECX]
011906AA 8BC6 MOV EAX,ESI
011906AC 5A POP EDX
011906AD 5E POP ESI
011906AE 5F POP EDI
011906AF 59 POP ECX
011906B0 5B POP EBX
011906B1 5D POP EBP
011906B2 FFE0 JMP EAX
-------------------------------CALL EDI---------------------------------------
00880AA0 53 PUSH EBX ; 进入到这里了。
00880AA1 57 PUSH EDI
00880AA2 56 PUSH ESI
00880AA3 55 PUSH EBP
00880AA4 E8 00000000 CALL 00880AA9
00880AA9 5D POP EBP
00880AAA 81ED 4C130010 SUB EBP,1000134C
00880AB0 8DB5 43130010 LEA ESI,DWORD PTR SS:[EBP+100013>
00880AB6 8B46 FC MOV EAX,DWORD PTR DS:[ESI-4]
。。。。。。省略了
00880B44 /0F85 94000000 JNZ 00880BDE
00880B4A |56 PUSH ESI
00880B4B |E8 40030000 CALL 00880E90
00880B50 |56 PUSH ESI
00880B51 |E8 55020000 CALL 00880DAB
00880B56 |56 PUSH ESI
00880B57 |E8 53010000 CALL 00880CAF--------》这个CALL就是我们要找的了
00880B5C |90 NOP
-------------------------------CALL 00880CAF----------------------------------
00880CAF 55 PUSH EBP-----》 进入到这里了。
00880CB0 8BEC MOV EBP,ESP
00880CB2 83C4 F8 ADD ESP,-8
00880CB5 53 PUSH EBX
00880CB6 57 PUSH EDI
00880CB7 56 PUSH ESI
00880CB8 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]
00880CBB 8B47 04 MOV EAX,DWORD PTR DS:[EDI+4]----》EAX=DS:[00880954]=00D90000 (qtintf.00D90000)
00880CBE 8B5F 08 MOV EBX,DWORD PTR DS:[EDI+8]----》EBX=DS:[00880958]=00D90000 (qtintf.00D90000)
00880CC1 3BC3 CMP EAX,EBX---------------------》比较映像基址是否相等,相等则不处理。
00880CC3 74 59 JE SHORT 00880D1E---------------》还是使用FLY大侠的(改标志位Z=0,使这里不跳转)
00880CC5 8B77 38 MOV ESI,DWORD PTR DS:[EDI+38]---》ESI=DS:[00880988]=003D7000,重定位的RVA
00880CC8 85F6 TEST ESI,ESI
00880CCA 74 52 JE SHORT 00880D1E
00880CCC 03F3 ADD ESI,EBX---------------------》ESI=00D90000+003D7000=1167000
00880CCE 8BD3 MOV EDX,EBX
00880CD0 2BD8 SUB EBX,EAX
00880CD2 895D F8 MOV DWORD PTR SS:[EBP-8],EBX
00880CD5 AD LODS DWORD PTR DS:[ESI]
00880CD6 8BD8 MOV EBX,EAX
00880CD8 03DA ADD EBX,EDX
00880CDA AD LODS DWORD PTR DS:[ESI]
00880CDB 85C0 TEST EAX,EAX
00880CDD 74 3F JE SHORT 00880D1E
00880CDF 8BC8 MOV ECX,EAX
00880CE1 83E9 08 SUB ECX,8
00880CE4 85C9 TEST ECX,ECX
00880CE6 ^ 74 ED JE SHORT 00880CD5
00880CE8 66:C745 FE FFFF MOV WORD PTR SS:[EBP-2],0FFFF
00880CEE 66:AD LODS WORD PTR DS:[ESI]
00880CF0 66:837D FE FF CMP WORD PTR SS:[EBP-2],0FFFF
00880CF5 74 04 JE SHORT 00880CFB
00880CF7 66:0345 FE ADD AX,WORD PTR SS:[EBP-2]
00880CFB 66:8945 FE MOV WORD PTR SS:[EBP-2],AX
00880CFF 8BF8 MOV EDI,EAX
00880D01 81E7 FF0F0000 AND EDI,0FFF
00880D07 03FB ADD EDI,EBX
00880D09 66:C1E8 0C SHR AX,0C
00880D0D 66:83F8 03 CMP AX,3
00880D11 75 05 JNZ SHORT 00880D18
00880D13 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
00880D16 0107 ADD DWORD PTR DS:[EDI],EAX
00880D18 49 DEC ECX
00880D19 49 DEC ECX
00880D1A ^ 75 D2 JNZ SHORT 00880CEE
00880D1C ^ EB B7 JMP SHORT 00880CD5
00880D1E 5E POP ESI-------------------------------》在此下F4运行到此处,这时ESI的值为ESI=0118E4E0
00880D1F 5F POP EDI
00880D20 5B POP EBX
00880D21 C9 LEAVE
00880D22 C2 0400 RETN 4
重定位表的大小是:0118E4E0-8-1167000=274D8(其实我们知道了003D7000之后,用用WinHex打开dumped_.dll,到达此处之后,向下翻到为0处就是重定位表的大小了)
用WinHex打开dumped_.dll,复制003D7000-003FE4D8之间的16进制数值,另存为1.bin
运行 看雪 老师写的辅助修复PECompact加壳DLL重定位表的工具PEComAngela.exe,打开1.bin,创建pediy.bin文件失败了!
http://bbs.pediy.com/showthread.php?s=&threadid=40785这里有讨论。
后来使用了Relox V1.0a也不能修复。
这里我也感觉很郁闷,为什么不能创建成功呢?好了我就进入程序内看一看吧。经过仔细考虑之后,进入此CALL 00880CAF修改了如下代码:
-------------------------------CALL 00880CAF----------------------------------
00880CAF 55 PUSH EBP
00880CB0 8BEC MOV EBP,ESP
00880CB2 83C4 F8 ADD ESP,-8
00880CB5 53 PUSH EBX
00880CB6 57 PUSH EDI
00880CB7 56 PUSH ESI
00880CB8 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]
00880CBB 8B47 04 MOV EAX,DWORD PTR DS:[EDI+4]
00880CBE 8B5F 08 MOV EBX,DWORD PTR DS:[EDI+8]
00880CC1 3BC3 CMP EAX,EBX
00880CC3 74 59 JE SHORT 00880D1E-----------------------》注册意要改标志位Z=0,使这里不跳转哟
00880CC5 8B77 38 MOV ESI,DWORD PTR DS:[EDI+38]
00880CC8 85F6 TEST ESI,ESI
00880CCA 74 52 JE SHORT 00880D1E
00880CCC 03F3 ADD ESI,EBX
00880CCE 8BD3 MOV EDX,EBX
00880CD0 2BD8 SUB EBX,EAX
00880CD2 895D F8 MOV DWORD PTR SS:[EBP-8],EBX
00880CD5 AD LODS DWORD PTR DS:[ESI]
00880CD6 8BD8 MOV EBX,EAX
00880CD8 03DA ADD EBX,EDX
00880CDA AD LODS DWORD PTR DS:[ESI]
00880CDB 85C0 TEST EAX,EAX
00880CDD 74 3F JE SHORT 00880D1E
00880CDF 8BC8 MOV ECX,EAX
00880CE1 83E9 08 SUB ECX,8
00880CE4 85C9 TEST ECX,ECX
00880CE6 ^ 74 ED JE SHORT 00880CD5
00880CE8 66:C745 FE FFFF MOV WORD PTR SS:[EBP-2],0FFFF
00880CEE 66:AD LODS WORD PTR DS:[ESI]
00880CF0 66:837D FE FF CMP WORD PTR SS:[EBP-2],0FFFF
00880CF5 74 54 JE SHORT 00880D4B
00880CF7 66:0345 FE ADD AX,WORD PTR SS:[EBP-2]
00880CFB EB 4E JMP SHORT 00880D4B
00880CFD 90 NOP--------------------------------
00880CFE 90 NOP |
00880CFF 8BF8 MOV EDI,EAX
00880D01 81E7 FF0F0000 AND EDI,0FFF |
00880D07 03FB ADD EDI,EBX
00880D09 66:C1E8 0C SHR AX,0C |
00880D0D 66:83F8 03 CMP AX,3 ---> 这里的代码相当与废了。
00880D11 75 05 JNZ SHORT 00880D18 |
00880D13 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
00880D16 0107 ADD DWORD PTR DS:[EDI],EAX |
00880D18 49 DEC ECX
00880D19 49 DEC ECX
00880D1A ^ 75 D2 JNZ SHORT 00880CEE |
00880D1C ^ EB B7 JMP SHORT 00880CD5-----------------
00880D1E 5E POP ESI
00880D1F 5F POP EDI
00880D20 5B POP EBX
00880D21 C9 LEAVE
00880D22 C2 0400 RETN 4------------------》此处返回。
00880D25 55 PUSH EBP
00880D26 8BEC MOV EBP,ESP
00880D28 53 PUSH EBX
00880D29 57 PUSH EDI
00880D2A 56 PUSH ESI
00880D2B 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8]
00880D2E 66:8B4D 10 MOV CX,WORD PTR SS:[EBP+10]
00880D32 8B55 0C MOV EDX,DWORD PTR SS:[EBP+C]
00880D35 AD LODS DWORD PTR DS:[ESI]
00880D36 85C0 TEST EAX,EAX
00880D38 74 07 JE SHORT 00880D41
00880D3A 03C2 ADD EAX,EDX
00880D3C 66:8908 MOV WORD PTR DS:[EAX],CX
00880D3F ^ EB F4 JMP SHORT 00880D35
00880D41 5E POP ESI
00880D42 5F POP EDI
00880D43 5B POP EBX
00880D44 C9 LEAVE
00880D45 C2 0C00 RETN 0C
00880D48 90 NOP
00880D49 90 NOP
00880D4A 90 NOP
00880D4B 66:8945 FE MOV WORD PTR SS:[EBP-2],AX
00880D4F 66:36:8946 FE MOV WORD PTR SS:[ESI-2],AX--------》还原重定位表数据就是这里了。
00880D54 8BF8 MOV EDI,EAX
00880D56 90 NOP
00880D57 90 NOP
00880D58 90 NOP
00880D59 81E7 FF0F0000 AND EDI,0FFF
00880D5F 03FB ADD EDI,EBX
00880D61 66:C1E8 0C SHR AX,0C
00880D65 66:83F8 03 CMP AX,3
00880D69 75 05 JNZ SHORT 00880D70
00880D6B 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
00880D6E 0107 ADD DWORD PTR DS:[EDI],EAX
00880D70 49 DEC ECX
00880D71 49 DEC ECX
00880D72 ^ 0F85 76FFFFFF JNZ 00880CEE
00880D78 ^ E9 58FFFFFF JMP 00880CD5
下面是二进数据,可以直接复制用:
55 8B EC 83 C4 F8 53 57 56 8B 7D 08 8B 47 04 8B 5F 08 3B C3 74 59 8B 77 38 85 F6 74 52 03 F3 8B
D3 2B D8 89 5D F8 AD 8B D8 03 DA AD 85 C0 74 3F 8B C8 83 E9 08 85 C9 74 ED 66 C7 45 FE FF FF 66
AD 66 83 7D FE FF 74 54 66 03 45 FE EB 4E 90 90 8B F8 81 E7 FF 0F 00 00 03 FB 66 C1 E8 0C 66 83
F8 03 75 05 8B 45 F8 01 07 49 49 75 D2 EB B7 5E 5F 5B C9 C2 04 00 55 8B EC 53 57 56 8B 75 08 66
8B 4D 10 8B 55 0C AD 85 C0 74 07 03 C2 66 89 08 EB F4 5E 5F 5B C9 C2 0C 00 90 90 90 66 89 45 FE
66 36 89 46 FE 8B F8 90 90 90 81 E7 FF 0F 00 00 03 FB 66 C1 E8 0C 66 83 F8 03 75 05 8B 45 F8 01
07 49 49 0F 85 76 FF FF FF E9 58 FF FF FF
这里返回之后。
并运行到第一步提到的OEP处之后,请重新用LordPE选中Ollydbg的loaddll.exe的进程,在下面的列表里选择qtintf.dll,然后完整脱壳,得到unqtintf.dll。
再执行第二步:运行ImportREC,选中Ollydbg的loaddll.exe的进程,然后点“选取DLL”,选择qtintf.dll,填入RVA=003B80C8、大小=9F4、OEP=000737A8 ,点“Get Import”。用PEditor纠正unqtintf.dll的DumpFixer,修正区块。FixDump!
最后用LordPE修正unqtintf_.dll的重定位表RVA=003D7000、大小=000274D8,保存之。自己优化一下吧!
用Dll_LoadEx.exe工具测试可以载入。
--------------------------------------------------------------------------------
【经验总结】
没什么经验只能说玩一玩还可以吧!
2007年03月09日 21:00:00
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!