朱朱你堕落了 发表于 2024-3-8 16:40

如何到达此壳的oep?

一个非常老的壳,论坛脱壳练习用的例子,只能在XP上运行,请在xp虚拟机上测试。
求助以下问题:
1
如图:
https://im.gurl.eu.org/file/3103c5244311a387a4c77.png

“在访问上设置中断(F2)”和下方的那个“设置内存访问断点”这两者有什么区别?

2
如何到达OEP?使用什么方法,并说明为什么要使用这个方法。
3
以本例这个壳来说,如何分析它到达OEP,大佬们都是如何下手分析的?

链接:https://www.123pan.com/s/YL29-ggVOh.html

谢谢各位大佬。


solly 发表于 2024-3-8 16:40

本帖最后由 solly 于 2024-3-9 17:33 编辑

朱朱你堕落了 发表于 2024-3-9 15:20
solly老师,怎么分析出来是分段解密的?
1
“先在0x00401200, 0x00401400, 0x00401800, 0x00401A00 下4 ...
1、执行一段代码就可看出来,大概就是解密一段,执行一段的意思,先解密一部分壳代码,再执行这段代码解密另一部分代码。。。。。。最后才解密crackme的代码。
2、因为代码段在0x00401000~0x00402000之间,所以比较均匀地选4个地址呀,这跟那个猜数字游戏一个意思(硬件断点最多也只能选4个)。后面选3个也是一个意思,选几个随意,范围小了就少选一点,只要能最后确定最终解密点就可以了,这样操作跟踪量小很多。
3、选地址就是为了缩小并最终确定范围,怎么选没规定,一般是均匀分布。
4、这种操作并不是适于所有壳,每种壳都有相应的不同办法。

solly 发表于 2024-3-8 20:10

本帖最后由 solly 于 2024-3-8 20:22 编辑

我是在x32dbg中直接运行,然后在 ExitProcess 下断点,然后关闭crackme,断在ExitProcess,然后在堆栈中回溯,就可定位msvcrt的exit()函数调用处(0x00401838),往上走一点就是OEP:0x00401700,填好OEP,点“IAT自动搜索”,当询问普通和高级搜索结果不一致时,选择高级搜索就可找到IAT,再点“获取导入”就有了。然后就是dump出来修复一下即可:UnPackMe4_dump_SCY.exe,这个就是可运行的了。

朱朱你堕落了 发表于 2024-3-8 20:37

solly 发表于 2024-3-8 20:10
我是在x32dbg中直接运行,然后在 ExitProcess 下断点,然后关闭crackme,断在ExitProcess,然后在堆栈中回 ...

经测试,大佬的方法可行,只是为什么要下ExitProcess断点?而不是其他API函数呢?

solly 发表于 2024-3-8 21:09

其它的不好激活呀,退出是最好激活的,并且Vc的exit()调用前面就是调用main(),再往前是C的初始化,再往往前就是OEP了。

朱朱你堕落了 发表于 2024-3-9 08:07

solly 发表于 2024-3-8 21:09
其它的不好激活呀,退出是最好激活的,并且Vc的exit()调用前面就是调用main(),再往前是C的初始化,再往往 ...

solly老师是每年春节的出题者,C++编程水平自然了得,从VC程序自身特点特殊函数下手来找OEP,是个巧妙的方法,不过,如果这个程序本身是VB或delphi程序,那么ExitProcess这种方法是否还行?

如果不行的话,那么只能针对壳来搞了,我也想知道如何从壳的角度来到达OEP。

solly 发表于 2024-3-9 10:06

本帖最后由 solly 于 2024-3-9 10:54 编辑

