特别是在不是以标准功能序言开头的情况下。
例如:
我发现了以下示例,该示例以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 楼
即使包装程序将启动代码分成许多小段,并有大量跳转并“返回”到推入/交换的地址等,魔术常数有时也会有所帮助。其中一个示例是用于VC ++启动代码的__security_init_cookie。 ,与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。签名属性是一个常量,用于修改驻留在寄存器中的常量(在基本块内部,不涉及重定位),所有自重编译器都将对此进行优化。
评论
什么是内存地址?最后一个JMP是转到原始内存页面,第一个映射到的页面还是第二个(通常是最终的)页面?如果在分配了2个内存之后,您发现进入最后分配的页面的JMP,通常是您跳到了OEP(这是转储和修复解压缩版本的好时机)。