pao 发表于 2010-4-19 19:38

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

水母干 发表于 2010-8-28 00:11

这篇文章写得不错啊,能学到东西,不能这样沉了
页: [1]
查看完整版本: PEtite 2.3加壳的记事本IAT修复