Analyser Call et Ret avec ptrace.

J’essaie d’parsingr tous les appels et les appels à partir d’un exécutable avec ptrace. En conformité avec le x64opcode , j’ai trouvé des opcodes pour les appels: 0xe8 et pour Rets: 0xc3, 0xc2, 0xca, 0xcb .

Depuis que je les ai analysés, j’ai trouvé plus de Rets que d’appels.

Voici le programme que je trace:

void func() { write(1, "i", 1); } int main(int ac) { func(); return(0); } 

Voici mon traceur:

 int tracer(t_info *info) { int status; long ptr; int ret = 0; int call = 0; waitpid(info->pid, &status, 0); while (WIFSTOPPED(status)) { ptrace(PTRACE_GETREGS, info->pid, NULL, info->regs); ptr = ptrace(PTRACE_PEEKDATA, info->pid, info->regs->rip); if (((ptr & 0x000000ff) == 0xe8)) // Opcode for call { call++; } else if (((ptr & 0x000000ff) == 0xc3) // Opcodes for rets || ((ptr & 0x000000ff) == 0xc2) || ((ptr & 0x000000ff) == 0xca) || ((ptr & 0x000000ff) == 0xcb)) { ret++; } ptrace(PTRACE_SINGLESTEP, info->pid, 0, 0); waitpid(info->pid, &status, 0); } printf("Calls: %i\nRets: %i\nDiff: %i\n", call, ret, call - ret); return (0); } 

Voici ma sortie:

 Calls: 656 Rets: 666 Diff: -10 

Pourquoi n’y a-t-il pas le même nombre de rets et d’ appels ? Est-ce que je manque des opcodes? Y a-t-il des fonctions qui ne reviennent pas?

Par exemple, vous manquez des appels indirects comme

 callq *() 

qui utilisent d’autres opcodes. Les routines d’initialisation standard Libc les utilisent. En fonction de l’expression, plusieurs opcodes sont possibles, deux exemples:

 ff d0 callq *%rax 41 ff 14 dc callq *(%r12,%rbx,8) 

Ce n’est probablement pas facile de tous les obtenir. Peut-être serait-il plus facile et plus propre de décoder les instructions avec une bibliothèque comme libbfd et libopcodes