如何复制函数指令至缓冲区?及代码存储汇编指令失败问题
问题解答
问题2:代码无法复制函数指令的原因
你的代码核心错误出在memcpy(buffer, &addr, 1000);这一行:
addr是存储函数地址的指针变量,&addr取的是这个变量自身在内存中的存储地址,而非addr指向的func函数指令的起始地址。你实际复制的是addr变量所在内存的字节(也就是一个指针值),根本没读取到func的指令内容,这就是buffer始终是无效数据的原因。- 另外,
addr = (uint64_t*)&func;这一步完全多余,直接用&func就能拿到函数的起始地址。
问题1:正确复制函数指令到缓冲区的方法
要把函数的汇编指令复制到缓冲区,关键是直接操作函数的起始地址,同时注意复制的长度:
- 用函数地址作为源:
&func(或直接写func)就是函数指令在内存中的起始地址,直接作为memcpy的源参数。 - 明确函数的实际大小:你用1000做长度只是示例,但实际必须知道函数的字节长度,避免越界复制(可以通过编译器扩展、链接器脚本或分析汇编代码获取)。
- 确认内存权限:多数系统中代码段默认是可读可执行的,所以读取函数指令没问题。
修正后的代码示例:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> // 必须包含才能使用uint64_t char buffer[1000]; // 假设func的实际大小为64字节(需根据你的函数实际情况调整) #define FUNC_ACTUAL_SIZE 64 void func() { // 直接从func的起始地址复制指令到buffer memcpy(buffer, &func, FUNC_ACTUAL_SIZE); // 后续哈希链逻辑 // strcpy(secret, hash(secret, buffer)); }
额外提示
- 如果函数包含编译器插入的额外指令(比如栈保护、对齐填充),要确保复制范围覆盖完整的函数代码。
- 不建议硬编码函数大小,实际项目中可以这样获取:
- 使用GCC扩展
__builtin_function_start和__builtin_function_end来获取函数的起止地址,计算长度。 - 编写链接器脚本,在编译阶段导出函数的起始和结束标记。
- 查看编译后的汇编代码,手动计算函数的字节长度。
- 使用GCC扩展
内容的提问来源于stack exchange,提问作者Mohammed
相关产品推荐
相关产品推荐

