我有一些二进制数据,其中包含一堆函数并想调用其中一个。我知道这些函数的签名以及相对于文件开头的偏移量。调用约定是默认的:__cdecl
. 该文件已加载到具有执行权限的内存页面中。
例如(A
, B
,C
是某些类型)
void myFunction (A *arg1, B arg2, C arg3); // Signature
int myOffset = 0x42; // Offset
我怎样才能指定myOffset
指向myFunction
?
我有一些二进制数据,其中包含一堆函数并想调用其中一个。我知道这些函数的签名以及相对于文件开头的偏移量。调用约定是默认的:__cdecl
. 该文件已加载到具有执行权限的内存页面中。
例如(A
, B
,C
是某些类型)
void myFunction (A *arg1, B arg2, C arg3); // Signature
int myOffset = 0x42; // Offset
我怎样才能指定myOffset
指向myFunction
?
// define a function pointer
typedef __cdecl void (*your_function) (A *arg1, B arg2, C arg3);
your_function ftr;
char * memory = 0x123456; // base segment address
fptr = (your_function)(memory + 0x42); //calculate memory address
(*ftpr)(a,b,b); // call function
我不太确定你在问什么。我假设您尝试声明一个函数指针,并将一个函数指针分配给某个任意地址。
要声明一个函数指针,
void (*p)(A*,B,C);
要分配它,
p = (void (*)(A*,B,C)))0x42;
要调用该函数,
p(a,b,c) or (*p)(a,b,c);
对于问题本身:您只需在加载二进制文件的内存中添加地址。即,如果您将二进制文件加载到地址myLoadAddress
,只需将其添加到myOffset
. 但是,这不会让您轻松调用该函数。如果你想这样做,你应该把它当作一个库文件(如果它实际上是一个库文件,检查系统函数以在 Windows 上加载像LoadLibrary这样的库,然后使用GetProcAddress来检索指向函数的指针)。
// create a type for your function signature
typedef void (*myFunc)(A *arg1, B arg2, C arg3);
// create a pointer to your function
myFunc myFuncPointer;
// set the address of the function in memory
myFuncPointer = myLoadAddress + myOffset;
// invoke function
myFuncPointer(A, B, C);
加载 DLL 时,您使用 LoadLibrary 加载它,然后使用 GetProcAddress 并将返回的地址类型转换为函数指针 - 即myFuncPointer = (myFunc)GetProcAddress(hmodule, "myFunc");
在示例中。
在 POSIX 上,它的工作方式几乎相同,但功能略有不同:用于dlopen
加载动态库和dlsym
检索符号。Programming Library Howto对此进行了更详细的描述,或查看dlopen和dlsym的手册页。基础是一样的。
( (void(*)(A*,B,C))0x42 )(a,b,c);
或类似的东西。第一次得到它总是有麻烦。那就是如果我理解你的问题,无论如何。