好友
阅读权限10
听众
最后登录1970-1-1
|
pao
发表于 2010-4-19 19:38
【文章标题】: PEtite 2.3加壳的记事本IAT修复
【文章作者】: pao
【作者邮箱】: paohum@126.com
【软件名称】: PEtite 2.3加壳的记事本
【操作平台】: 盗版XP_2
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
01010046 > B8 00000101 MOV EAX,NOTEPAD_.01010000 壳EP
0101004B 68 00860001 PUSH NOTEPAD_.01008600
01010050 64:FF35 0000000>PUSH DWORD PTR FS:[0]
01010057 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
0101005E 66:9C PUSHFW
01010060 60 PUSHAD
01010061 50 PUSH EAX
01010062 8BD8 MOV EBX,EAX
01010064 0300 ADD EAX,DWORD PTR DS:[EAX]
01010066 68 D4330000 PUSH 33D4
0101006B 6A 00 PUSH 0
因为是介绍IAT修复所以如何到达OEP就不详细写了,不过这壳到OEP也不难单步跟就可以了有几个异常
0100868A 57 PUSH EDI 一路F8步入某call
0100868B 8DB7 55010000 LEA ESI,DWORD PTR DS:[EDI+155]
01008691 8BCE MOV ECX,ESI
01008693 2BCF SUB ECX,EDI
01008695 F3:AA REP STOS BYTE PTR ES:[EDI]
01008697 60 PUSHAD
01008698 FFE0 JMP EAX 这里会出现一个一个EIP的异常,直接用OD的SEH查看的功能,在SEH处下断即可
010088D0 33C0 XOR EAX,EAX 断在这
010088D2 64:8B18 MOV EBX,DWORD PTR FS:[EAX]
010088D5 8B1B MOV EBX,DWORD PTR DS:[EBX]
010088D7 8D63 AE LEA ESP,DWORD PTR DS:[EBX-52]
一路F8
步入遇到的CALL
0101003D 5F POP EDI ; NOTEPAD_.01008956
0101003E F3:AA REP STOS BYTE PTR ES:[EDI]
01010040 61 POPAD
01010041 66:9D POPFW
01010043 83C4 08 ADD ESP,8
01010046 >- E9 D563FFFF JMP NOTEPAD_.01006420 跳向OEP
0101004B - E9 46863275 JMP comdlg32.FindTextW
01010050 - E9 9E7C3275 JMP comdlg32.GetSaveFileNameW
01010055 - E9 7C483375 JMP comdlg32.PageSetupDlgW
0101005A - E9 8970637C JMP SHELL32.DragFinish
0101005F - E9 CBEDC076 JMP msvcrt._controlfp
01010064 - E9 452DBF76 JMP msvcrt._XcptFilter
01010069 - E9 265CBF76 JMP msvcrt._except_handler3
0101006E - E9 8AD5DB76 JMP ADVAPI32.IsTextUnicode
01010073 - E9 A375D976 JMP ADVAPI32.RegOpenKeyExA
01010078 - E9 0678D976 JMP ADVAPI32.RegQueryValueExA
0101007D - E9 BE02927B JMP ntdll.RtlSetLastWin32Error
01010082 - E9 671E7F7B JMP kernel32.GetStartupInfoA
01006420 55 PUSH EBP 程序的OEP
01006421 8BEC MOV EBP,ESP
01006423 6A FF PUSH -1
01006425 68 88180001 PUSH NOTEPAD_.01001888
0100642A 68 D0650001 PUSH NOTEPAD_.010065D0
0100642F 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
01006435 50 PUSH EAX
01006436 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
0100643D 83C4 98 ADD ESP,-68
01006440 53 PUSH EBX
01006441 56 PUSH ESI
01006442 57 PUSH EDI
因为是VC程序所以我们在OEP搜索二进制 FF15,在内存窗口跟随,再右键Long—>address
01001000 0101006E NOTEPAD_.0101006E
01001004 77DC8F7D ADVAPI32.RegCreateKeyW
01001008 77DA6FC8 ADVAPI32.RegQueryValueExW
0100100C 77DAD7CC ADVAPI32.RegSetValueExW
01001010 01010073 NOTEPAD_.01010073
01001014 01010078 NOTEPAD_.01010078
01001018 77DA6BF0 ADVAPI32.RegCloseKey
0100101C 00000000
可以看见IAT被加密了,随便点击一个被加密的右键Follow in Dump再右键Disassembly
0101004B - E9 46863275 JMP comdlg32.FindTextW
01010050 - E9 9E7C3275 JMP comdlg32.GetSaveFileNameW
01010055 - E9 7C483375 JMP comdlg32.PageSetupDlgW
0101005A - E9 8970637C JMP SHELL32.DragFinish
0101005F - E9 CBEDC076 JMP msvcrt._controlfp
01010064 - E9 452DBF76 JMP msvcrt._XcptFilter
01010069 - E9 265CBF76 JMP msvcrt._except_handler3
0101006E - E9 8AD5DB76 JMP ADVAPI32.IsTextUnicode
01010073 - E9 A375D976 JMP ADVAPI32.RegOpenKeyExA
01010078 - E9 0678D976 JMP ADVAPI32.RegQueryValueExA
0101007D - E9 BE02927B JMP ntdll.RtlSetLastWin32Error
01010082 - E9 671E7F7B JMP kernel32.GetStartupInfoA
01010087 - E9 63B97F7B JMP kernel32.lstrcpynW
0101008C - E9 46ED7F7B JMP kernel32.FindClose
01010091 - E9 36A97F7B JMP kernel32.lstrcmpW
01010096 - E9 DC1C7F7B JMP kernel32.LoadLibraryA
0101009B - E9 D536827B JMP kernel32.GetDateFormatW
可以看到都被加密成JMP的形式了,看了几个发现都是这种加密的形式,好了我们记录下3个数据,IAT开始的地址和结束的地址
、OEP 分别是1001000和10012F8、01006420
用strongOD分配内存开始写代码修复代码
00C70000 60 PUSHAD ; 保存现场
00C70001 B8 00100001 MOV EAX,1001000 ; IAT开始的地址给eax,用eax来做IAT的指针
00C70006 8B18 MOV EBX,DWORD PTR DS:[eax]; 把IAT处存放的地址给eax
00C70008 8B4B 01 MOV ECX,DWORD PTR DS:[ebx+1]; 把EB后面的偏移给ecx
00C7000B 03CB ADD ECX,EBX ; 加上地址
00C7000D 83C1 05 ADD ECX,5 ; 在加上5个字节的偏移,此时ecx的值就是原API的地址,具体为什么这样计算就需要了解转移指令的原理了
00C70010 8908 MOV DWORD PTR DS:[EAX]; 填写会原来的IAT
00C70012 83C0 04 ADD EAX,4 ; 指向下一个IAT地址
00C70015 8338 00 CMP DWORD PTR DS:[EAX+3]; 比较是否为0,这步是必须的因为每个Dll的输入表地址间以一个DWORD结尾
00C70018 ^ 74 F8 JE SHORT 00C70012 ; 是0就指向下一个吧
00C7001A 8078 03 01 CMP BYTE PTR DS:[EAX+3]; 因为壳修改后的调用地址都是01开头的,其他的不是0就是正常的
00C7001E ^ 75 F2 JNZ SHORT 00C70012 ; 所以不用修改直接指向下一个
00C70020 90 NOP
00C70021 3D F8120001 CMP EAX,10012F8 ; 是否结束了
00C70026 7F 04 JG SHORT 00C7002C ; 结束了就跳走
00C70028 90 NOP
00C70029 90 NOP
00C7002A ^ EB DA JMP SHORT 00C70006 ; 没结束继续干苦力
00C7002C 61 POPAD ; 结束了就还原现在把
00C7002D - E9 EE633900 JMP NOTEPAD_.01006420 ; 跳回OEP吧
写完后直接在OEP下断,再用ImportREC重建输入表,全部有效。。
--------------------------------------------------------------------------------
【经验总结】
其实这个JMP类型的用ImportREC的等级1都可以修复的,单个人觉得自己写代码修复的话能写到的东西更多,也可以锻炼自
己的汇编能力。
THE END!
--------------------------------------------------------------------------------
【版权声明】: 没有版权,欢迎转载!
2010年04月13日 20:19:17 |
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|