达到 OEP 的指标是什么?

逆向工程 部件 开箱 操作
2021-07-07 10:07:44

对我来说,当我试图手动打开它时,有时很难确定我是否已经达到了 OEP。特别是在它不以标准函数序言开头的情况下。

例如:我发现了以下示例,该示例以 PUSHAD 指令开头。我逐步完成代码的内容,直到到达 POPAD。几行之后,我看到了一个 JMP 指令,它导致一个 CALL 指令和一个函数被调用。跳过该函数后,在下一行中,还有另一条 JMP 指令在此处结束:

    PUSH 58
    PUSH unbr002.014A22F8
    CALL unbr002.013CBD40#
    XOR ESI, ESI
    MOV DWORD PTR SS:[EBP-4], ESI
    LEA EAX, DWORD PTR SS:[EBP-68]
    PUSH EAX
    CALL DWORD PTR DS:[141409C]          kernel32.GetStartupInfoA
    ....
    ....
    ....
    ....
    POP ECX
    CALL DWORD PTR DS:[1414278]          kernel32.GetCommandLineA
    ....

所以,我在某处读到了“GetCommandLineA – 表明您已经到达了使用 Visual Studio 6 编译的程序的入口点”

我问自己是否有一份指标清单可以知道一个人是否达到了 OEP。

最好的祝福,

1个回答

即使打包程序将启动代码拆分成小片段,并大量跳转并“返回”到推送/交换地址等,魔术常量有时也会有所帮助。

一个这样的例子是 __security_init_cookie 用于 VC++ 启动代码,它与 32 位代码中的常量 0BB40E64Fh 和 64 位代码中的 2B992DDFA232h 相关。该函数通常是同时写入 __security_cookie 和 __security_cookie_complement 的唯一代码:

.text:00401F06 020           mov     edi, 0BB40E64Eh
; ... stuff involving GetCurrentThreadId(), GetCurrentProcessId() etc. pp. ...
.text:00401F79 020           mov     ___security_cookie, ecx
.text:00401F7F 020           not     ecx
.text:00401F81 020           mov     ___security_cookie_complement, ecx
...
.data:00404000     ___security_cookie dd 0BB40E64Eh
.data:00404004     ___security_cookie_complement dd 44BF19B1h

___security_cookie 的位置也很容易识别,因为它具有独特的作用,独立于魔法常量。它会直接引导您进入 __security_init_cookie(),它通常是在 OEP 中调用的第一个函数,甚至在 __tmainCRTStartup() 之前。相比之下,导入的函数(CRT dll、Windows API)偶尔会被打乱,因此难以识别。

有一些垃圾软件可以通过像这样拆分它们来自动混淆恒定负载:

1441285DB           mov     edx, 0E6FFA20Fh                           
...
1441285E3           lea     edx, [rdx+19005DF2h]                      

在这个例子中,混淆常数当然是 1。其他拆分也是可能的,例如涉及算术或位操作而不是 LEA。签名属性是一个常量,修改驻留在寄存器中的常量(在基本块内,不涉及重定位),所有自尊的编译器都会优化掉它。