繁体   English   中英

如何在 Microsoft Visual Studio C/C++ 编译器中关闭与位置无关的代码编译?

[英]How to turn off position-independent code compilation in Microsoft Visual Studio C/C++ compiler?

我想知道是否可以关闭这个与位置无关的代码来改变汇编call指令,例如

call [rip+0x1234] // this address is relative to the current code position

类似于

call qword ptr[0x12345678] // this address is absolute and doesn't crash the program

这样做的原因是我通过从 WinAPI 调用CreateRemoteThread创建了一个远程线程,并且我希望能够通过输入普通代码来调用其他 WinAPI 函数,但是现在由于 PIC 是打开的,每次我在里面调用任何 ZC1C4DF145268E68A98远程线程我遇到访问冲突并且进程崩溃。 还值得一提的是,我知道每个进程都有不同的导入函数地址,但我只是从kernel32.dll调用函数,据我所知,它在每个进程中加载到相同的绝对地址,所以这不是问题.

是否有一些宏或编译器选项? 我还想更改该行为仅用于编译一个文件,而不是解决方案中的所有文件。

当然,我的 CPU 架构是amd64 ,但我认为这无关紧要。

提前致谢!

如果我理解正确,这至少在三个层面上是错误的。

  1. 无法保证新主机进程正在导入您调用的 API。 如果您调用CryptAcquireContext ,linker 将确保在构建的 PE(源二进制文件)中添加advapi32.dllCryptAcquireContext条目。 目标可能一开始就没有这种导入。

  2. call QWORD [target]仍然使用 32 位位移。 加载程序修复的导入地址可以很好地高于 4GiB(几乎总是如此)。 我不认为你可以强制cl (尝试使用链接选项/LARGEADDRESSAWARE:no ,但它是一个链接选项,而不是编译器选项)不为这些调用使用相对于 RIP 的地址,但即使你这样做了为你的PE 工作,而不是为目标 PE 工作。 您的 PE 需要加载到 4GiB 以下,而几乎可以肯定目标 PE 不会。

  3. 绝对地址需要重定位。 您可以强制cl / link发出一个不可移动的 PE,并避免重新定位,但同样,这是针对您的PE,而不是目标 PE。

简而言之,您的代码和您的二进制文件被捆绑在一起以创建一个进程,您的代码将在该进程中正常工作。
如果您迁移到另一个进程,则必须弥补差异,这不像编写普通代码(包括访问全局数据)。

如果您已经在编写 DLL,最简单的方法是使用SetWindowsHookEx将新创建的远程线程与 DLL 中的 function 挂钩。 Windows 将自动将您的整个 DLL 注入目标进程。 使用任何你知道至少会被调用一次的钩子(这很容易,因为你控制了远程线程的代码)。

否则,您可以将注入的代码移动到 DLL 中,并注入一个 shim/loader 从磁盘/内存中加载所述 DLL。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM