如何阻止MSVC链接器重排机器代码中的C函数顺序?
解决方案
1. 修正/ORDER选项的使用方式
你之前直接把源文件传给/ORDER是错误的,这个选项需要的是排序规则文件而非源文件。操作步骤:
- 新建一个文本文件(比如
func_order.txt),每行写入一个需要指定顺序的函数名:shellcode_start shellcode_finish main - 修改链接器选项为
/ORDER:@"func_order.txt",确保文件路径正确。
注意:Debug模式下MSVC会给函数名添加修饰前缀(例如?shellcode_start@@YAXXZ),必须使用修饰后的符号名才能让排序生效。可以通过dumpbin /symbols x64\Debug\order.obj查看目标文件中的符号,找到对应函数的修饰名替换到排序文件中;也可以直接在代码中用#pragma comment(linker, "/ORDER:?shellcode_start@@YAXXZ")指定单个函数的顺序。
2. 用自定义段强制函数顺序
创建自定义代码段,将目标函数都放入该段,链接器会保持段内函数的定义顺序,无需依赖排序文件:
#include <Windows.h> #pragma section(".mycode", read, execute) __declspec(allocate(".mycode")) void shellcode_start() {} __declspec(allocate(".mycode")) void shellcode_finish() {} int main() { unsigned char *start = (unsigned char*)shellcode_start; unsigned char *finish = (unsigned char*)shellcode_finish; unsigned int sizeofshellcode = finish - start; return 0; }
3. 关闭Debug模式的增量链接
Debug模式默认开启增量链接(/INCREMENTAL),这会干扰函数顺序的控制。将链接器选项改为/INCREMENTAL:NO,再配合/ORDER使用,可解决排序失效问题。
4. 切换到Release模式(若允许)
Release模式下,只要禁用链接器的/OPT:REF和/OPT:ICF(改为/OPT:NOREF和/OPT:NOICF),再结合前两种方法,更容易稳定控制函数顺序。如果必须使用Debug模式,优先考虑前三种方案。
内容的提问来源于stack exchange,提问作者vengy
相关产品推荐
相关产品推荐

