PEtite 2.3加壳的记事本IAT修复
【文章标题】: 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:
01010057 64:8925 0000000>MOV DWORD PTR FS:,ESP
0101005E 66:9C PUSHFW
01010060 60 PUSHAD
01010061 50 PUSH EAX
01010062 8BD8 MOV EBX,EAX
01010064 0300 ADD EAX,DWORD PTR DS:
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:
01008691 8BCE MOV ECX,ESI
01008693 2BCF SUB ECX,EDI
01008695 F3:AA REP STOS BYTE PTR ES:
01008697 60 PUSHAD
01008698 FFE0 JMP EAX 这里会出现一个一个EIP的异常,直接用OD的SEH查看的功能,在SEH处下断即可
010088D0 33C0 XOR EAX,EAX 断在这
010088D2 64:8B18 MOV EBX,DWORD PTR FS:
010088D5 8B1B MOV EBX,DWORD PTR DS:
010088D7 8D63 AE LEA ESP,DWORD PTR DS:
一路F8
步入遇到的CALL
0101003D 5F POP EDI ; NOTEPAD_.01008956
0101003E F3:AA REP STOS BYTE PTR ES:
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 00000000MOV EAX,DWORD PTR FS:
01006435 50 PUSH EAX
01006436 64:8925 0000000>MOV DWORD PTR FS:,ESP
0100643D 83C4 98 ADD ESP,-68
01006440 53 PUSH EBX
01006441 56 PUSH ESI
01006442 57 PUSH EDI
因为是VC程序所以我们在OEP搜索二进制 FF15,在内存窗口跟随,再右键Long—>address
010010000101006ENOTEPAD_.0101006E
0100100477DC8F7DADVAPI32.RegCreateKeyW
0100100877DA6FC8ADVAPI32.RegQueryValueExW
0100100C77DAD7CCADVAPI32.RegSetValueExW
0100101001010073NOTEPAD_.01010073
0100101401010078NOTEPAD_.01010078
0100101877DA6BF0ADVAPI32.RegCloseKey
0100101C00000000
可以看见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:; 把IAT处存放的地址给eax
00C70008 8B4B 01 MOV ECX,DWORD PTR DS:; 把EB后面的偏移给ecx
00C7000B 03CB ADD ECX,EBX ; 加上地址
00C7000D 83C1 05 ADD ECX,5 ; 在加上5个字节的偏移,此时ecx的值就是原API的地址,具体为什么这样计算就需要了解转移指令的原理了
00C70010 8908 MOV DWORD PTR DS:; 填写会原来的IAT
00C70012 83C0 04 ADD EAX,4 ; 指向下一个IAT地址
00C70015 8338 00 CMP DWORD PTR DS:; 比较是否为0,这步是必须的因为每个Dll的输入表地址间以一个DWORD结尾
00C70018^ 74 F8 JE SHORT 00C70012 ; 是0就指向下一个吧
00C7001A 8078 03 01 CMP BYTE PTR DS:; 因为壳修改后的调用地址都是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 这篇文章写得不错啊,能学到东西,不能这样沉了
页:
[1]