吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 14035|回复: 15
收起左侧

[原创] 说说处理加密IAT的一种常用方法

[复制链接]
kissy 发表于 2008-3-24 15:55
标 题: 说说处理加密IAT的一种常用方法
作 者: wynney
时 间: 2007-04-14 08:07
链 接: http://bbs.pediy.com/showthread.php?t=42694
详细信息:

【文章标题】: 说说处理加密IAT的一种常用方法
【文章作者】: wynney
【下载地址】: 打包下载
【作者声明】: 凑热闹~^_^
--------------------------------------------------------------------------------
【详细过程】

零、前言

在论坛上看到很多朋友说一些教程看不懂,需要多讲一些原理,抽点空写了这篇文章,大侠飘过:)

一、引述

在讲述这个方法之前,我们先看一个实例,壳子是CrypToCrackPeProtector 0.93的,最后一个区段名是.ccp3p。它加密
的软件的输入表是加密了的,算是一个简单的加密壳了。

忽略所有异常

  

引用:
0046B000 > 5B       pop   ebx               ; EP
0046B001  81E3 00FFFFFF  and   ebx, FFFFFF00
0046B007  66:813B 4D5A  cmp   word ptr [ebx], 5A4D
0046B00C  75 33      jnz   short 0046B041
0046B00E  8BF3      mov   esi, ebx
  
??
  
引用:
00400000  00001000  CrypToCr       PE header   Imag  R     RWE
00401000  0004A000  CrypToCr  .text   code     Imag  R     RWE
0044B000  0000C000  CrypToCr  .rdata          Imag  R     RWE
00457000  00009000  CrypToCr  .data   data     Imag  R     RWE
00460000  00003000  CrypToCr  .IDAta          Imag  R     RWE
00463000  00008000  CrypToCr  .rsrc   resources   Imag  R     RWE
0046B000  00002000  CrypToCr  .ccp3p   SFX,imports  Imag  R     RW
  
??
我们先在.rsrc区段F2,F9,再在.text段F2,F9,就到OEP了

  
引用:
004271B0  55       push  ebp            ; OEP
004271B1  8BEC      mov   ebp, esp
004271B3  6A FF      push  -1
004271B5  68 600E4500   push  00450E60
004271BA  68 C8924200   push  004292C8
004271BF  64:A1 00000000 mov   eax, dword ptr fs:[0]
004271C5  50       push  eax
004271C6  64:8925 0000000>mov   dword ptr fs:[0], esp
004271CD  83C4 A8     add   esp, -58
004271D0  53       push  ebx
004271D1  56       push  esi
004271D2  57       push  edi
004271D3  8965 E8     mov   dword ptr [ebp-18], esp
004271D6  FF15 DC0A4600  call  dword ptr [460ADC]     ; 应该是GetVersion,其他的IAT也都加密了
  
??
我们需要找到,IAT加密的地方

重新加载目标程序,命令行DD 460ADC,下内存访问断点,F9几次

  
引用:
0046B338  893C8A     mov   dword ptr [edx+ecx*4], edi   ; 中断在这,看寄存器
0046B33B  807F 05 55   cmp   byte ptr [edi+5], 55
0046B33F  73 0C      jnb   short 0046B34D
0046B341  2B47 01     sub   eax, dword ptr [edi+1]
  
??
  
引用:
EAX 7C8114AB kernel32.GetVersion
ECX 0000005A
EDX 00460974 CrypToCr.00460974
EBX 00400000 CrypToCr.00400000
ESP 0013FFB4
EBP 7C800000 kernel32.7C800000
ESI 00460014 CrypToCr.00460014
EDI 0046B823 CrypToCr.0046B823
EIP 0046B338 CrypToCr.0046B338
  
??
可以看到eax里才是真正的IAT了,把edi改成eax,然后到00401000段下断,F9,到达OEP
IAT全部都恢复了:)


  
引用:
/*
Script written by wynney

Date:  2007-04-13
Script:CrypToCrackPeProtector Fixer
Environment : OllyDbg 1.1, ODBGScript 1.52,Winxp Sp2
Debugging options: Tick all items in OllyDbg's Debugging Options-Exceptions

Thanks :
      kanxue   - author of HideOD   
      hnhuqiong - author of ODbgScript 1.52
*/
var OEP
var temp
var IAT

Start:
        find eip,#2D000000805055FF5424??5A595B8B7C2404#
        cmp $RESULT,0
        je Error
        mov temp,$RESULT
        mov IAT,temp
        mov OEP,temp
        sub OEP,25
        add IAT,12
        bp IAT
        esto
        bc IAT
        repl eip,#893C8A#,#89048A#,3
        bp OEP
        esto
        bc OEP
        sti

