我经常看到这样格式化的代码:

push arg
push arg
(...)
mov ecx, arg
call function


如果需要在Assembly中调用该函数,就可以了。但是由于我知道如何始终如一地获得这些函数的基础,因此为了组织和简化起见,我想在DLL中使用typedef来调用这些函数。

问题是我不知道如何使用ecx进行呼叫以传递数据。除非我弄错了,否则func(arg,arg)将始终组装为两次按下和一次调用。如果我不使用ecx,则函数会崩溃,因为它是指向对象的指针,因此必须如此。如果没有内联汇编,有什么方法可以避免吗?

#1 楼

您可以像这样键入它的定义:

// typedef <return-type>(__thiscall* <type-name>)(<ecx>, <stack-1>, <stack-2>);
typedef int(__thiscall* tSomeFunc)(int thisPtr, int arg1, int arg2);
tSomeFunc func = (tSomeFunc) 0xBAADC0DE;

// this is how you call it
func(/* this */ 0x123, /* arg1 */ 1, /* arg2 */ arg2);


或直接调用它:

((int(__thiscall*)(int, int, int)) 0xDEADBABE)(/* this */ 0x123, 1, 2);


您的调用约定似乎是__thiscall,将this指针存储到ecx中,然后将其余args推入堆栈。

评论


谢谢,这太完美了。我一直想知道C ++如何神奇地分辨函数是使用ret还是retn%d,这也解释了这一点

–Lupe
15年8月31日,0:50

@AcidShout,很好的工作,在您的答案中包括typedef风格和直接调用风格!

–詹森·格夫纳(Jason Geffner)
15年8月31日在13:58