找回密码
 注册
搜索
热搜: 回贴

脱壳技术,Arm3.70a对IAT保护的一点心得 ,ARM

2010-1-30 18:20| 发布者: admin| 查看: 61| 评论: 0|原作者: 潇潇雨


脱壳技术,Arm3.70a对IAT保护的一点心得 ,ARM
2008年06月23日 星期一 下午 04:41
Arm3.61版后加强了对IAT解码的保护,这里只谈到IAT解码前的保护代码跟踪心得。

本次使用的程序是goodmorning发在http://tongtian.net/pediybbs/viewtopic.php?t=5395&sid=9f24b627dcfe6d35be45f9f2244142a7

的Armadillo 3.70完全版加的记事本。

前面都是定式了,不要我说……

我从bp OpenMutexA 后,修改代码完成,F9运行再次被中断在OpenMutexA函数的入口地址处开始:



去掉以前的所有断点,bp VirtualProtect F9运行,中断后看看堆栈中:

0012F484 0101FAC6 /CALL 到 VirtualProtect 来自 notepad.0101FAC0

0012F488 009A1000 |Address = 009A1000 <--这里是代码解码的开始

0012F48C 00029CCA |Size = 29CCA (171210.)

0012F490 00000040 |NewProtect = PAGE_EXECUTE_READWRITE

0012F494 0012F4B0 \pOldProtect = 0012F4B0





一直F9运行4次,到堆栈中:

0012F484 0101FAC6 /CALL 到 VirtualProtect 来自 notepad.0101FAC0

0012F488 009DE000 |Address = 009DE000 <--代码解码完成地址

0012F48C 00003216 |Size = 3216 (12822.)

0012F490 00000002 |NewProtect = PAGE_READONLY

0012F494 0012F4B0 \pOldProtect = 0012F4B0



如果再次F9运行,就会出现第一个anti “错误:不知道如何在地址009C7E13处绕过命令……”,这说明程序开始在解码的代码中运行

并且运行到第一个有效验的地方,关闭OD的这个提示窗口,F12就会来到:

009C7E0E >PUSH 9C7E16

009C7E13 >??? ; 未知命令 <--就是这个anti

009C7E15 >IRETD



向上看看:

009C7D59 >PUSH EBP

009C7D5A >MOV EBP,ESP

009C7D5C >PUSH ECX

009C7D5D >PUSH EBX

009C7D5E >XOR EBX,EBX

009C7D60 >CMP BYTE PTR DS:[9D9075],BL

009C7D66 >PUSH ESI

009C7D67 >PUSH EDI

009C7D68 >JNZ SHORT 009C7D7B

009C7D6A >CMP BYTE PTR DS:[9D8CB1],BL

009C7D70 >JNZ SHORT 009C7D7B

009C7D72 >CALL 009A72FD

009C7D77 >TEST EAX,EAX

009C7D79 >JNZ SHORT 009C7D82

009C7D7B >XOR AL,AL

009C7D7D >JMP 009C7EAE

009C7D82 >MOV DWORD PTR SS:[EBP-4],EBX

009C7D85 >MOV DWORD PTR DS:[9D8CD8],EBX

009C7D8B >PUSH ECX

009C7D8C >BSWAP ECX

009C7D8E >NOT ECX

009C7D90 >PUSH EAX

009C7D91 >NOT EAX

009C7D93 >MOV EAX,6C65696D

009C7D98 >XCHG EAX,ECX

009C7D99 >MOV ECX,DEADC0DE

009C7D9E >XCHG EAX,ECX

009C7D9F >NOT EAX

009C7DA1 >POP EAX

009C7DA2 >NOT ECX

009C7DA4 >POP ECX

009C7DA5 >PUSHFD

009C7DA6 >PUSHAD

009C7DA7 >XOR EBX,EBX

009C7DA9 >JE SHORT 009C7DAE

009C7DAB >JMP SHORT 009C7DCF

009C7DAD >JMP SHORT 009C7DE2

009C7DAF >??? ; 未知命令

009C7DB0 >JE SHORT 009C7DB2

009C7DB2 >JMP SHORT 009C7DC1

009C7DB4 >MOV EAX,87B90FEB

009C7DB9 >LEAVE

009C7DBA >STC

009C7DBB >XOR AL,90

009C7DBD >STC

009C7DBE >JE SHORT 009C7DC5

009C7DC0 >JMP SHORT 009C7DF5

009C7DC2 >SAL BYTE PTR DS:[EDX ESI*8-48],87 ; 移动常数超出 1..31 的范围

009C7DC7 >LEAVE

009C7DC8 >INC EAX

009C7DC9 >DEC EAX

009C7DCA >TEST EAX,EAX

009C7DCC ^>JNZ SHORT 009C7DAB

009C7DCE ->JMP 93031B34

009C7DD3 >XCHG AX,DX

009C7DD5 >MOV EAX,EAX

009C7DD7 >MOV EAX,DWORD PTR DS:[9D9200]

009C7DDC >PUSH 9C7E25

009C7DE1 >PUSH DWORD PTR FS:[0]

009C7DE8 >MOV DWORD PTR FS:[0],ESP

009C7DEF >XOR ESI,ESI

009C7DF1 >PUSH 4

009C7DF3 >PUSH 1000

009C7DF8 >PUSH 1000

009C7DFD >PUSH 0

009C7DFF >CALL EAX

009C7E01 >PUSHFW

