脱壳-PECompact v1.66

前言

在练习脱壳.
这个壳特点:
* 在OEP处少代码, 需要自己在OEP处补齐. 少的代码在OEP之前都能看到. 这是所谓的偷代码.
* 在OEP处脱壳后, ImpRec找不到IAT. 需要自己搜索指令来找到IAT项.

记录

查壳

Detect It Easy => Borland Delphi(-)[-]
PEID => 什么都没找到 *
RDG => PECompact v1.66

查找OEP

用ESP定律

004C3550    50              push    eax
004C3551    68 30ED4800     push    0048ED30
004C3556    C2 0400         retn    4

0048ED30    55              push    ebp
0048ED31    90              nop
0048ED32    8BEC            mov     ebp, esp
0048ED34    90              nop
0048ED35    B9 07000000     mov     ecx, 7
0048ED3A    90              nop
0048ED3B    6A 00           push    0
0048ED3D    6A 00           push    0
0048ED3F    90              nop
0048ED40    90              nop
0048ED41    49              dec     ecx
0048ED42  ^ E9 8EFCFFFF     jmp     0048E9D5

0048E9C7    0000            add     byte ptr [eax], al
0048E9C9    0000            add     byte ptr [eax], al
0048E9CB    0000            add     byte ptr [eax], al
0048E9CD    0000            add     byte ptr [eax], al
0048E9CF    006A 00         add     byte ptr [edx], ch
0048E9D2    6A 00           push    0
0048E9D4    49              dec     ecx
0048E9D5  ^ 75 F9           jnz     short 0048E9D0                   ; 跳到这里来了, 如果这里作为OEP要将前面的代码补上

输入新OEP代码

Address    Size       Owner      Section    Contains      Type   Access    Initial   Mapped as
00400000   00001000   NfoViewe              PE header     Imag   R         RWE
00401000   000A2000   NfoViewe   XtreaM     code          Imag   R         RWE
004A3000   00023000   NfoViewe   .rsrc      SFX,data,res  Imag   R         RWE
004C6000   00001000   NfoViewe   .rsrc      imports       Imag   R         RWE

0048xxxx在代码段(XtreaM)
004Cxxxx在其他段(.rsrc)
必须将004C3550开始的3句话搬到代码段

如果从0048E9C7作为OEP, 正好留了8个字节.
看看将前面欠的语句搬过来, 是否8个字节是否能放下. 
试过了,放不下.
0048E9D5下面也放着代码没空隙.

0048ED30~0048ED42中间还空着5个字节.
004C3550 主要语句就是push eax, 那就将 004C3550的push eax搬到0048ED30.重新组织一下, 将多余的nop去掉, 空间就够了

重新运行程序, 当运行到0048ED30时, 直接将旧代码抹掉, 键入新代码, 然后脱壳.
将 0048ED30 作为OEP, 将0048ED30~0048ED42填充为NOP, 再输入下面的新代码

0048ED30 新的代码为:
push eax 
push ebp
mov ebp, esp
mov ecx, 7
push 0
push 0
dec ecx
jmp 0048E9D5

新代码码好了
0048ED30    50              push    eax                      ; 0048ed30 new OEP
0048ED31    55              push    ebp
0048ED32    8BEC            mov     ebp, esp
0048ED34    B9 07000000     mov     ecx, 7
0048ED39    6A 00           push    0
0048ED3B    6A 00           push    0
0048ED3D    49              dec     ecx
0048ED3E  ^ E9 92FCFFFF     jmp     0048E9D5
0048ED43    90              nop
0048ED44    90              nop
0048ED45    90              nop
0048ED46    90              nop                              ; 原来的语句结尾, 可以看出空间足够.

脱壳

在0048ED30处, 用ollyDump脱2个版本(不勾选RebuildImport, 勾选RebuildImport)
直接运行脱壳后的2个版本,都是报错的.

修复IAT

ImpREC , 输入OEP = 0008ED30, Click “AutoSearch”.

---------------------------
Found something!
---------------------------
Found address which may be in the Original IAT. Try 'Get Import'.
(If it is not correct, try RVA: 00001000 Size:000A2000)
---------------------------
确定   
---------------------------

RVA = 00092018
SIZE = 00000004
去看一下IAT. =>00492018, 都是0, 说明ImpREC没找到IAT.

手工查找IAT

调用API时, 一般都是 call xx

00402BF0    E8 17E6FFFF     call    0040120C                 ; jmp to kernel32.CloseHandle

调用到的API处再跳到IAT表项内容

0040120C  - FF25 0C324900   jmp     dword ptr [49320C]       ; kernel32.CloseHandle