Done:
        dpe "\\UnPacked.exe", eip
        cmt eip,"OEP"
        ret
      
Error:
        msg "错误"
        ret
  


  二、PELock 1.0x

前面看了之后,大家应该明白点了,这是最基本的IAT加密法子,从中我们也可以看到最基本的IAT处理法子
但是,有很多壳有壳校验或内存校验,例如:PELock

我们用上面的方法,再入PELock.exe程序,F9,Alt+E,双击目标程序所在行,Ctrl+B:FF 25

  
引用:
0098089F - FF25 E4314000  jmp   dword ptr [4031E4]
009808A5 - E9 B014A8FF   jmp   Dll_Load.00401D5A
009808AA  B0 FF      mov   al, 0FF
009808AC  15 C4314000   adc   eax, 4031C4
009808B1 - E9 F214A8FF   jmp   Dll_Load.00401DA8
009808B6  F2:       prefix repne:
009808B7  FF15 C0314000  call  dword ptr [4031C0]
  
??
重新加载目标程序,DD 4031E4,下内存访问断点,几次F9

  
引用:
00034661  8919      mov   dword ptr [ecx], ebx       ; 中断在这,看寄存器
00034663  EB 03      jmp   short 00034668
00034665  92       xchg  eax, edx
00034666  E1 7C      loopde short 000346E4
  
??
  
