C语言中uint64_t写入char*缓冲区后读取值不一致问题求解
问题原因与修复方案
核心错误点
- 你使用
snprintf配合%s格式化符写入uint64_t类型的地址是完全错误的:%s要求参数为C字符串的首地址,你直接传入new_ret这个数值,程序会把该数值当作内存地址,去对应地址读取字符串内容再写入缓冲区,完全没有把new_ret本身的二进制值写入目标位置,导致缓冲区内容和预期完全不符。 snprintf、strncpy都属于字符串处理函数,遇到\0字节就会自动截断,而返回地址作为二进制数值大概率包含0字节,就算格式化符用对,用这类函数也无法完整写入8字节的地址值。- 把
char数组直接强转为uint64_t*存在内存对齐风险,部分CPU架构下非对齐访问会直接触发崩溃,即使在x86平台能正常运行也属于未定义行为。
正确实现代码
要直接写入uint64_t的二进制值到缓冲区,使用内存拷贝函数memcpy即可:
uint64_t new_ret = ret - 8 - 32 - 32 - 1001 + (ret_buffer_offset + sizeof(shellcode)); // 打印地址建议用%p输出十六进制,更方便对比 printf("new_ret :%p\n", (void*)new_ret); // 直接拷贝8字节二进制内容到缓冲区对应位置 memcpy(&buffer[ret_buffer_offset], &new_ret, sizeof(new_ret)); // 调试代码 char buffer_debug[10]; uint64_t ret_debug; bzero(buffer_debug, 10); // 同样用memcpy拷贝,避免字符串截断问题 memcpy(buffer_debug, &buffer[ret_buffer_offset], sizeof(ret_debug)); // 用memcpy取值,规避对齐问题 memcpy(&ret_debug, buffer_debug, sizeof(ret_debug)); printf("ret debug: %p\n", (void*)ret_debug);
内容的提问来源于stack exchange,提问作者Dyskord
相关产品推荐
相关产品推荐

