【文章标题】: NsPacK V3.7加的DLL壳分析
【软件名称】: pcomm.dll
【软件大小】: 87KB
【下载地址】: 附件
【加壳方式】: NsPacK V3.7 -> LiuXingPing *
【保护方式】: 加壳
【编写语言】: Microsoft Visual C++ 6.0 DLL
【使用工具】: OllyDBG、WinHex、PEiD、LordPE、PEditor、ImportREC、UPXAngela、Dll_LoadEx
【操作平台】: WinXP SP2
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
继第一篇《脱PECompact 2.5 Retail加的DLL壳》之后,再接再励出第二篇。
对于这篇http://bbs.pediy.com/showthread.php?threadid=16603讲的自己构造基址重定位表,像我这样的菜鸟又如何构造呢?
还是哪句话“DLL处理好了基址重定,就算成功了”。
下面就进入正题:
一:基址重定位的确认
6005524B > 9C PUSHFD ; 进入OD后停在这
6005524C 60 PUSHAD
6005524D E8 00000000 CALL pcomm.60055252
60055252 5D POP EBP
60055253 83ED 07 SUB EBP,7
60055256 8D8D 31FEFFFF LEA ECX,DWORD PTR SS:[EBP-1CF]
6005525C 8039 01 CMP BYTE PTR DS:[ECX],1
6005525F 0F84 42020000 JE pcomm.600554A7 ; 这里是一个远距离跳转也就是跳到OEP处附近
60055265 C601 01 MOV BYTE PTR DS:[ECX],1
60055268 8BC5 MOV EAX,EBP
向下找,可以找到这样的
600552FE 8BD6 MOV EDX,ESI
60055300 8BCF MOV ECX,EDI
60055302 8B85 EDFDFFFF MOV EAX,DWORD PTR SS:[EBP-213]
60055308 05 AA050000 ADD EAX,5AA
6005530D FFD0 CALL EAX ; 这个CALL主要是解压代码,有兴趣的可以跟入
6005530F 5B POP EBX
60055310 59 POP ECX
60055311 5F POP EDI
继续向下找,找到6005539C处下F2断点。(注:解压代码与输入表处理简要的提示,不作详细讲解,重点是重定位表)
60055383 E8 3A010000 CALL pcomm.600554C2 ; 这个CALL主要是处理输入表
60055388 8D8D 09FEFFFF LEA ECX,DWORD PTR SS:[EBP-1F7]
6005538E 8B41 08 MOV EAX,DWORD PTR DS:[ECX+8]
60055391 83F8 00 CMP EAX,0
60055394 0F84 81000000 JE pcomm.6005541B
6005539A 8BF2 MOV ESI,EDX
6005539C 2B71 10 SUB ESI,DWORD PTR DS:[ECX+10] ; (也就这里下F2断点)ESI=60000000,DS:[60055064]=60000000(注:基址有可能与你的不同)
6005539F 74 7A JE SHORT pcomm.6005541B ; 这里是比较映像基址是否相等,相等则不处理。改标志位Z=0,使这里不跳转
600553A1 8971 10 MOV DWORD PTR DS:[ECX+10],ESI
600553A4 8DB5 39FEFFFF LEA ESI,DWORD PTR SS:[EBP-1C7]
600553AA 8B36 MOV ESI,DWORD PTR DS:[ESI]
600553AC 8D5E FC LEA EBX,DWORD PTR DS:[ESI-4]
600553AF 8B01 MOV EAX,DWORD PTR DS:[ECX]
600553B1 83F8 01 CMP EAX,1
600553B4 74 0A JE SHORT pcomm.600553C0
600553B6 8BFA MOV EDI,EDX
600553B8 0379 08 ADD EDI,DWORD PTR DS:[ECX+8]
600553BB 8B49 10 MOV ECX,DWORD PTR DS:[ECX+10]
600553BE EB 08 JMP SHORT pcomm.600553C8
600553C0 8BFE MOV EDI,ESI
600553C2 0379 08 ADD EDI,DWORD PTR DS:[ECX+8]
600553C5 8B49 10 MOV ECX,DWORD PTR DS:[ECX+10]
600553C8 33C0 XOR EAX,EAX
600553CA 8A07 MOV AL,BYTE PTR DS:[EDI] ; EDI=60051000-当前基址60000000=00051000 , 这就是重定位表的RVA了
600553CC 47 INC EDI
600553CD 0BC0 OR EAX,EAX
600553CF 74 20 JE SHORT pcomm.600553F1 ; 重定位数据处理完,则跳转
600553D1 3C EF CMP AL,0EF
600553D3 77 06 JA SHORT pcomm.600553DB
600553D5 03D8 ADD EBX,EAX
600553D7 010B ADD DWORD PTR DS:[EBX],ECX
600553D9 ^ EB ED JMP SHORT pcomm.600553C8
600553DB 24 0F AND AL,0F
600553DD C1E0 10 SHL EAX,10
600553E0 66:8B07 MOV AX,WORD PTR DS:[EDI]
600553E3 83C7 02 ADD EDI,2
600553E6 0BC0 OR EAX,EAX
600553E8 ^ 75 EB JNZ SHORT pcomm.600553D5
600553EA 8B07 MOV EAX,DWORD PTR DS:[EDI]
600553EC 83C7 04 ADD EDI,4
600553EF ^ EB E4 JMP SHORT pcomm.600553D5
600553F1 33DB XOR EBX,EBX ; EDI=60051E4B,也就是重定位表的结束地址
600553F3 87FE XCHG ESI,EDI
实际NsPacK破坏了重定位表.但是已经得到了一些重要的重定位数据。
第二步:OEP
------------------JE pcomm.600554A7-------------------------
600554A7 B8 00000000 MOV EAX,0 ; 第一步的远距离跳转,跳到了这个地方
600554AC 83F8 00 CMP EAX,0
600554AF 74 0A JE SHORT pcomm.600554BB
600554B1 61 POPAD
600554B2 9D POPFD
600554B3 B8 01000000 MOV EAX,1
600554B8 C2 0C00 RETN 0C
600554BB 61 POPAD ; POPAD和POPFD与入口的PUSHFD和PUSHAD构成堆栈平衡
600554BC 9D POPFD
600554BD - E9 93A7FBFF JMP pcomm.6000FC55 ; 直接在这个地方下F2断点,就是飞向光明顶OEP了
--------------------------------------------------------------------------------------
6000FC55 55 PUSH EBP---------------------------》这里就是OEP了。
6000FC56 8BEC MOV EBP,ESP
6000FC58 53 PUSH EBX
6000FC59 8B5D 08 MOV EBX,DWORD PTR SS:[EBP+8]
6000FC5C 56 PUSH ESI
6000FC5D 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]
6000FC60 57 PUSH EDI
6000FC61 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10]
6000FC64 85F6 TEST ESI,ESI
6000FC66 75 09 JNZ SHORT pcomm.6000FC71
6000FC68 833D EC100360 0>CMP DWORD PTR DS:[600310EC],0
6000FC6F EB 26 JMP SHORT pcomm.6000FC97
6000FC71 83FE 01 CMP ESI,1
6000FC74 74 05 JE SHORT pcomm.6000FC7B
6000FC76 83FE 02 CMP ESI,2
6000FC79 75 22 JNZ SHORT pcomm.6000FC9D
6000FC7B A1 1CA70460 MOV EAX,DWORD PTR DS:[6004A71C]
6000FC80 85C0 TEST EAX,EAX
6000FC82 74 09 JE SHORT pcomm.6000FC8D
6000FC84 57 PUSH EDI
6000FC85 56 PUSH ESI
6000FC86 53 PUSH EBX
6000FC87 FFD0 CALL EAX
6000FC89 85C0 TEST EAX,EAX
6000FC8B 74 0C JE SHORT pcomm.6000FC99
6000FC8D 57 PUSH EDI
6000FC8E 56 PUSH ESI
6000FC8F 53 PUSH EBX
6000FC90 E8 15FFFFFF CALL pcomm.6000FBAA
6000FC95 85C0 TEST EAX,EAX
6000FC97 75 04 JNZ SHORT pcomm.6000FC9D
第三步:输入表
随便从程序找一个API调用,如:
6000FBD8 FF15 F4500260 CALL DWORD PTR DS:[600250F4] ; msvcrt.malloc
单击右键选跟随到数据窗口--》内存地址600250F4,上下看到许多函数地址,很明显的可以找到IAT开始和结束的地址:
60025000 77EFD452 GDI32.ExtTextOutA
60025004 77EFA8DA GDI32.CreatePatternBrush
60025008 77EF8709 GDI32.SetBrushOrgEx
6002500C 77EF85B8 GDI32.PatBlt
60025010 77EF6000 GDI32.CreateCompatibleDC
60025014 77EF620F GDI32.CreateBitmap
。。。。。。
60025194 77D217F8 USER32.GetScrollInfo
60025198 77D67BC5 USER32.EnableScrollBar
6002519C 77D2F39A USER32.SendMessageA
600251A0 77D1C01B USER32.SetWindowPos
600251A4 77D3001A USER32.GetPropA
600251A8 77D1C257 USER32.FillRect
600251AC 00000000
600251B0 76D36051 IPHLPAPI.GetAdaptersInfo
600251B4 00000000
第四步:DUMP及修复重定位
用LordPE选中Ollydbg的loaddll.exe的进程,在下面的列表里选择pcomm.dll,然后完整脱壳,得到dumped.dll。
运行ImportREC,(注意:去掉“使用来自磁盘的PE部首”的选项)
选中Ollydbg的loaddll.exe的进程,然后点“选取DLL”,选择pcomm.dll,填入RVA=00025000、大小=000001B4 ,点“Get Import”,得到输入表。改OEP=0000FC55,FixDump!
根据第一步得到的重定位表地址,用WinHex打开dumped_.dll,复制00051000-00051E4B之间的16进制数值,另存为1.bin
运行 看雪老师写的辅助修复UPX加壳DLL重定位表的工具UPXAngela.exe,打开1.bin,很快的提示pediy.bin文件创建成功!
(这里要告诉大家一下,我为什么选择看雪老师写的辅助修复UPX加壳DLL重定位表的工具UPXAngela.exe呢,因为原来学习了FLY大侠写的这篇《用Ollydbg手脱UPX加壳的DLL 》之后才用此工具)
============================================================================================================
大家可以对照一下:
这个是UPX加壳的DLL
003B825E 8A07 mov al,byte ptr ds:[edi]//EDI=003B7318-当前基址003B0000=00007318 ★ 这就是重定位表的RVA
003B8260 47 inc edi
003B8261 09C0 or eax,eax
003B8263 74 22 je short EdrLib.003B8287//重定位数据处理完毕则跳转
003B8265 3C EF cmp al,0EF
003B8267 77 11 ja short EdrLib.003B827A
003B8269 01C3 add ebx,eax
003B826B 8B03 mov eax,dword ptr ds:[ebx]
003B826D 86C4 xchg ah,al//找到这里
003B826F C1C0 10 rol eax,10
003B8272 86C4 xchg ah,al
003B8274 01F0 add eax,esi
003B8276 8903 mov dword ptr ds:[ebx],eax
003B8278 EB E2 jmp short EdrLib.003B825C
003B827A 24 0F and al,0F
003B827C C1E0 10 shl eax,10
003B827F 66:8B07 mov ax,word ptr ds:[edi]
003B8282 83C7 02 add edi,2
003B8285 EB E2 jmp short EdrLib.003B8269
这个是NsPacK V3.7加壳的DLL
600553CA 8A07 MOV AL,BYTE PTR DS:[EDI] ; EDI=60051000-当前基址60000000=00051000 , 这就是重定位表的RVA了
600553CC 47 INC EDI
600553CD 0BC0 OR EAX,EAX
600553CF 74 20 JE SHORT pcomm.600553F1 ; 重定位数据处理完,则跳转
600553D1 3C EF CMP AL,0EF
600553D3 77 06 JA SHORT pcomm.600553DB
600553D5 03D8 ADD EBX,EAX
600553D7 010B ADD DWORD PTR DS:[EBX],ECX
600553D9 ^ EB ED JMP SHORT pcomm.600553C8
600553DB 24 0F AND AL,0F
600553DD C1E0 10 SHL EAX,10
600553E0 66:8B07 MOV AX,WORD PTR DS:[EDI]
600553E3 83C7 02 ADD EDI,2
600553E6 0BC0 OR EAX,EAX
600553E8 ^ 75 EB JNZ SHORT pcomm.600553D5
600553EA 8B07 MOV EAX,DWORD PTR DS:[EDI]
600553EC 83C7 04 ADD EDI,4
600553EF ^ EB E4 JMP SHORT pcomm.600553D5
600553F1 33DB XOR EBX,EBX ; EDI=60051E4B,也就是重定位表的结束地址
============================================================================================================
我们就从dumped_.dll中的00051000处开始。
用WinHex把pediy.bin(注:pediy.bin中的数据长度为1C22比原先的数据长度要长,这就要注意写入时不能覆盖了有用的数据哟)中的16进制数值全部复制、写入到dumped_.dll的00051000处。
用LordPE修正dumped_.dll的重定位表RVA=00051000、大小=00001C22,并保存。
用OD,及Dll_LoadEx载入都很正常。
脱壳完成。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2007年03月12日 13:43:37
[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!