c++ - 可移植可执行文件是否可以在代码段中直接绝对引用外部库,而不是通过 IAT?

标签 c++ c winapi portable-executable

如果我从 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 进行间接引用?

最佳答案

I would like only some of them to change. Or to make it such that a certain Win32 API function does not even appear in the IAT at all, but it is directly referenced by the code segment.

How can I do that?

为此,您必须使用 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);          

关于c++ - 可移植可执行文件是否可以在代码段中直接绝对引用外部库,而不是通过 IAT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36050085/

相关文章:

c++ - 以GPU(OpenGL)为目标的Halide-基准测试并使用HalideRuntimeOpenGL.h

c++ - g++ 对 -Ofast 做了哪些额外的优化?

c++ - 删除循环链表c++中的节点?

c - sizeof(int) 是 4 个字节,但只写了两个

winapi - 使用 PowerShell : "Exception calling Recycle" 回收 IIS 应用程序池

c++ - InvalidateRect 和 RedrawWindow 的区别

c++ - 多级继承错误 "cout does not name a type"

python -/usr/bin/ld : cannot find -lpython-dev on Ubuntu. 使用PyObject编译C程序

c - OSDev:为什么我的内存分配功能突然在AHCI初始化功能中停止工作?

java - 使用 JNI 使用 Windows 命名管道的 Java 程序的 IPC