引用:
EAX 77BF27FA msvcrt.__CxxFrameHandler
ECX 004031E4 ASCII """:"
EDX 77BE0000 msvcrt.77BE0000
EBX 003B0325
ESP 0013FFAC
EBP 0003062D
ESI 003A0426
EDI 003A038F ASCII "MSVCRT.dll"
EIP 00034661
  
??
eax里才是真正的IAT,ebx里是壳的地址。
那么我们把ebx改成eax,F9运行看看,出现错误:(
那么我们再来看一次,看看是那里出错,改了ebx之后,一路F8,F7交替走

  
引用:
00034351  2B848D 143B0000 sub   eax, dword ptr [ebp+ecx*4+3B14]  ; 到这就走不下去了
00034358  D3C0      rol   eax, cl
0003435A  49       dec   ecx
  
??
看来00034351处就是CrC校验的地方了
我们解决他的法子有2个,这里说个简单的法子吧

同时对00034661和00034351下内存断点,运行到00034661后把eax改成ebx,F9运行到00034351马上又把ebx改成eax,
如此往替,所有的IAT就都修复完了,这个操作如果手动的确是麻烦,呵呵,用脚本吧?


  
引用:
Compar:
cmp eip,IATAddr     //处理输入表的位置
je FixIAT
cmp eip,CrCAddr    //CRC的位置
jne GotoOEP
esto
jmp Compar

FixIAT:
ASM IATAddr,"mov [ecx],eax"
sti
ASM IATAddr,"mov [ecx],ebx"
esto
jmp Compar
  


  三、ASProtect 1.31

  说下两个分支的处理

   
引用:
  00D1574B  8B5424 0C    mov   edx, dword ptr [esp+C]      ; 找到这里
  00D1574F  8902      mov   dword ptr [edx], eax       ; ①ebp里是IAT,把eax改成ebp
  00D15751  8B4424 0C    mov   eax, dword ptr [esp+C]
  00D15755  8906      mov   dword ptr [esi], eax
  00D15757  0FB74424 04   movzx  eax, word ptr [esp+4]
  00D1575C  0143 08     add   dword ptr [ebx+8], eax
   
????
  
   
引用:
  00D15672  8B5424 0C    mov   edx, dword ptr [esp+C]      
  00D15676  8902      mov   dword ptr [edx], eax       ; ②ebp里是IAT,把eax改成ebp
  00D15678  8D4C24 0C    lea   ecx, dword ptr [esp+C]
  00D1567C  8A5424 07    mov   dl, byte ptr [esp+7]
  00D15680  8BC3      mov   eax, ebx
  00D15682  E8 F9F7FFFF   call  00D14E80             ; ③加密Call,nop掉
  00D15687  8BC6      mov   eax, esi
  00D15689  83E8 02     sub   eax, 2
  00D1568C  66:8338 00   cmp   word ptr [eax], 0
  00D15690  75 10      jnz   short 00D156A2          ; ④改jmp
   
??
IAT处理完毕,撤消修改,以免后面出现内存保护错误

  四、ASProtect 2.0 Alpha

  两个分支的处理

  
引用:
  00A8CEAD  8B5424 0C    mov   edx, dword ptr [esp+C]  
  00A8CEB1  8902      mov   dword ptr [edx], eax   ; ①ebp里才是IAT,把eax改成ebp
  00A8CEB3  8B4424 0C    mov   eax, dword ptr [esp+C]
  00A8CEB7  8906      mov   dword ptr [esi], eax
  00A8CEB9  0FB74424 04   movzx  eax, word ptr [esp+4]
  00A8CEBE  0143 08     add   dword ptr [ebx+8], eax
   
????
  
   
引用:
  00A83780  53       push  ebx            ; ②找到这,Patch这里
  00A83781  8BD8      mov   ebx, eax
  00A83783  8BC3      mov   eax, ebx
  00A83785  E8 56FFFFFF   call  00A836E0
  00A8378A  C603 E8     mov   byte ptr [ebx], 0E8    ; 这里是IAT加密,给改成EB了
  00A8378D  43       inc   ebx
  00A8378E  8903      mov   dword ptr [ebx], eax
  00A83790  5B       pop   ebx
  00A83791  C3       retn 3
   
????
  自己Patch代码

   
引用:
  00A83780  66:C700 FF15  mov   word ptr [eax], 15FF   ; Call类型的,如果是jmp类型的把15FF改成25FF
  00A83785  83C0 02     add   eax, 2
  00A83788  8910      mov   dword ptr [eax], edx
  00A8378A  892A      mov   dword ptr [edx], ebp   ; ebp是正确的IAT
  00A8378C  90       nop
  00A8378D  90       nop
  00A8378E  90       nop
  00A8378F  90       nop
  00A83790  90       nop
  00A83791  C3       retn
   
??
IAT处理完毕,最好是撤消修改,以免后面出现内存保护错误

  五、MoleBox

上面我们说的都是比较明显的加密IAT,现在来看个不明显的

MoleBox这个就不用多说了,很容易到达OEP,我们看看IAT表,部分IAT是加密的

  
引用:
00406DF8 - FF25 04756300  jmp   dword ptr [637504]        ; flashfxp.0073BED3
00406DFE  8BC0      mov   eax, eax
00406E00 - FF25 00756300  jmp   dword ptr [637500]        ; flashfxp.0073BE34
00406E06  8BC0      mov   eax, eax
00406E08 - FF25 FC746300  jmp   dword ptr [6374FC]        ; flashfxp.0073BFCE
  
??
重新加载程序,DD 637504,下内存访问断点,几次F9

  
引用:
00715B6F  FF96 20CB3200  call  dword ptr [esi+32CB20]      ; 从这里出来的
00715B75  09C0      or   eax, eax
00715B77  74 07      je   short 00715B80
00715B79  8903      mov   dword ptr [ebx], eax       ; 到达这里,注意eax
00715B7B  83C3 04     add   ebx, 4
00715B7E ^ EB E1      jmp   short 00715B61
  
??
  
引用:
EAX 0073BED3 flashfxp.0073BED3   ;填充无效指针
ECX 0013FFE0
EDX 00CA09D8
EBX 00637504 flashfxp.00637504
ESP 0013FFA4
EBP 7C800000 kernel32.7C800000
ESI 00401000 flashfxp.00401000
EDI 007128E0 flashfxp.007128E0
  
??
he 00715B6F

重载,F9,中断下来后F7,跟踪发现

  
引用:
0073C4E9  FF75 E4     push  dword ptr [ebp-1C]        ; [ebp-1C]里才是真正的IAT
0073C4EC  8B0D 34707400  mov   ecx, dword ptr [747034]
0073C4F2  E8 3E070000   call  0073CC35             ; 加密Call
0073C4F7  8945 E0     mov   dword ptr [ebp-20], eax     ; call会产生一个值给eax,0或1
0073C4FA  837D E0 00   cmp   dword ptr [ebp-20], 0      ; eax再给[ebp-20],再比较
0073C4FE  74 08      je   short 0073C508          ; 为0则不加密,为1则加密,Magic Jump,改jmp
0073C500  8B45 E0     mov   eax, dword ptr [ebp-20]     ; 加密则把值传回eax
0073C503  8B00      mov   eax, dword ptr [eax]       ; [eax]里就是无效指针,传给eax
0073C505  8945 E4     mov   dword ptr [ebp-1C], eax     ; 无效指针再传给[ebp-1C]
0073C508  834D FC FF   or   dword ptr [ebp-4], FFFFFFFF
0073C50C  E8 02000000   call  0073C513
0073C511  EB 1C      jmp   short 0073C52F
0073C513  A1 34707400   mov   eax, dword ptr [747034]
0073C518  8945 D4     mov   dword ptr [ebp-2C], eax
0073C51B  837D D4 00   cmp   dword ptr [ebp-2C], 0
0073C51F  74 0D      je   short 0073C52E
0073C521  8B45 D4     mov   eax, dword ptr [ebp-2C]
0073C524  83C0 10     add   eax, 10
0073C527  50       push  eax
0073C528  FF15 18F07300  call  dword ptr [<&KERNEL32.LeaveCriti>; ntdll.RtlLeaveCriticalSection
0073C52E  C3       retn
0073C52F  8B45 E4     mov   eax, dword ptr [ebp-1C]     ; IAT或无效指针再传给eax
0073C532  8B4D F0     mov   ecx, dword ptr [ebp-10]
0073C535  64:890D 0000000>mov   dword ptr fs:[0], ecx
0073C53C  5F       pop   edi
0073C53D  5E       pop   esi
0073C53E  5B       pop   ebx
0073C53F  C9       leave
0073C540  C2 0800     retn  8                ; 返回后把eax的值传给IAT表地址
  
??
我们把Magic Jump改成jmp之后IAT不再加密:)
这里需要说明的是,这个法子跟我原先的文章里的法子是不一样的,但是可以达到相同的效果

于是,我们可以写个脚本


  
引用:
/*
Script written by wynney

Date:  2007-04-13
Script:MoleBox
Environment : OllyDbg 1.1, ODBGScript 1.52,Winxp Sp2
Debugging options: Tick all items in OllyDbg&#39;s Debugging Options-Exceptions

Thanks :
      kanxue   - author of HideOD   
      hnhuqiong - author of ODbgScript 1.52
*/
#log
var temp

log eip
STI
STO
mov temp,esp
bphws temp,"r"        //esp定律,用来找OEP
esto
bphwcall
find eip,#8945??837D??0074088B45??8B008945??834D??FF#
cmp $RESULT,0
je err
mov temp,$RESULT
repl temp,#8945??837D??0074088B45??8B008945??834D??FF#,#8945??837D??00EB088B45??8B008945??834D??FF#,21
sti
sti
mov temp,eax
bp temp
esto
bc temp
sti
mov temp,esp
bphws temp,"r"
esto
bphwcall
mov temp,eip
add temp,0D
bp temp
esto
bc temp
sti
dpe "\\UnPacked.exe", eip
cmt eip, "This is the OEP! Found By: wynney "
ret

err:
msg "error"
ret
  


--------------------------------------------------------------------------------
【经验总结】
1、若有的壳有内存访问断点校验,可以换用内存写入断点,或者是硬件访问/写入断点
2、如果不是很明显的寄存器填充,那么一般IAT加密就在附近,多跟踪下:)
3、很多时候,并不是单纯的修改可以解决的,需要自己Patch代码,多了解下汇编吧,这个是别人教不会的
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                            2007年04月14日 wynney

免费评分

参与人数 1热心值 +1 收起 理由
颓废、冰 + 1 对新手很有帮助

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

头像被屏蔽
vk929495v 发表于 2014-7-22 07:29
提示: 作者被禁止或删除 内容自动屏蔽
 楼主| kissy 发表于 2008-3-24 15:57
前段时间调试一个外挂 被暗算 机器一直处于半瘫痪状态 答应HMILY的脱文和教程也迟迟未做 无法打开OD。。。。
机器里重要东西比较多 又不舍得重新装系统 只好一点点弄 到今天才差不多了
实在对不住大家 我慢慢补回漏掉的工作
Hmily 发表于 2008-3-24 15:58
 楼主| kissy 发表于 2008-3-24 16:03
前段时间脱幻影的时候遇到不少麻烦 这篇文章给我不少启发 ^_^
咱也学习大牛如何处理IAT加密的
maloushan 发表于 2008-3-24 16:12
三人行的东东,收下学习了.
ladder 发表于 2008-5-22 15:53
先学习了,不过还不是很懂,两个字 复杂
chen123456 发表于 2009-3-24 17:19
非常非常值得学习,谢谢了。
热火朝天 发表于 2009-3-24 19:10
好文章啊,支持一下,要好好学习的
头像被屏蔽
jakccui 发表于 2009-3-25 01:28
提示: 作者被禁止或删除 内容自动屏蔽
凡人1234 发表于 2009-3-25 10:49
太好了,对菜鸟们学习处理IAT有实质性的指导意义
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-18 01:37

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表