【发布时间】:2020-06-04 16:39:35
【问题描述】:
我一直在尝试挂钩一个主要由编译器优化的函数。它在调用之前初始化 EAX,并将其返回值存储在 EAX 中。
这是一些代码:
mov eax,dword ptr ds:[0xA6DD08]
push 0x3DC
add eax,0x800
call 0x48A2B4
mov esi,eax
起初,0xA6DD08 是指向内存中某些数据的指针,但是一旦添加 0x800,EAX 只指向 零 的值,但接下来的几个 DWORD(s)存储指针或数据数组的指针。该函数本身的目的是查找并返回一个特定对象,该对象的 DWORD 变量等于给定值 0x3DC。
当使用 __asm 从我的 dll 调用函数时,它可以完美运行,但我正在尝试用 c++ 编写它,类似于
Class1* pClass = reinterpret_cast<Class1*(__stdcall*)(DWORD)>(0x48A2B4)(988);
我相信从我读到的只有 __stdcall 使用 EAX 来存储它的返回值,这就是我选择 __stdcall 调用约定的原因。我不明白的是调用函数之前 EAX 的目的。
【问题讨论】:
-
1) 为什么这个问题被标记为“C++”? 2) 为什么你想用内联 ASM 写东西,而不是用更高级的语言表达你想要的东西,让编译器为 ASM 操心? - 就生成最佳 ASM 而言,您很少能超越优化编译器(即使可以,在任何实际应用程序中,性能方面通常都无关紧要)。
-
我不想做编译器所做的事情,我只是想用我的 DLL 中的 c++ 代码正确地挂钩函数。
-
你检查过函数本身的目标代码吗?
EAX的期望是什么? -
我做了,正如我所说,它只是指向内存中的一个位置,它的值只是零。但是它自己的函数在 EAX 之后使用数据,我认为它更像是指针指针或指针数组。基本上功能目的是在列表或smth中查找对象
-
对于 32 位编译器来说,期望
eax、edx、ecx中的前几个参数并不罕见,假设它们适合 fast 调用约定。
标签: c++ assembly visual-c++ x86 calling-convention