TPPpack脱壳的一点记录
本帖最后由 smallyou93 于 2009-12-28 19:51 编辑本文是由ximo大牛的指导下完成,学到了很多东西,感谢ximo,膜拜ximo
脱壳目标:TPPpack加过的记事本(TPPpack主程序见附件,在tut发现的..)
1.SEH + AntiDRx01013010 > $E8 00000000 call 01013015 ;EP
01013015 $5D pop ebp
01013016 .81ED F58F4000 sub ebp, 0x408FF5
0101301C .60 pushad
0101301D .33F6 xor esi, esi ;ESI清零
0101301F .E8 11000000 call <SEH_1>
00495024 8B6424 08 mov esp, dword ptr ;Drx清零01013035 > $64:FF35 00000000 push dword ptr fs:
0101303C .64:8925 00000000 mov dword ptr fs:, esp
01013043 .AD lods dword ptr ;造成第一次内存访问异常.Dr7清零
01013044 .90 nop
01013024 .8B6424 08 mov esp, dword ptr ;异常出口
01013028 .64:8F05 00000000 pop dword ptr fs:
0101302F .58 pop eax
01013030 .61 popad
01013031 .EB 13 jmp short 01013046
01013046 ?60 pushad
01013047 ?33FF xor edi, edi ;edi清零
01013049 .E8 00000000 call <SEH_2>
0101304E >/$830424 10 add dword ptr , 0x10
01013052|.64:8B07 mov eax, dword ptr fs:
01013055|.50 push eax
01013056|.64:8927 mov dword ptr fs:, esp
01013059|.C607 00 mov byte ptr , 0x0 ;再次造成内存访问异常.Dr7清零
0101305C|.90 nop
0101305D|.90 nop
0101305E|.8B7C24 0C mov edi, dword ptr ;DRx全部清零
01013062|.33C0 xor eax, eax ;eax清零
01013064|.8947 04 mov dword ptr , eax
01013067|.8947 08 mov dword ptr , eax
0101306A|.8947 0C mov dword ptr , eax
0101306D|.8947 10 mov dword ptr , eax
01013070|.8387 B8000000 27 add dword ptr , 0x27
01013077|.33C0 xor eax, eax
01013079\.C3 retn ;返回到ntdll.7C9232A8
0101307A 1F db 1FDr0,Dr1,Dr2,Dr3是存放中断的地址,Dr6,Dr7是控制状态的(比如硬件写入断点还是执行等等),被清零了,你下的硬件断点信息全被清掉了,因此下的硬件断点也就失效了
2.Stolen code
bp VirtualProtect 解码后返回
alt+m 在x001000下内存访问断点 shift+f9就到fake oep了01007568/$68 BA750001 push 010075BA ;断在这里向上一拉,全是00...01007398 CC int3
01007399 CC int3
0100739A CC int3
0100739B CC int3
0100739C CC int3
0100739D 00 db 00 ;这里才是oep
--------------------------------------(省去一部分)--------------------------------------
01007562 00 db 00
01007563 CC int3
01007564 CC int3
01007565 CC int3
01007566 CC int3
01007567 CC int3
01007568/$68 BA750001 push 010075BA ;断在这里100739D 到 1007562 的代码都被壳抽取到壳中了
大小0x1c6
3.IAT加密
bp GetModuleHandleA+20
观察堆栈0013FF90 0049783D返回到 TPPpack.0049783D
0013FF94 1001E235ASCII "KERNEL32.dll" <---第一次
....(shift+f9若干次后)...
0013FF10 1000C135返回到 1000C135 来自 kernel32.GetModuleHandleA
0013FF14 1001B997ASCII "KERNEL32"
0013FD20 1000572B返回到 1000572B 来自 kernel32.GetModuleHandleA
0013FD24 006518C0ASCII "ntdll.dll" <---返回时机了.alt+f9取消断点返回1000C12A 68 97B90110 push 0x1001B997 ; ASCII "KERNEL32"
1000C12F FF15 D7730110 call dword ptr ; kernel32.GetModuleHandleA
1000C135 85C0 test eax, eax ; 返回到这里
1000C137 74 15 je short 1000C14ECtrl+B 搜索
3D ?? ?? ?? ?? 74 ?? 3D ?? ?? ?? ?? 74 ?? 3D ?? ?? ?? ?? 74 ?? 3D ?? ?? ?? ??10005B6E FF15 08710110 call dword ptr ; kernel32.GetProcAddress
10005B74 894424 18 mov dword ptr , eax
10005B78 EB 08 jmp short 10005B82
10005B7A 1122 adc dword ptr , esp
10005B7C 334455 66 xor eax, dword ptr
10005B80^ 77 88 ja short 10005B0A
10005B82 8B4424 54 mov eax, dword ptr
10005B86 3D 53F14A7A cmp eax, 0x7A4AF153
10005B8B 74 19 je short 10005BA6 ; nop
10005B8D 3D 4DE75D66 cmp eax, 0x665DE74D
10005B92 74 12 je short 10005BA6 ; nop
10005B94 3D 5FF05127 cmp eax, 0x2751F05F
10005B99 74 0B je short 10005BA6 ; nop
10005B9B 3D 59F04E75 cmp eax, 0x754EF059
10005BA0 0F85 70010000 jnz 10005D16 ; magic jmp10005BA0的jnz改成jmp即可跳过iat加密
4.AntiDump
bp VirtualProtect 解码后返回10008531 FF15 C1790110 call dword ptr ; kernel32.VirtualProtect
10008537 83C7 01 add edi, 0x1 ; 返回到这里Ctrl+B 搜索
8B 94 24 6C 01 00 001000874B 8B9424 6C010000 mov edx, dword ptr ; 此处下断
10008752 8D4C24 18 lea ecx, dword ptr
10008756 51 push ecx
10008757 6A 01 push 0x1
10008759 6A 64 push 0x64
1000875B 52 push edx
1000875C FF15 92130210 call dword ptr ; 跟进
004A1AD4 8BFF mov edi, edi
004A1AD6 55 push ebp
004A1AD7 8BEC mov ebp, esp
004A1AD9 FF75 14 push dword ptr
004A1ADC FF75 10 push dword ptr
004A1ADF FF75 0C push dword ptr
004A1AE2 FF75 08 push dword ptr
004A1AE5 6A FF push -0x1
004A1AE7 E8 75FFFFFF call 004A1A61 ; F7
004A1A61 8BFF mov edi, edi
004A1A63 55 push ebp
004A1A64 8BEC mov ebp, esp
004A1A66 56 push esi
004A1A67 8B35 C4124A00 mov esi, dword ptr ; ntdll.ZwProtectVirtualMemory
004A1A6D 57 push edi
004A1A6E FF75 18 push dword ptr
004A1A71 8D45 10 lea eax, dword ptr
004A1A74 FF75 14 push dword ptr
004A1A77 50 push eax
004A1A78 8D45 0C lea eax, dword ptr
004A1A7B 50 push eax
004A1A7C FF75 08 push dword ptr
004A1A7F FFD6 call esi ; ntdll.ZwProtectVirtualMemory看一下ZwProtectVirtualMemory参数#define PAGE_NOACCESS 0x01
#define PAGE_READONLY 0x02
#define PAGE_READWRITE 0x04
#define PAGE_WRITECOPY 0x08
#define PAGE_EXECUTE 0x10
#define PAGE_EXECUTE_READ 0x20
#define PAGE_EXECUTE_READWRITE 0x40再看回头那段代码1000874B 8B9424 6C010000 mov edx, dword ptr
10008752 8D4C24 18 lea ecx, dword ptr
10008756 51 push ecx
10008757 6A 01 push 0x1 ; 参数为1,也就是NOACCESS
10008759 6A 64 push 0x64那这样就好办了,只要把10008757改成push 40就可以过Anti Dump
5.寻找被偷的代码
bp VirtualProtect 解码后返回
Ctrl+B 搜索
8B 94 24 6C 01 00 00
把10007E76 6A 01 push 0x1改成10007E76 6A 40 push 0x40 //先干掉antidump,方便找回被偷的代码Ctrl+B 搜索
B8 01 00 00 00 C2 04 00 CC CC CC CC CC CC CC CC CC CC CC CC CC1000831D B8 01000000 mov eax, 0x1 ; 断在这里
10008322 C2 0400 retn 0x4 ; 返回
10008325 CC int3
10008326 CC int3
10008327 CC int3
10008328 CC int3
10008329 CC int3
1000832A CC int3
1000832B CC int3右键,查找,命令,jmp eax,下断,shift+f9,取消断点(一般是很大的跳转.如果不是大跳转,多找几次)010153CB- FFE0 jmp eax ; F7跟进后就是被偷的代码了!
直接用二进制复制吧
复制到100739D那里后,还需要修正一下call的地址006AFE00 6A 70 push 0x70 //被偷的代码
006AFE02 68 98180001 push 0x1001898
006AFE07 E8 5C779500 call pack_NOT.01007568 <---call 1
...........
006AFEAB E8 44779500 call pack_NOT.010075F4 <---call 2
...........
006AFEC4 E8 14779500 call pack_NOT.010075DD <---call 3
006AFEC9 68 10900001 push 0x1009010
006AFECE 68 0C900001 push 0x100900C
006AFED3 E8 FA769500 call pack_NOT.010075D2 <---call 4
...........
006AFF09 E8 C4769500 call pack_NOT.010075D2 <---call 5
...........
006AFF6F E8 C2299500 call pack_NOT.01002936 <--- call 6
...........
006AFF99 E8 28769500 call pack_NOT.010075C6 <--- call 7
........
006AFFC0 E8 DE759500 call pack_NOT.010075A3 <--- call 8
006AFFC5 C3 retn总结一下脱壳步骤:
1.bp GetModuleHandleA+20
2.返回干掉iat加密
3.再次断在VirtualProtect那里,解码后返回干掉AntiDump
4.找被偷的代码
5.alt+m,在test(x01000)下内存访问断点,来到fake oep,向上拉,粘贴一下被偷的代码
6.修正一下call的地址,LORDPE+IMPREC修复之.脱壳完成 :@靠 真难脱 膜拜。 向来不会脱壳。。。。 徐ma又祸害孩子了,文章分析的很好! 跟楼主看齐```学习```膜拜``` 丫的,bslz+膜拜 :$qqq
膜拜 晕4大牛 看到此文只有膜拜~ 终于开坛子了。。。 想不到这么多天没得上来,一可以上来就看到这么精彩的文章