【问题标题】:How do I stop ESP from being corrupted in a __fastcall?如何阻止 ESP 在 __fastcall 中损坏?
【发布时间】:2012-01-12 11:36:57
【问题描述】:

我正在尝试在汇编中编写一个函数,将一块内存设置为指定值,就像 memset(),但是,当我从堆栈中取出第三个参数时(它使用 fastcall 调用约定),寄存器 ECX 得到一些乱码。

通过使用内联汇编将代码放入 Visual Studio,我发现调用函数时 ESP 发生了显着变化。 前两个参数被放入 ECX 和 EDX 没有任何问题,只是第三个引起了麻烦。

我知道代码有效,当我在 VS 中调试时手动设置寄存器中的值时,内存块填充了正确的值。

我对汇编比较陌生,所以我的代码可能有点狡猾,但是有人知道如何解决这个问题吗?

代码如下:

#ifdef __GNUC__ #define __fastcall __attribute__((fastcall)) // 'Cause I'm a M$ fanboy #endif void __fastcall memset(void *pDest, int iValue, int iSize) { __asm { ; Assume the pointer to the memory is stored in ECX ; Assume the value is stored in EDX ; Assume the size of the block is stored on the stack mov eax, esi ; Put ESI somewhere it won't be touched (I think) mov esi, ecx ; Move the address of the memory into ESI xor ecx, ecx ; Zero ECX pop ecx ; Get the size of the block into ECX. ECX is our loop counter memset_count: cmp ecx, 0 ; If we are at the end of the block, jz memset_return ; Jump to return mov [esi], edx ; Move our value into the memory inc esi ; Otherwise, increment out position in the memory dec ecx ; Decrement out counter jmp memset_count ; Start again memset_return: mov esi, eax ; Restore ESI add esp, 4 ; Remove our third argument from the stack ret } } #define ret return int main(int argc, char **argv) { char szText[3]; /* __asm { push 3 mov edx, 65 lea ecx, szText2 call memset } */ memset(&szText, 'A', 3); ret 42; }

【问题讨论】:

  • #define ret return?你能有多懒?
  • 您可以在 VS 中启用反汇编视图,看看它对您的代码有何影响。

标签: assembly stack corruption stack-pointer


【解决方案1】:

被调用代码堆栈上的第一件事将是调用的返回地址。第二件事将是第一个参数。

为避免更改 ESP 并解决“弹出错误内容”问题,请尝试使用“mov ecx,[esp+4]”(而不是“pop ecx”)。

【讨论】:

  • 添加 __declspec(naked) 后,mov ecx, [esp+4] 完美运行。谢谢。
【解决方案2】:

问题在于 this 在函数中,编译器已经弹出了一些变量。 gcc有引用变量的方法,我不知道MSVC

【讨论】:

  • 我不知道为什么我忽略了这一点 - 无法知道在序言/尾声中可能会或可能不会对编译器造成多少意想不到的混乱。
  • 这让我想起了我忘记将它声明为 __declspec(naked)。一旦这样做了,编译器就不再在函数执行前后搞砸了。
猜你喜欢
  • 1970-01-01
  • 2014-02-17
  • 2019-06-15
  • 2011-01-15
  • 1970-01-01
  • 2021-09-14
  • 2020-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多