假设我有一个函数
inline PVOID CallFunc(PVOID Dll, PCHAR Name, INT nArgs, ...)
{
va_list Args;
va_start(Args, nArgs);
ULONG_PTR *Params = (ULONG_PTR *) malloc(nArgs);
for(INT n = 0; n < nArgs; ++n)
Params[n] = va_arg(Args, ULONG_PTR);
PVOID Func = (PVOID)GetProcAddress(Dll, Name);
typedef PVOID (WINAPI *MyFunc)(ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR,
ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR,
ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR);
MyFunc FuncPtr = (MyFunc)Func;
va_end(Args);
return ERROR;
}
基本上我要做的是制作一个函数,该函数可以动态调用,以通过函数名称在给定的DLL偏移中调用任何其他函数。我知道以前通过模板实现了此类实现,但是人们制作了多个模板来采用多个参数。我试图弄清楚该怎么做的就是通过我想要的多个参数,并相应地填写功能。
假设我正在打电话给MessageBoxA
例如,我将以下内容传递给此功能
CallFunc(User32Address, "MessageBoxA", 4, (ULONG_PTR) NULL, (ULONG_PTR) "World", (ULONG_PTR) "Hello", (ULONG_PTR) NULL);
现在,您会发现我已经在函数本身中的Typedef中初始化了一个函数类型定义。我这样做是因为我不知道该函数本身将采用多少参数,如果我知道,我将能够仅分配我需要的参数数量来初始化Typedef(在这种情况下为4)。
我的问题是,在MessageBoxA
通过GetProcAddress(Dll, Name)
加载并分配给PVOID Function
之后。使用Function
中的函数偏移,我如何确定MessageBoxA
包含4个参数,然后如何动态初始化Typedef;知道我只需要将4个ulong_ptr参数分配给 FuncPtr
?
我理解这个问题可能会使某些问题感到困惑,但是请告诉我是否应该澄清它的任何方面。
它是可能的,但很难做到。您所要求的不能在直的C 中完成,您必须下降到组装层。假设您正在使用32位X86(64位x64更难处理),则必须要么必须:
-
PUSH
CallFunc()
的每个参数值在呼叫堆栈上的重复,然后CALL
尖锐的函数,然后最终从呼叫堆栈中删除重复参数,如果指向函数使用cdecl
(或类似的)呼叫约定,要求呼叫者执行呼叫堆栈清理(您必须提前知道)。 -
将
CallFunc()
只需JMP
即可进入指向函数,因此它读取CallFunc()
参数,就好像它们是其自己的参数一样,然后将其RET
URN直接放在称为CallFunc()
的代码中。但是,CallFunc()
必须使用与尖头函数完全相同的呼叫约定,以使其起作用。因此,您需要具有多个CallFunc()
样式功能以进行不同的呼叫约定。