009C7E03 >BTS DWORD PTR SS:[ESP],10

009C7E08 >BTS DWORD PTR SS:[ESP],8

009C7E0D >PUSH CS

009C7E0E >PUSH 9C7E16

009C7E13 >??? ; 未知命令

009C7E15 >IRETD

009C7E16 >INC DWORD PTR DS:[EAX]

009C7E18 >PUSH EAX

009C7E19 >MOV EAX,DWORD PTR DS:[9D9204]

009C7E1E >CALL EAX

009C7E20 >MOV DWORD PTR SS:[EBP-4],ESI

009C7E23 >JMP SHORT 009C7E9D

009C7E25 >PUSHAD

009C7E26 >LEA EDI,DWORD PTR SS:[ESP 24]

009C7E2A >MOV ESI,DWORD PTR DS:[EDI]

009C7E2C >MOV EDI,DWORD PTR DS:[EDI 8]

009C7E2F >MOV EAX,DWORD PTR DS:[ESI]

009C7E31 >CMP EAX,80000004

009C7E36 >JE SHORT 009C7E71

009C7E38 >CMP EAX,C000001D

009C7E3D >JE SHORT 009C7E44

009C7E3F >POPAD

009C7E40 >XOR EAX,EAX

009C7E42 >INC EAX

009C7E43 >RETN



分析发现是这个函数引起的错误:

009C7D72 >CALL 009A72FD

009C7D77 >TEST EAX,EAX

009C7D79 >JNZ SHORT 009C7D82



修改上面的EAX值为 0 就可以跳过这个anti,重新来做:



bp VirtualProtect F9运行4次,Ctrl F9返回:

0101FAC0 >CALL DWORD PTR DS:[<&KERNEL32.VirtualPro>; kernel32.VirtualProtect

0101FAC6 >TEST EAX,EAX <--- 返回到这里

0101FAC8 >JNZ SHORT notepad.0101FAD8

0101FACA >MOV DWORD PTR DS:[1050504],4

0101FAD4 >XOR EAX,EAX

0101FAD6 >JMP SHORT notepad.0101FB13



F8运行到:

0101EF84 >PUSH 0

0101EF86 >PUSH 1

0101EF88 >MOV EDX,DWORD PTR DS:[10504F8]

0101EF8E >PUSH EDX

0101EF8F >CALL DWORD PTR DS:[10504FC]

上面的CALL就是进入解码代码的入口,F7进入:

009CAA0B >PUSH EBP

009CAA0C >MOV EBP,ESP

009CAA0E >PUSH EBX

009CAA0F >MOV EBX,DWORD PTR SS:[EBP 8]

009CAA12 >PUSH ESI



在这里用Ctrl S搜索命令序列:



PUSH EBP

MOV EBP,ESP

PUSH ECX

PUSH EBX

XOR EBX,EBX



(这个代码是固定的,可以用于别的Arm3.70a加的程序)



来到这里,第一个anti的地方:



009C7D59 >PUSH EBP

009C7D5A >MOV EBP,ESP

009C7D5C >PUSH ECX

009C7D5D >PUSH EBX

009C7D5E >XOR EBX,EBX

009C7D60 >CMP BYTE PTR DS:[9D9075],BL

009C7D66 >PUSH ESI

009C7D67 >PUSH EDI

009C7D68 >JNZ SHORT 009C7D7B

009C7D6A >CMP BYTE PTR DS:[9D8CB1],BL

009C7D70 >JNZ SHORT 009C7D7B

009C7D72 >CALL 009A72FD

009C7D77 >TEST EAX,EAX

009C7D79 >JNZ SHORT 009C7D82



光标停在:



009C7D77 >TEST EAX,EAX



F4直接到这个地方,修改EAX的值为0 第一个anti过去了:)



F9运行,又一次出现错误,再次运行到过了第一个anti后,F8运行到:



009C36E0 >MOV EAX,DWORD PTR DS:[9D9560]

009C36E5 >MOV AL,BYTE PTR DS:[EAX 3D2F]

009C36EB >MOV BYTE PTR SS:[EBP-31B0],AL

009C36F1 >MOVZX EAX,BYTE PTR SS:[EBP-31B0]

009C36F8 >TEST EAX,EAX

009C36FA >JE 009C382A



发现错误是上面的这效验引起的,修改SS:[EBP-31B0]地址中的值为0 后F9运行,在地址01001000地址里发现写入了数据了。又一次被中断在:



77E1F149 > >PUSH EBP

77E1F14A >MOV EBP,ESP

77E1F14C >PUSH DWORD PTR SS:[EBP 14]

77E1F14F >PUSH DWORD PTR SS:[EBP 10]

77E1F152 >PUSH DWORD PTR SS:[EBP C]

77E1F155 >PUSH DWORD PTR SS:[EBP 8]

77E1F158 >PUSH -1

77E1F15A >CALL kernel32.VirtualProtectEx

77E1F15F >POP EBP

77E1F160 >RETN 10





停止在函数VirtualProtect的入口地址处。



以后可以对bp GetModuleHandleA 下中断,查找那个Magic Jmp的地方,或者利用bp VirtualProtect这个断点到IAT解码的代码处



在解码IAT的代码处还有anti这个以后再讨论。



个人心得,未必正确,仅作参考。







fxyang[OCN][BCG][FCG]



2003.3.22


最新评论

QQ|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )

GMT+8, 2024-9-29 21:33 , Processed in 0.213222 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

返回顶部