c - 链表在执行期间不复合
问题描述
我正在尝试创建一个链接列表,在解析汇编代码文件时存储返回指令。作为对代码的解释,当遇到调用指令时,要保存下一条指令的地址。当遇到返回指令时,应该遍历链表,直到到达下一个节点为 的点NULL
。由于某种原因,代码没有保存返回地址。它可能与递归有关吗?
//function to create a node in linked list
struct ret_addr *return_address(cs_insn *insn, struct ret_addr *r) {
struct ret_addr *ret = malloc(sizeof(*ret));
ret->address = insn->address + insn->size;
ret->nxt_ret_addr = r;
return ret;
}
//retrieve the data from the last node of the linked list
int return_val(struct ret_addr *r) {
if(r == NULL)
return 0;
while(r->nxt_ret_addr != NULL) {
r = r->nxt_ret_addr;
return r->address;
}
}
//parse assembly code
struct bb_data *disassemble_function_cfg(int startAddr, unsigned char *bytes, int end_section) {
csh handle;
cs_insn *insn;
cs_detail *detail;
size_t count;
int stop_disasm = 0;
struct ret_addr *r_data = malloc(sizeof(*r_data));
count = cs_disasm(handle, bytes, end_section, startAddr, 1, &insn);
detail = insn->detail;
for(int n = 0; n < detail->groups_count; n++) {
if(detail->groups[n] == X86_GRP_CALL) {
stop_disasm = 1;
r_data = return_address(insn, r_data);
}
else if(detail->groups[n] == X86_GRP_RET) {
stop_disasm = 1;
start_edge = return_val(r_data);
}
if(!stop_disasm)
disassemble_function_cfg(insn->address + insn->size, bytes + insn->size, end_section);
else
return edges;
}
在初始call
指令期间,返回值被保存(通过打印出来检查),但是当到达返回指令时,链表突然为空。我的想法是,这是由对 的不断调用引起的malloc
,但我不确定这是否是一个正确的假设。
解决方案
问题出在return_val
函数中:它没有修改r_data
调用函数的值disassemble_function_cfg
。
我还假设了一件小事:因为它是一个调用/返回实现,所以链表应该表现为 LIFO(后进先出)。该return_address
函数通过插入头部来填充链表,因此该return_val
函数应该首先从头部删除地址:在到达之前不需要读取列表NULL
。
试试这个代码:
//retrieve the data from the last node of the linked list
int return_val(struct ret_addr **r) {
int ret_val;
if (*r == NULL)
return 0;
ret_val = (*r)->address;
*r = (*r)->nxt_ret_addr;
return ret_val;
}
在调用者函数中:
else if(detail->groups[n] == X86_GRP_RET) {
stop_disasm = 1;
start_edge = return_val(&r_data); // address of r_data, so it can be modified
}
推荐阅读
- forms - XLSForm、ODK XForm 和 XForms 是等效的吗?
- c - 编译 Ubuntu 20.04 时找不到库函数
- node.js - 如何将输入数据存储到数组选项中?
- node.js - pm2 可以自动重启一个结束的脚本吗?
- python - 如何将标签名称添加到线标签?
- laravel - windows server 中的 laravel 制作
- visual-studio - 在 Visual Studio 2013 中编译用户模式驱动程序
- python - QItemDelegate 修改单元格中选定单元格没有背景
- r - 如何在 R 编程中自动生成和命名 10,000 个向量?
- python - 对 TensorFlow 服务的 RaggedTensor 请求失败