smallyou93 发表于 2009-12-28 16:11

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修复之.脱壳完成

zapline 发表于 2009-12-28 16:13

:@靠 真难脱

Squn 发表于 2009-12-28 16:16

膜拜。 向来不会脱壳。。。。

Hmily 发表于 2009-12-28 16:18

徐ma又祸害孩子了,文章分析的很好!

小黑冰 发表于 2009-12-28 16:20

跟楼主看齐```学习```膜拜```

kongzi 发表于 2009-12-28 16:33

丫的,bslz+膜拜

什么也不是 发表于 2009-12-28 17:41

:$qqq
膜拜 晕4大牛

小糊涂虫 发表于 2009-12-28 18:34

看到此文只有膜拜~

2051314 发表于 2009-12-28 18:36

终于开坛子了。。。

幻覺 发表于 2009-12-28 19:42

想不到这么多天没得上来,一可以上来就看到这么精彩的文章
页: [1] 2 3
查看完整版本: TPPpack脱壳的一点记录