我目前正在学习装配,因此我正在尝试一些简单的破解或只是在装配中查看不同的程序。但现在我偶然发现了一个非常奇怪的案例,我无法理解。 代码如下所示:
LEA, EDX, [406349]
PUSH EDX
CALL <JMP.&kernel32.lstrlenA>
真的没什么可怕的。在我的理解中,字符串的地址被加载到EDX寄存器中,然后作为strlen
的参数被压入堆栈。我可以在OllyDbg中遵循这个过程。
奇怪的事情发生在函数调用之后。 EDX
中的地址突然增加1个字节,因此指向字符串的第二个字符。
为什么会这样?
答案 0 :(得分:3)
该应用程序是Windows / x86的32位应用程序,因此它使用stdcall调用约定来调用系统函数。来自Wikipedia page:
<强> STDCALL 强>
stdcall调用约定是Pascal调用的变体 被呼叫者负责清理的惯例 堆栈,但参数从右到左推入堆栈 顺序,如_cdecl调用约定。 注册EAX,ECX和 指定EDX在函数内使用。返回值为 存储在EAX寄存器中。
stdcall是Microsoft Win32 API的标准调用约定 以及Open Watcom C ++。
很可能EDX
似乎在函数内部递增,因为函数将堆栈中的参数读入EDX
,然后递增它以便对齐它以便然后读取字符一次32位。
但修改的原因并不重要:允许函数修改EDX
(和ECX
)。它还可以在返回时包含与原始值无关的任意值,并且该函数仍然会尊重ABI。