说说处理加密IAT的一种常用方法
标 题: 说说处理加密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
0046B00181E3 00FFFFFFand ebx, FFFFFF00
0046B00766:813B 4D5Acmp word ptr , 5A4D
0046B00C75 33 jnz short 0046B041
0046B00E8BF3 mov esi, ebx
??
引用:
0040000000001000CrypToCr PE header ImagR RWE
004010000004A000CrypToCr.text code ImagR RWE
0044B0000000C000CrypToCr.rdata ImagR RWE
0045700000009000CrypToCr.data data ImagR RWE
0046000000003000CrypToCr.idata ImagR RWE
0046300000008000CrypToCr.rsrc resources ImagR RWE
0046B00000002000CrypToCr.ccp3p SFX,importsImagR RW
??
我们先在.rsrc区段F2,F9,再在.text段F2,F9,就到OEP了
引用:
004271B055 pushebp ; OEP
004271B18BEC mov ebp, esp
004271B36A FF push-1
004271B568 600E4500 push00450E60
004271BA68 C8924200 push004292C8
004271BF64:A1 00000000 mov eax, dword ptr fs:
004271C550 pusheax
004271C664:8925 0000000>mov dword ptr fs:, esp
004271CD83C4 A8 add esp, -58
004271D053 pushebx
004271D156 pushesi
004271D257 pushedi
004271D38965 E8 mov dword ptr , esp
004271D6FF15 DC0A4600calldword ptr ; 应该是GetVersion,其他的IAT也都加密了
??
我们需要找到,IAT加密的地方
重新加载目标程序,命令行DD 460ADC,下内存访问断点,F9几次
引用:
0046B338893C8A mov dword ptr , edi ; 中断在这,看寄存器
0046B33B807F 05 55 cmp byte ptr , 55
0046B33F73 0C jnb short 0046B34D
0046B3412B47 01 sub eax, dword ptr
??
引用:
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 E4314000jmp dword ptr
009808A5 - E9 B014A8FF jmp Dll_Load.00401D5A
009808AAB0 FF mov al, 0FF
009808AC15 C4314000 adc eax, 4031C4
009808B1 - E9 F214A8FF jmp Dll_Load.00401DA8
009808B6F2: prefix repne:
009808B7FF15 C0314000calldword ptr
??
重新加载目标程序,DD 4031E4,下内存访问断点,几次F9
引用:
000346618919 mov dword ptr , ebx ; 中断在这,看寄存器
00034663EB 03 jmp short 00034668
0003466592 xchgeax, edx
00034666E1 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交替走
引用:
000343512B848D 143B0000 sub eax, dword ptr ; 到这就走不下去了
00034358D3C0 rol eax, cl
0003435A49 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 ,eax"
sti
ASM IATAddr,"mov ,ebx"
esto
jmp Compar
三、ASProtect 1.31
说下两个分支的处理
引用:
00D1574B8B5424 0C mov edx, dword ptr ; 找到这里
00D1574F8902 mov dword ptr , eax ; ①ebp里是IAT,把eax改成ebp
00D157518B4424 0C mov eax, dword ptr
00D157558906 mov dword ptr , eax
00D157570FB74424 04 movzxeax, word ptr
00D1575C0143 08 add dword ptr , eax
????
引用:
00D156728B5424 0C mov edx, dword ptr
00D156768902 mov dword ptr , eax ; ②ebp里是IAT,把eax改成ebp
00D156788D4C24 0C lea ecx, dword ptr
00D1567C8A5424 07 mov dl, byte ptr
00D156808BC3 mov eax, ebx
00D15682E8 F9F7FFFF call00D14E80 ; ③加密Call,nop掉
00D156878BC6 mov eax, esi
00D1568983E8 02 sub eax, 2
00D1568C66:8338 00 cmp word ptr , 0
00D1569075 10 jnz short 00D156A2 ; ④改jmp
??
IAT处理完毕,撤消修改,以免后面出现内存保护错误
四、ASProtect 2.0 Alpha
两个分支的处理
引用:
00A8CEAD8B5424 0C mov edx, dword ptr
00A8CEB18902 mov dword ptr , eax ; ①ebp里才是IAT,把eax改成ebp
00A8CEB38B4424 0C mov eax, dword ptr
00A8CEB78906 mov dword ptr , eax
00A8CEB90FB74424 04 movzxeax, word ptr
00A8CEBE0143 08 add dword ptr , eax
????
引用:
00A8378053 pushebx ; ②找到这,Patch这里
00A837818BD8 mov ebx, eax
00A837838BC3 mov eax, ebx
00A83785E8 56FFFFFF call00A836E0
00A8378AC603 E8 mov byte ptr , 0E8 ; 这里是IAT加密,给改成EB了
00A8378D43 inc ebx
00A8378E8903 mov dword ptr , eax
00A837905B pop ebx
00A83791C3 retn 3
????
自己Patch代码
引用:
00A8378066:C700 FF15mov word ptr , 15FF ; Call类型的,如果是jmp类型的把15FF改成25FF
00A8378583C0 02 add eax, 2
00A837888910 mov dword ptr , edx
00A8378A892A mov dword ptr , ebp ; ebp是正确的IAT
00A8378C90 nop
00A8378D90 nop
00A8378E90 nop
00A8378F90 nop
00A8379090 nop
00A83791C3 retn
??
IAT处理完毕,最好是撤消修改,以免后面出现内存保护错误
五、MoleBox
上面我们说的都是比较明显的加密IAT,现在来看个不明显的
MoleBox这个就不用多说了,很容易到达OEP,我们看看IAT表,部分IAT是加密的
引用:
00406DF8 - FF25 04756300jmp dword ptr ; flashfxp.0073BED3
00406DFE8BC0 mov eax, eax
00406E00 - FF25 00756300jmp dword ptr ; flashfxp.0073BE34
00406E068BC0 mov eax, eax
00406E08 - FF25 FC746300jmp dword ptr ; flashfxp.0073BFCE
??
重新加载程序,DD 637504,下内存访问断点,几次F9
引用:
00715B6FFF96 20CB3200calldword ptr ; 从这里出来的
00715B7509C0 or eax, eax
00715B7774 07 je short 00715B80
00715B798903 mov dword ptr , eax ; 到达这里,注意eax
00715B7B83C3 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,跟踪发现
引用:
0073C4E9FF75 E4 pushdword ptr ; 里才是真正的IAT
0073C4EC8B0D 34707400mov ecx, dword ptr
0073C4F2E8 3E070000 call0073CC35 ; 加密Call
0073C4F78945 E0 mov dword ptr , eax ; call会产生一个值给eax,0或1
0073C4FA837D E0 00 cmp dword ptr , 0 ; eax再给,再比较
0073C4FE74 08 je short 0073C508 ; 为0则不加密,为1则加密,Magic Jump,改jmp
0073C5008B45 E0 mov eax, dword ptr ; 加密则把值传回eax
0073C5038B00 mov eax, dword ptr ; 里就是无效指针,传给eax
0073C5058945 E4 mov dword ptr , eax ; 无效指针再传给
0073C508834D FC FF or dword ptr , FFFFFFFF
0073C50CE8 02000000 call0073C513
0073C511EB 1C jmp short 0073C52F
0073C513A1 34707400 mov eax, dword ptr
0073C5188945 D4 mov dword ptr , eax
0073C51B837D D4 00 cmp dword ptr , 0
0073C51F74 0D je short 0073C52E
0073C5218B45 D4 mov eax, dword ptr
0073C52483C0 10 add eax, 10
0073C52750 pusheax
0073C528FF15 18F07300calldword ptr [<&KERNEL32.LeaveCriti>; ntdll.RtlLeaveCriticalSection
0073C52EC3 retn
0073C52F8B45 E4 mov eax, dword ptr ; IAT或无效指针再传给eax
0073C5328B4D F0 mov ecx, dword ptr
0073C53564:890D 0000000>mov dword ptr fs:, ecx
0073C53C5F pop edi
0073C53D5E pop esi
0073C53E5B pop ebx
0073C53FC9 leave
0073C540C2 0800 retn8 ; 返回后把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'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 前段时间调试一个外挂 被暗算 机器一直处于半瘫痪状态 答应HMILY的脱文和教程也迟迟未做 无法打开OD。。。。
机器里重要东西比较多 又不舍得重新装系统 只好一点点弄 到今天才差不多了
实在对不住大家 我慢慢补回漏掉的工作 这个文章好好学习下~~~ 前段时间脱幻影的时候遇到不少麻烦 这篇文章给我不少启发 ^_^
咱也学习大牛如何处理IAT加密的 三人行的东东,收下学习了. 先学习了,不过还不是很懂,两个字 复杂 非常非常值得学习,谢谢了。 好文章啊,支持一下,要好好学习的 太好了,对菜鸟们学习处理IAT有实质性的指导意义:lol
页:
[1]
2