/** * Copyright (C) NAKAMURA Minoru * * gcc disassembler.c -lopcodes -lbfd -liberty */ #include #include #include #include static int read_memory_func(bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, struct disassemble_info *info); /** * start_memaddr から length バイト分の命令を逆アセンブラした結果を * stream に出力する。 */ extern int disassemble_instructions(const char* start_memaddr, int length, FILE* stream) { disassemble_info dinfo; int ret = 0; bfd_vma start, end, eip; bfd_init(); INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf); dinfo.read_memory_func = read_memory_func; start = (bfd_vma) start_memaddr; end = (bfd_vma) start + length; #if defined(__i386__) dinfo.mach = bfd_mach_i386_i386; #elif defined(__x86_64__) dinfo.mach = bfd_mach_x86_64; #endif for (eip = start; eip < end ;) { int ret; unsigned char* p = (unsigned char*) eip; #if defined(__ia64__) fprintf(stream, "%p %02x %02x %02x %02x %02x %02x : ", p, p[0], p[1], p[2], p[3], p[4], p[5]); fflush(stream); ret = print_insn_ia64(eip, &dinfo); fflush(stream); fprintf(stream, " \n"); fflush(stream); #elif defined(__i386__) || defined(__x86_64__) fprintf(stream, "%p : ", p); fflush(stream); ret = print_insn_i386(eip, &dinfo); fflush(stream); fprintf(stream, " \n"); fflush(stream); #else #error "Not supported for this platform." #endif if (ret <= 0) { break; } else { eip += ret; } } return 0; } static int read_memory_func(bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, struct disassemble_info *info) { int i; for (i=0 ; i