代码段为00401000开始
从00401000开始, 2进制字符串搜索 FF25
搜到了IAT项

004011F9   .  54 49 6E 74 6>ascii   "TInterfacedObjec"
00401209   .  74            ascii   "t"
0040120A      8BC0          mov     eax, eax
0040120C   $- FF25 0C324900 jmp     dword ptr [49320C]       ;  kernel32.CloseHandle
00401212      8BC0          mov     eax, eax
00401214   $- FF25 08324900 jmp     dword ptr [493208]       ;  kernel32.CreateFileA
0040121A      8BC0          mov     eax, eax
0040121C   $- FF25 04324900 jmp     dword ptr [493204]       ;  kernel32.GetFileType

00401388   $- FF25 84314900 jmp     dword ptr [493184]       ;  kernel32.LocalAlloc
0040138E      8BC0          mov     eax, eax
00401390   $- FF25 80314900 jmp     dword ptr [493180]       ;  kernel32.LocalFree
00401396      8BC0          mov     eax, eax
00401398   $- FF25 7C314900 jmp     dword ptr [49317C]       ;  kernel32.VirtualAlloc
0040139E      8BC0          mov     eax, eax
004013A0   $- FF25 78314900 jmp     dword ptr [493178]       ;  kernel32.VirtualFree
004013A6      8BC0          mov     eax, eax
004013A8   $- FF25 74314900 jmp     dword ptr [493174]       ;  kernel32.InitializeCriticalSection
004013AE      8BC0          mov     eax, eax
004013B0   $- FF25 70314900 jmp     dword ptr [493170]       ;  ntdll.RtlEnterCriticalSection
004013B6      8BC0          mov     eax, eax
004013B8   $- FF25 6C314900 jmp     dword ptr [49316C]       ;  ntdll.RtlLeaveCriticalSection
004013BE      8BC0          mov     eax, eax
004013C0   $- FF25 68314900 jmp     dword ptr [493168]       ;  ntdll.RtlDeleteCriticalSection

004036BC   $- FF25 14324900 jmp     dword ptr [493214]       ;  user32.GetKeyboardType
00481C74   $- FF25 50384900 jmp     dword ptr [493850]       ;  UpdSyste.ShowUpdateDialog

用插件”Analyze This”分析一下.连续搜索FF25(CTRL+L), 看到最后一个CAll地址为004036BC

统计IAT范围

第一个Call为 jmp dword ptr [49320C], IAT地址49320C
最后一个Call为 jmp dword ptr [493850], IAT地址为493850
查看IAT地址, 已经找到正确的IAT了

0049320C  7C809BD7  kernel32.CloseHandle
00493210  00000000
00493214  77D311DB  user32.GetKeyboardType
00493218  77D2C908  user32.LoadStringA
0049321C  77D507EA  user32.MessageBoxA
00493220  77D2C8B0  user32.CharNextA
00493224  00000000
00493228  77DA7AAB  advapi32.RegQueryValueExA
0049322C  77DA7842  advapi32.RegOpenKeyExA
00493230  77DA6C17  advapi32.RegCloseKey
00493234  00000000
00493238  770F4880  oleaut32.SysFreeString
0049323C  770FA3EC  oleaut32.SysReAllocStringLen

向ImpREC填入IAT搜索参数
OEP = 0008ED30
IAT RVA = 0009320C // IAT开始地址为0049320C
IAT SIZE = 00000644 // 493850 - 49320C
click “Get Imports”

得到的IAT列表正确
这里写图片描述

IAT修复

点击”Fix Dump”, 对ollyDump脱壳出的2个版本进行IAT修复.

测试

测试时, 2个程序都报错:应用初始化失败

---------------------------
od_dump1_.exe - 应用程序错误
---------------------------
应用程序正常初始化(0xc000007b)失败。请单击“确定”,终止应用程序。 
---------------------------
确定   
---------------------------

重建PE

对ImpRec修复过的2个版本, 用LordPE重建PE, 设置导入表修复选项.
这里写图片描述

这里写图片描述
经过PE重建后, 2个版本中有一个正常运行了.
这个版本是用OllyDump不带引入表重建的版本.

备注

算IAT size时, 弄小了, 前面还有一些(取到一个IAT后, 在Memory窗口前后翻一下, 确定一下RVA和size, 范围弄大点都没关系, 可以在ImpREC中将无效的IAT剪掉).
调整IAT Info RVA and Size后, ImpREC fix.
运行修复完的版本,确实2个都不能运行.
但是经过PETools重建PE后, 2个都可以正常运行了.
不像IAT Info RVA and Size弄小时, PE重建后, 只有一个版本能正常运行.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值