C 链表在递归函数调用中不保留值?
我正在尝试实现一个链表,当遇到调用/返回汇编指令时,该链表将存储一个内存地址。这通过解析程序集的每一行递归地工作,并且仅在遇到调用或返回指令时中断函数。到目前为止,这适用于调用指令,这意味着返回地址保存在链接列表中的一个节点中,但在返回指令期间尝试检索此值时,数据已丢失,这意味着链接列表现在为空。以下是我的工作内容:C 链表在递归函数调用中不保留值?,c,data-structures,linked-list,C,Data Structures,Linked List,我正在尝试实现一个链表,当遇到调用/返回汇编指令时,该链表将存储一个内存地址。这通过解析程序集的每一行递归地工作,并且仅在遇到调用或返回指令时中断函数。到目前为止,这适用于调用指令,这意味着返回地址保存在链接列表中的一个节点中,但在返回指令期间尝试检索此值时,数据已丢失,这意味着链接列表现在为空。以下是我的工作内容: struct ret_addr { int address; struct ret_addr *nxt; }; struct ret_addr *ret_data
struct ret_addr {
int address;
struct ret_addr *nxt;
};
struct ret_addr *ret_data(cs_insn *insn, struct ret_addr **head) {
struct ret_addr *r = malloc(sizeof(*r));
r->address = insn->address + insn->size;
r->nxt = (*head);
(*head) = r;
return r;
}
struct bb_data *disassemble_function_cfg(int startAddr, unsigned char *bytes, int end_section) {
csh handle;
cs_insn *insn;
cs_detail *detail;
cs_x86 *x86;
size_t count;
int stop_disasm = 0;
struct bb_data *edges = NULL;
struct ret_addr *ret_edge = NULL;
count = cs_disasm(handle, bytes, end_section, startAddr, 1, &insn);
detail = insn->detail;
for(int n = 0; n < detail->groups_count; n++) {
//break when encountering a call instruction
if(detail->groups[n] == X86_GRP_CALL) {
stop_disasm = 1;
vector_new(edges);
edges = call_insn(handle, x86, insn, vector_back(edges));
ret_edge = ret_data(insn, &ret_edge);
}
//break when encountering a return instruction
else if(detail->groups[n] == X86_GRP_RET) {
stop_disasm = 1;
vector_new(edges);
edges = ret_insn(insn, edges, &ret_edge);
}
}
if(!stop_disasm) {
disassemble_function_cfg(insn->address + insn->size, bytes + insn->size, end_section);
}
else {
return edges;
}
}
在递归调用之间不保留列表。您可能想做的事情:
struct bb_data *disassemble_function_cfg(struct ret_addr **ret_edge, int startAddr, unsigned char *bytes, int end_section)
{
...
if(*ret_edge == NULL) *ret_edge = ret_data(insn, ret_edge);
...
}
看起来每次在反汇编函数中都会创建一个新列表。如果列表没有被传递到函数中,它将如何被保存;边缘=重新检查、边缘和重新检查边缘;这看起来像一个漏洞,边缘只是一个指针。但是我们不知道vector_new是什么,当然vector_new是一个宏,它通过malloc和realloc调用创建结构实例。很抱歉,我应该在原始POST中包含这一点,我试图实现这一点,但收到警告:传递来自不兼容指针类型的ret_数据的2的参数