这是一个分段解密的壳,看程序节信息,只有0x00401000~0x00402000之间是可执行,所以在先在0x00401200, 0x00401400, 0x00401800, 0x00401A00 下4个硬件写入断点,然后执行crackme,最终前面3个会断下来,最后一个没有断下来,表示没有用到,所以确定解密过程在 0x00401800~00401A00之间结束,在这个区间内继续下3个硬件断点再来一次:如 0x00401880, 0x00401900, 0x00401980,最后又是前2个断下来了,再就是在 0x00401900~0x00401980内下断点了,可以看到这个区间后面都是0了,应该是代码段要结束了,所以在最后一个非0字节下一个断点吧,然后执行,断在如下处:
004093F0 | C00A 03                  | ROR BYTE PTR DS:,3               |
004093F3 | 87DD                     | XCHG EBP,EBX                            |
004093F5 | 56                         | PUSH ESI                              |
然后F7一路逢call必进,到下面这里:
0040958D | 40                         | INC EAX                                 |
0040958E | 60                         | PUSHAD                                  |
0040958F | 56                         | PUSH ESI                              |
00409590 | 83EC FC                  | SUB ESP,FFFFFFFC                        |
00409593 | 83C4 20                  | ADD ESP,20                              |
00409596 | 48                         | DEC EAX                                 |
00409597 | 83C2 01                  | ADD EDX,1                               |
0040959A | 83C1 FF                  | ADD ECX,FFFFFFFF                        |
0040959D | 75 8B                      | JNE unpackme4.40952A                  |
这里是恢复 IAT 了,一个循环,EAX++,ECX--,在下面下断点:
0040959F | 68 2386F7DA                | PUSH DAF78623                           |
F9执行。断下后又是一路F7,来到这里:
00409676 | 40                         | INC EAX                                 |
00409677 | 48                         | DEC EAX                                 |
00409678 | 83C4 20                  | ADD ESP,20                              |
0040967B | 48                         | DEC EAX                                 |
0040967C | C00A 04                  | ROR BYTE PTR DS:,4               |
0040967F | E8 01000000                | CALL unpackme4.409685                   |
00409684 | 5B                         | POP EBX                                 |
00409685 | E8 00000000                | CALL unpackme4.40968A                   | call $0
0040968A | C70424 2B1BEB32            | MOV DWORD PTR SS:,32EB1B2B         | :&L"ALLUSERSPROFILE=C:\\Documents and Settings\\All Users"
00409691 | 81C0 92CD3C56            | ADD EAX,563CCD92                        |
00409697 | 81E8 92CD3C56            | SUB EAX,563CCD92                        |
0040969D | 83EC FC                  | SUB ESP,FFFFFFFC                        |
004096A0 | 83EC FC                  | SUB ESP,FFFFFFFC                        |
004096A3 | 83C2 01                  | ADD EDX,1                               |
004096A6 | 83C1 FF                  | ADD ECX,FFFFFFFF                        |
004096A9 | 0F85 74FFFFFF            | JNE unpackme4.409623                  |
004096AF | 68 F864F7B8                | PUSH B8F764F8                           |
又是一个循环,EAX++,ECX--,又在循环后下面F2断点,F9执行,断下后又是一路F7,逢call必进,来到这里:
004097F0 | C70424 2DC2EB67            | MOV DWORD PTR SS:,67EBC22D         | :&L"ALLUSERSPROFILE=C:\\Documents and Settings\\All Users"
004097F7 | 83EC FC                  | SUB ESP,FFFFFFFC                        |
004097FA | 4B                         | DEC EBX                                 |
004097FB | 81EA 38A9741A            | SUB EDX,1A74A938                        |
00409801 | 83EA FF                  | SUB EDX,FFFFFFFF                        |
00409804 | 83C1 FF                  | ADD ECX,FFFFFFFF                        |
00409807 | 85C9                     | TEST ECX,ECX                            |
00409809 | 0F85 36FFFFFF            | JNE unpackme4.409745                  |
0040980F | 57                         | PUSH EDI                              |
00409810 | 56                         | PUSH ESI                              |
00409811 | E8 D8000000                | CALL unpackme4.4098EE                   |
00409816 | A1 58214000                | MOV EAX,DWORD PTR DS:         |
0040981B | C3                         | RET                                     |
0040981C | 90                         | NOP                                     |
最后一个循环了吧,在循环后面(0x0040980F)下 F2 断点,F9执行,断下后,F7进入 call 0x004098EE:
004098EE | 5E                         | POP ESI                                 |
004098EF | BF 00104000                | MOV EDI,<unpackme4.EntryPoint>          | edi:EntryPoint
004098F4 | B9 36000000                | MOV ECX,36                              | 36:'6'
004098F9 | F3:A5                      | REP MOVSD                               |
004098FB | 5E                         | POP ESI                                 |
004098FC | 5F                         | POP EDI                                 | edi:EntryPoint
这里进行壳的入口代码恢复为crackme的原始代码。F8一路执行,来到这里:
0040990F | 3E:8B45 0C               | MOV EAX,DWORD PTR DS:            |
00409913 | 05 00004000                | ADD EAX,unpackme4.400000                |
00409918 | 50                         | PUSH EAX                              |
00409919 | FFD7                     | CALL EDI                              |
0040991B | 83EC 04                  | SUB ESP,4                               |
0040991E | 50                         | PUSH EAX                              |
0040991F | 33DB                     | XOR EBX,EBX                           |
00409921 | 8B45 00                  | MOV EAX,DWORD PTR SS:            |
00409924 | 8B8418 00004000            | MOV EAX,DWORD PTR DS:   |
0040992B | A9 00000080                | TEST EAX,80000000                     |
00409930 | 74 07                      | JE unpackme4.409939                     |
00409932 | 25 FFFF0000                | AND EAX,FFFF                            |
00409937 | EB 09                      | JMP unpackme4.409942                  |
00409939 | 85C0                     | TEST EAX,EAX                            |
0040993B | 74 1D                      | JE unpackme4.40995A                     |
0040993D | 05 02004000                | ADD EAX,unpackme4.400002                |
00409942 | 894424 04                  | MOV DWORD PTR SS:,EAX            |
00409946 | FFD6                     | CALL ESI                              |
00409948 | 83EC 08                  | SUB ESP,8                               |
0040994B | 8B4D 10                  | MOV ECX,DWORD PTR SS:         |
0040994E | 898419 00004000            | MOV DWORD PTR DS:,EAX   |
00409955 | 83C3 04                  | ADD EBX,4                               |
00409958 | EB C7                      | JMP unpackme4.409921                  |
0040995A | 83C4 08                  | ADD ESP,8                               |
0040995D | 83C5 14                  | ADD EBP,14                              |
00409960 | 837D 10 00               | CMP DWORD PTR SS:,0             |
00409964 | 75 A9                      | JNE unpackme4.40990F                  |
这里是加载DLL的导出函数的入口地址了。在大循环后面(0x00409966)下 F2 断点,F9执行,再一路 F7 来到这里:
00409995 | EB 05                      | JMP unpackme4.40999C                  |
00409997 | 41                         | INC ECX                                 | ecx:"姍@"
00409998 | F6F9                     | IDIV CL                                 |
0040999A | 2F                         | DAS                                     |
0040999B | 55                         | PUSH EBP                              |
0040999C | 83EC FC                  | SUB ESP,FFFFFFFC                        |
0040999F | 83EC E0                  | SUB ESP,FFFFFFE0                        |
004099A2 | C3                         | RET                                     |
一路F8, ret 后到这里:
0040998A | 60                         | PUSHAD                                  |
0040998B | E8 05000000                | CALL unpackme4.409995                   |
00409990 | 83B40D 6A18EB05 41         | XOR DWORD PTR SS:,41   |
然后还是一路 F7 ,ret 和call几次后,就会到这里:
00407000 | 0F31                     | RDTSC                                 |
00407002 | 33C9                     | XOR ECX,ECX                           |
00407004 | 03C8                     | ADD ECX,EAX                           |
00407006 | EB 58                      | JMP unpackme4.407060                  |
这里是时钟反调试,后面还有一个 RDTSC 。还是一路 F7 到这里:
00407060 | 0F31                     | RDTSC                                 |
00407062 | 2BC1                     | SUB EAX,ECX                           |
00407064 | 3D FF0F0000                | CMP EAX,FFF                           |
00407069 | 0F83 A3000000            | JAE unpackme4.407112                  |
0040706F | E9 84000000                | JMP unpackme4.4070F8                  |
这里的 JAE跳转是反调试用的,不能跳转,下面的那个 JMP 才是正确的线路。执行这个 JMP 0x004070F8,来到这里:
004070F8 | B8 00174000                | MOV EAX,unpackme4.401700                |
004070FD | 33F6                     | XOR ESI,ESI                           | esi:&L"ALLUSERSPROFILE=C:\\Documents and Settings\\All Users"
004070FF | 33DB                     | XOR EBX,EBX                           |
00407101 | 8A1C06                     | MOV BL,BYTE PTR DS:            |
00407104 | 80EB FF                  | SUB BL,FF                               |
00407107 | 881C06                     | MOV BYTE PTR DS:,BL            |
0040710A | 46                         | INC ESI                                 | esi:&L"ALLUSERSPROFILE=C:\\Documents and Settings\\All Users"
0040710B | 83FE 32                  | CMP ESI,32                              | esi:&L"ALLUSERSPROFILE=C:\\Documents and Settings\\All Users", 32:'2'
0040710E | 75 F1                      | JNE unpackme4.407101                  |
00407110 | FFE0                     | JMP EAX                                 |
就可以看到 OEP 了。执行最后那条指令:
00407110 | FFE0                     | JMP EAX                                 |
你就到 OEP 去了。


另外,delphi 和 VB 的入口也很好找的,特征都很明显。

冥界3大法王 发表于 2024-3-9 12:34

@solly
分析的太好了,有点有据,充分暴露了各个阶段该提取的程序特性。
强烈建议加精华。

朱朱你堕落了 发表于 2024-3-9 15:20

solly 发表于 2024-3-9 10:06
这是一个分段解密的壳,看程序节信息,只有0x00401000~0x00402000之间是可执行,所以在先在0x00401200, 0x0 ...

solly老师,怎么分析出来是分段解密的?
1
“先在0x00401200, 0x00401400, 0x00401800, 0x00401A00 下4个硬件写入断点”
这四个地址是程序中固定的,还是自己随便定义的,只是为了方便自己确定是哪些段解密。

如果是自己随便定义,那么是否我也可以这么设置,如:
00401100, 0x00401500, 0x00401700, 0x00401B00,只要分成几段,缩小范围就行了?

2
同样,这三个“0x00401880, 0x00401900, 0x00401980”是怎么来的?也是和上面一样吗?
页: [1]
查看完整版本: 如何到达此壳的oep?