DynamoRIO / dynamorio

Dynamic Instrumentation Tool Platform
Other
2.61k stars 554 forks source link

AARCHXX: Implement dr_insert_mbr_instrumentation #2919

Open vanhauser-thc opened 6 years ago

vanhauser-thc commented 6 years ago

The code below works find on intel x64 but on on arm7/AARCHXX:

#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/shm.h>
#include "droption.h"
#include "dr_api.h"
#include "drmgr.h"
#include "drx.h"
#include "drwrap.h"
#include "drx.h"
#include "drutil.h"
#include "drreg.h"
#include <cstring>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <sstream>
#include <unordered_set>
#include <exception>

int debug = 1;

static void ind(app_pc instr_addr, app_pc target_addr) {
  fprintf(stderr, "INDIRECT from %p to %p\n", instr_addr, target_addr);
}

static dr_emit_flags_t event_app_instruction(void *drcontext, void *tag, instrlist_t * bb, instr_t * inst, bool for_trace, bool translating, void *user_data) {
  drmgr_disable_auto_predication(drcontext, bb);
  if (instr_is_call_indirect(inst) == true) {
      if (debug) {
        char buf[64];
        instr_disassemble_to_buffer(drcontext, inst, buf, sizeof(buf));
        fprintf(stderr, "INFO %p %s ; indirect call\n", instr_get_app_pc(inst), buf);
      }
      drreg_status_t res = drreg_restore_app_values(drcontext, bb, inst, instr_get_target(inst), NULL);
      dr_insert_mbr_instrumentation(drcontext, bb, inst, (app_pc)ind, SPILL_SLOT_1);
  } else if (instr_is_mbr(inst) == true && instr_is_return(inst) == false) {
      if (debug) {
        char buf[64];
        instr_disassemble_to_buffer(drcontext, inst, buf, sizeof(buf));
        fprintf(stderr, "INFO %p %s ; indirect jump\n", instr_get_app_pc(inst), buf);
      }
      drreg_status_t res = drreg_restore_app_values(drcontext, bb, inst, instr_get_target(inst), NULL);
      dr_insert_mbr_instrumentation(drcontext, bb, inst, (app_pc)ind, SPILL_SLOT_1);
  }
  return DR_EMIT_DEFAULT;
}

DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[]) {
  if (!drmgr_init() || !drx_init() || !drwrap_init())
    DR_ASSERT(false);
  drmgr_register_bb_instrumentation_event(NULL, event_app_instruction, NULL);
  disassemble_set_syntax(DR_DISASM_INTEL);
}

on ARM7/AARCH:

drrun -c build/libtest.so -- /bin/true
INFO 0xb6ef61d6 tbb    byte ptr [pc+r0] ; indirect jump
INFO 0xb6f057d0 tbb    byte ptr [pc+r3] ; indirect jump
INFO 0xb6f0592c blx    lr, r7 ; indirect call
INFO 0xb6ef66ba bx     r3 ; indirect jump
INFO 0xb6ef57f8 ldr    pc, dword ptr [r12+0x0820] ; indirect jump
INFO 0xb6ef57d4 bx     pc ; indirect jump
INFO 0xb6ef57e0 ldr    pc, dword ptr [r12+0x0830] ; indirect jump
INFO 0xb6ef57c4 bx     pc ; indirect jump
[...]

where the mbr instrumentation function is never called.

on INTEL X64 its what I would except:

INFO 0x7ffff7d81792 jmp    rax ; indirect jump
INDIRECT from 0x7ffff7d81792 to 0x7ffff7d81902
INFO 0x7ffff7d8162f call   r13 ; indirect call
INDIRECT from 0x7ffff7d8162f to 0x7ffff7d6a1e0
INFO 0x7ffff7d6a2ff jmp    rax ; indirect jump
INDIRECT from 0x7ffff7d6a2ff to 0x7ffff7d6b368
INFO 0x7ffff7d68a90 jmp    <rel> qword ptr [0x00007ffff7f8e028] ; indirect jump
INDIRECT from 0x7ffff7d68a90 to 0x7ffff7d81f10
INFO 0x7ffff7d68a80 jmp    <rel> qword ptr [0x00007ffff7f8e020] ; indirect jump
INDIRECT from 0x7ffff7d68a80 to 0x7ffff7d81f00
INFO 0x7ffff7d68a70 jmp    <rel> qword ptr [0x00007ffff7f8e018] ; indirect jump
INDIRECT from 0x7ffff7d68a70 to 0x7ffff7d81e00
INFO 0x7ffff7d73b11 call   <rel> qword ptr [0x00007ffff7f8ef48] ; indirect call
INDIRECT from 0x7ffff7d73b11 to 0x7ffff7d68c90
INFO 0x7ffff7d73b7f jmp    <rel> qword ptr [0x00007ffff7f8ef50] ; indirect jump
INDIRECT from 0x7ffff7d73b7f to 0x7ffff7d68ca0
INFO 0x7ffff7d83bc9 jmp    r10 ; indirect jump
INDIRECT from 0x7ffff7d83bc9 to 0x7ffff7d84a30

or did I forget something important which is necessary for ARM?

fhahn commented 6 years ago

Unfortunately I do not think you are missing anything. It looks like this has never been implemented for ARM or AArch64: https://github.com/DynamoRIO/dynamorio/blob/ce3a9f40970cd53a8f29c00bbff38d5140673870/core/lib/instrument.c#L6133

Issues #1551

fhahn commented 6 years ago

@vanhauser-thc from a quick look at the X86 implementation of dr_insert_mbr_instrumentation, it does not look like there is a huge amount of code to port to get it working on AArch64/ARM.

Let me know if you are interested in having a go at porting it, I am happy to help with any questions

vanhauser-thc commented 6 years ago

Hi Florian, I would not mind at all to implemend that, it should be not too hard. However I am drowned in programming work at the moment so it will take several weeks until I can/could start with it. If it is still undone when I have the time for it then I will have a go

fhahn commented 6 years ago

That would be great, just let us know when you start looking into this.

fhahn commented 6 years ago

See also #2297. @AssadHashmi is working on implementing dr_insert_cbr_instrumentation for AArch64