如果我从C ++代码中调用Win32 API函数,如以下示例所示:
fSuccess = WriteFile(
hPipe, // pipe handle
lpvMessage, // message
cbToWrite, // message length
&cbWritten, // bytes written
NULL); // not overlapped
然后Visual C ++编译器会将这些调用转换为对数据段中导入地址表(IAT)的绝对引用。 IAT本身将包含到包含该Win32 API函数的外部库的实际绝对地址。在上面的
WriteFile
函数示例中,此外部库为kernel32.dll
。如果我在运行时修改IAT中的一个条目,使其指向不同的库/函数,那么我的原始C ++中对该函数的所有调用也将更改。我只希望其中一些可以更改。或者为了使某个Win32 API函数甚至根本不出现在IAT中,而是由代码段直接引用它。
我怎样才能做到这一点?我能以某种方式强制编译器在代码段中包含对外部库的直接绝对引用,而不是通过IAT间接引用吗?
最佳答案
我只希望其中一些可以更改。或者为了使某个Win32 API函数甚至根本不出现在IAT中,而是由代码段直接引用它。
我怎样才能做到这一点?
为此,您必须在运行时使用LoadLibrary()
/ GetModuleHandle()
和GetProcAddress()
(或编译器的延迟加载包装程序,如果有的话)动态访问函数,而不是在以下位置静态链接到函数编译时。例如:
typedef BOOL (WINAPI *LPFN_WRITEFILE)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
LPFN_WRITEFILE lpWriteFile = (LPFN_WRITEFILE) GetProcAddress(GetModuleHandle("kernel32"), "WriteFile");
fSuccess = lpWriteFile(
hPipe, // pipe handle
lpvMessage, // message
cbToWrite, // message length
&cbWritten, // bytes written
NULL);