Связанный список не сохраняет значения при рекурсивных вызовах функций? - PullRequest
0 голосов
/ 01 мая 2018

Я пытаюсь реализовать связанный список, который бы сохранял адрес памяти при обращении к инструкциям сборки вызова / возврата. Это работает рекурсивно, анализируя каждую строку сборки и прерывая функцию только при обнаружении команды call или return. До сих пор это работает для инструкций вызова, то есть адрес возврата сохраняется узлом в связанном списке, но при попытке извлечь это значение во время инструкции возврата данные пропали (это означает, что связанный список теперь пуст). Вот с чем я работаю:

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;
    }
}

1 Ответ

0 голосов
/ 01 мая 2018

Вы не сохраняете свой список между рекурсивными вызовами. Что вы можете сделать:

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);
   ...
}
...