struct disassemble_info* new_disasm_info( struct bfd* abfd ) { struct disassemble_info *di = (struct disassemble_info *) malloc( sizeof(struct disassemble_info) ); if ( !di ) error_exit( "failed to allocate disassemble_info" ); init_disassemble_info( di, stdout, (fprintf_ftype) fprintf ); di->flavour = bfd_get_flavour( abfd ); di->arch = bfd_get_arch( abfd ); di->mach = bfd_get_mach( abfd ); di->octets_per_byte = bfd_octets_per_byte( abfd ); di->disassembler_needs_relocs = FALSE; di->buffer = NULL; di->symtab = NULL; if ( bfd_big_endian( abfd ) ) di->display_endian = di->endian = BFD_ENDIAN_BIG; else if ( bfd_little_endian ( abfd ) ) di->display_endian = di->endian = BFD_ENDIAN_LITTLE; disassemble_init_for_target( di ); return di; }
// disassemble one instruction at laddr relative to memory, but at most memory+byteSize int disassembleForAtInSize(void *cpu, ulong laddr, void *memory, ulong byteSize) { gdblog_index = 0; // ignore the cpu disassemble_info* dis = (disassemble_info*) calloc(1, sizeof(disassemble_info)); init_disassemble_info ( dis, NULL, gdb_log_printf); dis->arch = bfd_arch_arm; dis->mach = bfd_mach_arm_unknown; // sets some fields in the structure dis to architecture specific values disassemble_init_for_target( dis ); dis->buffer_vma = 0; dis->buffer = memory; dis->buffer_length = byteSize; //prepend the address gdb_log_printf(NULL, "0x%p: ", laddr); //other possible functions are listed in opcodes/dissassemble.c unsigned int size = print_insn_little_arm((bfd_vma) laddr, dis); free(dis); // zero terminate the string gdb_log[gdblog_index+1] = 0; return size; }
static struct disassemble_info gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file) { struct disassemble_info di; init_disassemble_info (&di, file, fprintf_disasm); di.flavour = bfd_target_unknown_flavour; di.memory_error_func = dis_asm_memory_error; di.print_address_func = dis_asm_print_address; /* NOTE: cagney/2003-04-28: The original code, from the old Insight disassembler had a local optomization here. By default it would access the executable file, instead of the target memory (there was a growing list of exceptions though). Unfortunately, the heuristic was flawed. Commands like "disassemble &variable" didn't work as they relied on the access going to the target. Further, it has been supperseeded by trust-read-only-sections (although that should be superseeded by target_trust..._p()). */ di.read_memory_func = dis_asm_read_memory; di.arch = gdbarch_bfd_arch_info (gdbarch)->arch; di.mach = gdbarch_bfd_arch_info (gdbarch)->mach; di.endian = gdbarch_byte_order (gdbarch); di.endian_code = gdbarch_byte_order_for_code (gdbarch); di.application_data = gdbarch; disassemble_init_for_target (&di); return di; }
/* Initialize disassembler (libopcodes/libbfd) for given file. * * If the the function returns data with data.bfd_file = NULL, * then the function failed. */ static struct disasm_data disasm_init(const char *filename) { asection *section; struct disasm_data data; static bool initialized = false; if (!initialized) { bfd_init(); initialized = true; } data.bfd_file = bfd_openr(filename, NULL); if (data.bfd_file == NULL) { VERB1 log_bfd_error("bfd_openr", filename); return data; } if (!bfd_check_format(data.bfd_file, bfd_object)) { VERB1 log_bfd_error("bfd_check_format", filename); goto ret_fail; } section = bfd_get_section_by_name(data.bfd_file, ".text"); if (section == NULL) { VERB1 log_bfd_error("bfd_get_section_by_name", filename); goto ret_fail; } data.disassemble = disassembler(data.bfd_file); if (data.disassemble == NULL) { VERB1 log("Unable to find disassembler"); goto ret_fail; } init_disassemble_info(&data.info, NULL, buffer_printf); data.info.arch = bfd_get_arch(data.bfd_file); data.info.mach = bfd_get_mach(data.bfd_file); data.info.buffer_vma = section->vma; data.info.buffer_length = section->size; data.info.section = section; /*TODO: memory error func*/ bfd_malloc_and_get_section(data.bfd_file, section, &data.info.buffer); disassemble_init_for_target(&data.info); return data; ret_fail: bfd_close(data.bfd_file); data.bfd_file = NULL; return data; }
void print_instruction(void *buf, unsigned long size) { struct disassemble_info info; init_disassemble_info (&info, stdout, (fprintf_ftype)fprintf); info.mach = bfd_mach_x86_64; info.endian = BFD_ENDIAN_LITTLE; info.buffer = buf; info.buffer_length = size; printf("\033[35m"); print_insn_i386(0, &info); printf("\033[0m"); printf("\n"); }
struct disassemble_info gdb_disassemble_info (unsigned char *mem_buf, char *output_buf) { struct disassemble_info di; init_disassemble_info (&di, output_buf, sprintf_disasm); di.buffer = mem_buf; di.buffer_length = UINT_MAX; di.print_address_func = dis_asm_sprint_address; di.flavour = bfd_target_unknown_flavour; di.arch = bfd_arch_m68k; di.mach = bfd_mach_m68000; di.endian = BFD_ENDIAN_BIG; disassemble_init_for_target (&di); return di; }
static void init_disasm_info(bfd *abfd, struct disassemble_info *disasm_info) { init_disassemble_info (disasm_info, stdout, (fprintf_ftype) fprintf); disasm_info->flavour = bfd_get_flavour (abfd); disasm_info->arch = bfd_get_arch (abfd); disasm_info->mach = bfd_get_mach (abfd); disasm_info->octets_per_byte = bfd_octets_per_byte (abfd); disasm_info->disassembler_needs_relocs = FALSE; if (bfd_big_endian (abfd)) disasm_info->display_endian = disasm_info->endian = BFD_ENDIAN_BIG; else if (bfd_little_endian (abfd)) disasm_info->display_endian = disasm_info->endian = BFD_ENDIAN_LITTLE; disassemble_init_for_target(disasm_info); disasm_info->read_memory_func = my_read_memory; }
void arch_bfdDisasm(pid_t pid, uint8_t * mem, size_t size, char *instr) { while (pthread_mutex_lock(&arch_bfd_mutex)) ; bfd_init(); char fname[PATH_MAX]; snprintf(fname, sizeof(fname), "/proc/%d/exe", pid); bfd *bfdh = bfd_openr(fname, NULL); if (bfdh == NULL) { LOGMSG(l_WARN, "bfd_openr('/proc/%d/exe') failed", pid); goto out; } if (!bfd_check_format(bfdh, bfd_object)) { LOGMSG(l_WARN, "bfd_check_format() failed"); goto out; } disassembler_ftype disassemble = disassembler(bfdh); if (disassemble == NULL) { LOGMSG(l_WARN, "disassembler() failed"); goto out; } struct disassemble_info info; init_disassemble_info(&info, instr, arch_bfdFPrintF); info.arch = bfd_get_arch(bfdh); info.mach = bfd_get_mach(bfdh); info.buffer = mem; info.buffer_length = size; info.section = NULL; info.endian = bfd_little_endian(bfdh) ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG; disassemble_init_for_target(&info); strcpy(instr, ""); if (disassemble(0, &info) <= 0) { snprintf(instr, _HF_INSTR_SZ, "[DIS-ASM_FAILURE]"); } out: bfdh ? bfd_close_all_done(bfdh) : 0; while (pthread_mutex_unlock(&arch_bfd_mutex)) ; return; }
int main () { unsigned int data[3] = {0xE3A01080, 0xE2810001, 0xE1A01001}; bfd_byte* buf = (bfd_byte*) &data[0]; disassemble_info* c = (struct disassemble_info*) calloc(1, sizeof(disassemble_info)); // void init_disassemble_info (struct disassemble_info *dinfo, void *stream, fprintf_ftype fprintf_func) init_disassemble_info ( c, stdout, my_fprintf); //c->application_data //c->memory_error_func // set architecture c->arch = bfd_arch_arm; // set the specific machine: unknown allows all instructions in the libraries database c->mach = bfd_mach_arm_unknown; // should set the disassembler field of c to the right function disassemble_init_for_target( c ); // given a bfd, the disassembler can find the arch by itself. //disassemble = disassembler( c ); c->buffer_vma = 0; c->buffer = buf; c->buffer_length = 12; // while-loop for calling single instruction decoding: unsigned int count = 0; size_t pos = 0; size_t length = c->buffer_length; size_t max_pos = c->buffer_vma+length; while(pos < max_pos) { //disassembler-function: print_insn_big_arm //other possible functions are listed in opcodes/dissassemble.c unsigned int size = print_insn_little_arm((bfd_vma) pos, c); pos += size; count++; fprintf(stdout, "\n"); } return 0; }
Mnemonic::Mnemonic(pword buffer, bool att) : opcodeLength(0), assemblyString("") { //NULL the opcode: memset(this->opcode, 0, MAX_INSTRUCTION_BYTES); //Open a memory stream: char stringBuffer[256]; FILE* memStream = fmemopen(stringBuffer, 256, "w"); if (!memStream) { throw runtime_error("Failed to open memory stream."); } //Prepare disassembly info (bfd): struct disassemble_info info; init_disassemble_info(&info, memStream, (fprintf_ftype)fprintf); //This is the same for all architectures: info.buffer = (bfd_byte*)buffer; info.buffer_length = MAX_INSTRUCTION_BYTES; //Discriminate between architectures: #ifdef __i386__ info.arch = bfd_arch_i386; info.mach = att ? bfd_mach_i386_i386 : bfd_mach_i386_i386_intel_syntax; info.endian = BFD_ENDIAN_LITTLE; this->opcodeLength = att ? print_insn_i386(0, &info) : print_insn_i386_intel(0, &info); #elif __amd64__ info.arch = bfd_arch_i386; info.mach = att ? bfd_mach_x86_64 : bfd_mach_x86_64_intel_syntax; info.endian = BFD_ENDIAN_LITTLE; this->opcodeLength = att ? print_insn_i386(0, &info) : print_insn_i386_intel(0, &info); #endif //Close the stream: fclose(memStream); //Assign: this->assemblyString = stringBuffer; //Build the raw opcode buffer from the length: memcpy(this->opcode, buffer, this->opcodeLength); }
static void get_asm_insns(uint8_t *image, size_t len, unsigned long base, int opcodes) { int count, i, pc = 0; char tpath[256]; struct disassemble_info info; disassembler_ftype disassemble; bfd *bfdf; memset(tpath, 0, sizeof(tpath)); get_exec_path(tpath, sizeof(tpath)); bfdf = bfd_openr(tpath, NULL); assert(bfdf); assert(bfd_check_format(bfdf, bfd_object)); init_disassemble_info(&info, stdout, (fprintf_ftype) fprintf); info.arch = bfd_get_arch(bfdf); info.mach = bfd_get_mach(bfdf); info.buffer = image; info.buffer_length = len; disassemble_init_for_target(&info); disassemble = disassembler(bfdf); assert(disassemble); do { printf("%4x:\t", pc); count = disassemble(pc, &info); if (opcodes) { printf("\n\t"); for (i = 0; i < count; ++i) printf("%02x ", (uint8_t) image[pc + i]); } printf("\n"); pc += count; } while(count > 0 && pc < len); bfd_close(bfdf); }
void init_disasm_info(bfd *abfd, struct disassemble_info *disasm_info) { init_disassemble_info (disasm_info, stdout, (fprintf_ftype) fprintf); disasm_info->flavour = bfd_get_flavour (abfd); disasm_info->arch = bfd_get_arch (abfd); disasm_info->mach = bfd_get_mach (abfd); //disasm_info->disassembler_options = disassembler_options; disasm_info->octets_per_byte = bfd_octets_per_byte (abfd); //disasm_info->skip_zeroes = DEFAULT_SKIP_ZEROES; //disasm_info->skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END; disasm_info->disassembler_needs_relocs = FALSE; if (bfd_big_endian (abfd)) disasm_info->display_endian = disasm_info->endian = BFD_ENDIAN_BIG; else if (bfd_little_endian (abfd)) disasm_info->display_endian = disasm_info->endian = BFD_ENDIAN_LITTLE; disassemble_init_for_target(disasm_info); disasm_info->read_memory_func = my_read_memory; }
static void gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch, struct disassemble_info *di, const gdb_byte *insn, int max_len, CORE_ADDR addr) { init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf); /* init_disassemble_info installs buffer_read_memory, etc. so we don't need to do that here. The cast is necessary until disassemble_info is const-ified. */ di->buffer = (gdb_byte *) insn; di->buffer_length = max_len; di->buffer_vma = addr; di->arch = gdbarch_bfd_arch_info (gdbarch)->arch; di->mach = gdbarch_bfd_arch_info (gdbarch)->mach; di->endian = gdbarch_byte_order (gdbarch); di->endian_code = gdbarch_byte_order_for_code (gdbarch); disassemble_init_for_target (di); }
bool disas_libopcode(FILE *fp_out, const char *machine, bool big_endian, uint64_t addr, void *buf, size_t len) { bfd *abfd = NULL; struct disassemble_info inf; const bfd_arch_info_type *arch_inf = bfd_scan_arch (machine); disassembler_ftype disas_fn; int size, pos; if (!arch_inf) { return false; } abfd = bfd_openr("/dev/null", "binary"); abfd->arch_info = arch_inf; init_disassemble_info (&inf, fp_out, (fprintf_ftype) fprintf); inf.buffer = buf; inf.buffer_vma = addr; inf.buffer_length = len; inf.endian = big_endian ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE; inf.print_address_func = print_address; disassemble_init_for_target(&inf); disas_fn = disassembler (abfd); pos = 0; do { fprintf(fp_out, "%" PRIx64 "\t", addr + pos); size = disas_fn(addr + pos, &inf); pos += size; fputc('\n', fp_out); } while (pos < len); bfd_close(abfd); return true; }
int main(void) { disassembler_ftype disassemble_fn; disassemble_info info = {0}; void *lib, *sym; lib_init_fn init_fn; init_disassemble_info(&info, stdout, (fprintf_ftype) fprintf); info.arch = bfd_arch_i386; // * info.mach = bfd_mach_i386_i386; // * info.flavour = bfd_target_elf_flavour; // * info.endian = BFD_ENDIAN_LITTLE; // * // not needed for this test code //info.read_memory_func = buffer_read_memory; //info.memory_error_func = perror_memory; //info.print_address_func = generic_print_address; //info.symbol_at_address_func = generic_symbol_at_address; //info.fprintf_func = disprintf; //info.stream = stdout; //info.symbols = NULL; //info.num_symbols = 0; info.display_endian = BFD_ENDIAN_LITTLE; // * info.buffer = target_buf; info.buffer_length = sizeof(target_buf); info.buffer_vma = 0x1000; printf("x86 AT&T disassembly\n"); disbuf(print_insn_i386_att, &info); // * // test unknown-everything printf("x86 Intel disassembly\n"); info.arch = bfd_arch_unknown; info.mach = bfd_arch_unknown; // * info.flavour = bfd_target_unknown_flavour; disbuf(print_insn_i386_intel, &info); // * lib = dlopen(ARM_BFD, RTLD_NOW | RTLD_GLOBAL ); if (! lib ) { fprintf(stderr, "Unable to load %s: %s\n", ARM_PATH, dlerror()); } lib = dlopen(ARM_PATH, RTLD_NOW | RTLD_GLOBAL ); // RTLD_LOCAL ); if ( lib ) { sym = dlsym(lib, ARM_INIT); if (sym) { init_fn = (lib_init_fn) sym; (*init_fn)(&info, stdout, (fprintf_ftype) fprintf); info.arch = bfd_arch_arm; // * info.mach = bfd_mach_arm_5; // * info.flavour = bfd_target_elf_flavour; // * info.endian = BFD_ENDIAN_LITTLE; // * info.buffer = target_buf; info.buffer_length = sizeof(target_buf); info.buffer_vma = 0x1000; } sym = dlsym(lib, ARM_SYM); if (sym) { printf("ARM disassembly\n"); disbuf(sym, &info); } dlclose(lib); } else { fprintf(stderr, "Unable to load %s: %s\n", ARM_PATH, dlerror()); } // Try Intel again (make sure loaded BFD does not conflict) init_disassemble_info(&info, stdout, (fprintf_ftype) fprintf); info.display_endian = BFD_ENDIAN_LITTLE; // * info.buffer = target_buf; info.buffer_length = sizeof(target_buf); info.buffer_vma = 0x1000; printf("(Post-ARM) x86 AT&T Disassembly\n"); info.arch = bfd_arch_unknown; info.mach = bfd_arch_unknown; // * info.flavour = bfd_target_unknown_flavour; /* test that overwriting print_address_func doesn't break anything */ info.print_address_func = (void (*) (bfd_vma, struct disassemble_info *)) print_insn_i386_att; disbuf(print_insn_i386_att, &info); // * return(0); }
void init_disassemble(){ abfd = malloc(sizeof(bfd)); init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf); disasm_info.print_address_func = objdump_print_address; disasm_info.symbol_at_address_func = objdump_symbol_at_address; /* * choose arch infor since we will select different disassemble function. */ generic_arch_t* arch_instance = get_arch_instance(""); machine = arch_instance->arch_name; const bfd_arch_info_type *info = bfd_scan_arch (machine); if (info == NULL){ //fatal (_("Can't use supplied machine %s"), machine); printf("Can't use supplied machine %s\n", machine); return; } abfd->arch_info = info; /* * endian selection */ if (endian != BFD_ENDIAN_UNKNOWN) { struct bfd_target *xvec; xvec = xmalloc (sizeof (struct bfd_target)); //memcpy (xvec, abfd->xvec, sizeof (struct bfd_target)); xvec->byteorder = endian; abfd->xvec = xvec; } /* Get a disassemble function according to the arch and endian of abfd */ disassemble_fn = disassembler (abfd); if(!disassemble_fn) { /* non_fatal (_("Can't disassemble for architecture %s\n"), bfd_printable_arch_mach (bfd_get_arch (abfd), 0)); */ printf("Can't disassemble for architecture %s\n", bfd_printable_arch_mach (bfd_get_arch (abfd), 0)); exit_status = 1; return; } disasm_info.flavour = bfd_get_flavour (abfd); disasm_info.arch = bfd_get_arch (abfd); disasm_info.mach = bfd_get_mach (abfd); disasm_info.disassembler_options = disassembler_options; disasm_info.octets_per_byte = bfd_octets_per_byte (abfd); disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES; disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END; disasm_info.disassembler_needs_relocs = FALSE; #if 1 if (bfd_big_endian (abfd)) disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG; else if (bfd_little_endian (abfd)) disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE; else /* ??? Aborting here seems too drastic. We could default to big or little instead. */ disasm_info.endian = BFD_ENDIAN_UNKNOWN; #endif /* set the default endianess is BFD_ENDIAN_LITTLE */ disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE; disasm_info.symtab = sorted_syms; disasm_info.symtab_size = sorted_symcount; disasm_info.read_memory_func = disasm_read_memory; free (sorted_syms); }
struct sr_disasm_state * sr_disasm_init(const char *file_name, char **error_message) { #if HAVE_LIBOPCODES struct sr_disasm_state *state = sr_malloc(sizeof(struct sr_disasm_state)); state->bfd_file = bfd_openr(file_name, NULL); if (!state->bfd_file) { *error_message = sr_asprintf("Failed to open file %s: %s", file_name, bfd_errmsg(bfd_get_error())); free(state); return NULL; } if (!bfd_check_format(state->bfd_file, bfd_object)) { *error_message = sr_asprintf("Invalid file format of %s: %s", file_name, bfd_errmsg(bfd_get_error())); bfd_close(state->bfd_file); free(state); return NULL; } asection *section = bfd_get_section_by_name(state->bfd_file, ".text"); if (!section) { *error_message = sr_asprintf( "Failed to find .text section in %s: %s", file_name, bfd_errmsg(bfd_get_error())); bfd_close(state->bfd_file); free(state); return NULL; } state->disassembler = disassembler(state->bfd_file); if (!state->disassembler) { *error_message = sr_asprintf( "Unable to find disassembler for %s", file_name); bfd_close(state->bfd_file); free(state); return NULL; } init_disassemble_info(&state->info, NULL, buffer_printf); state->info.arch = bfd_get_arch(state->bfd_file); state->info.mach = bfd_get_mach(state->bfd_file); state->info.buffer_vma = section->vma; state->info.buffer_length = section->size; state->info.section = section; /* TODO: memory error func */ bfd_malloc_and_get_section(state->bfd_file, section, &state->info.buffer); disassemble_init_for_target(&state->info); return state; #else // HAVE_LIBOPCODES *error_message = sr_asprintf("satyr compiled without libopcodes"); return NULL; #endif // HAVE_LIBOPCODES }
uv_err_t UVDBfdInstructionIterator::init() { bfd *a_bfd = NULL; uv_assert_ret(m_obj); uv_assert_ret(m_obj->m_bfd); a_bfd = m_obj->m_bfd; //Needs to be an object or an archive if( !bfd_check_format(a_bfd, bfd_object) && !bfd_check_format(a_bfd, bfd_archive) ) { //bfd_close(a_bfd); printf("bad file\n"); return UV_DEBUG(UV_ERR_GENERAL); } printf("BFD open and is object\n"); /* Standard disassemblers. Disassemble one instruction at the given target address. Return number of octets processed. typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *); */ g_disassembler_function = disassembler(a_bfd); if( !g_disassembler_function ) { printf("failed \n"); return UV_DEBUG(UV_ERR_GENERAL); } memset(&m_disasm_info, 0, sizeof(m_disasm_info)); init_disassemble_info(&m_disasm_info, stdout, (fprintf_ftype) fprintf); m_disasm_info.flavour = bfd_get_flavour (a_bfd); m_disasm_info.arch = bfd_get_arch (a_bfd); m_disasm_info.mach = bfd_get_mach (a_bfd); m_disasm_info.disassembler_options = NULL; m_disasm_info.octets_per_byte = bfd_octets_per_byte(a_bfd); m_disasm_info.skip_zeroes = 0; m_disasm_info.skip_zeroes_at_end = 0; m_disasm_info.disassembler_needs_relocs = FALSE; m_disasm_info.display_endian = m_disasm_info.endian = BFD_ENDIAN_BIG; //Don't care m_disasm_info.application_data = NULL; m_disasm_info.print_address_func = objdump_print_address; m_disasm_info.symbol_at_address_func = objdump_symbol_at_address; disassemble_init_for_target(&m_disasm_info); //Wonder if these can be NULL? m_disasm_info.symtab = NULL; m_disasm_info.symtab_size = 0; /* This won't work since we want to step on our own accord bfd_map_over_sections(a_bfd, disassemble_section, &disasm_info); */ #if 0 void bfd_map_over_sections (bfd *abfd, void (*operation) (bfd *, asection *, void *), void *user_storage) { asection *sect; unsigned int i = 0; for (sect = abfd->sections; sect != NULL; i++, sect = sect->next) (*operation) (abfd, sect, user_storage); if (i != abfd->section_count) /* Debugging */ abort (); }