拜读了 Lenus 的<<用内存断点找OEP>>(本版置顶帖,看雪老大的新手教程),对文中unpackme的一点疑惑
大体概述一下2次内存断点法,加壳的程序必定要经过解压过程才能够执行,所以我们就在code段解压缩完毕之后,利用对code段的内存访问断点把oep拦下来,而程序在内存中解压缩的过程是属于内存写入,过程往往是先解压缩code段,接着data段(当然也可能是其他段),所以我们在code段之后的段下内存写入断点,就可以停在code段解压完毕的一刻,此时再对code段下内存访问断点,很容易就能找到oep.
我对文中unpackme的脱壳过程,与作者不同,我忽略了所有异常.对data段下内存写入断点,停在这里:
00392712 F3:A4 rep movs byte ptr es:[edi], byte ptr>
00392714 5E pop esi
00392715 53 push ebx
00392716 68 00800000 push 8000
0039271B 6A 00 push 0
0039271D 56 push esi
0039271E FF95 00070000 call [ebp+700]
00392724 5B pop ebx
00392725 83C3 0C add ebx, 0C
00392728 ^ EB B3 jmp short 003926DD
继续对code段下内存访问断点,停在这里:
00392855 8907 mov [edi], eax ; SHELL32.DragFinish 这里有函数说明,多按几次F9可以看到更多函数,我的理解是code段还在解压过程中
00392857 5A pop edx
00392858 0FB642 FF movzx eax, byte ptr [edx-1]
0039285C 03D0 add edx, eax
0039285E 42 inc edx
0039285F 83C7 04 add edi, 4
00392862 59 pop ecx
00392863 ^ E2 A9 loopd short 0039280E
00392865 ^ E9 63FFFFFF jmp 003927CD
0039286A 8BB5 93060000 mov esi, [ebp+693]
我删除了code段内存断点,用F8单步跟踪,发现写入一个函数的完整工程需要执行一个loop,也就是
00392863 ^ E2 A9 loopd short 0039280E
00392865 ^ E9 63FFFFFF jmp 003927CD
这两个跳,那现在就F4到
0039286A 8BB5 93060000 mov esi, [ebp+693]
跳出这个循环
之后F8单步跟踪一小会儿,就发现了
0039298C - FFE0 jmp eax ; unpackme.004010CC
0039298E 50 push eax
0039298F 60 pushad
众所周知4010CC是记事本的OEP,但是跟踪过去发现
004010CC FFD7 call edi ; unpackme.004010CE
004010CE 58 pop eax
004010CF 83EC 44 sub esp, 44
004010D2 56 push esi
004010D3 90 nop
004010D4 E8 B518F9FF call 0039298E
这样的OEP的代码我不认识,如果不是事先知道4010CC是记事本的OEP那单步跟踪很可能就继续往下,虽然比较明显的一个跨段跳之后可能会怀疑.所以这里就有一个疑问,高手们,你们如何判断OEP的特征的?
Lenus说代码段的第一次内存执行访问,我不是很理解,希望有高手赐教.还有,看了不少关于stolen code的帖子,恕我愚钝,还是不知道怎么判断哪个是OEP入口代码是不是被偷换了.
[培训]科锐逆向工程师培训第53期2025年7月8日开班!