// Returns a fake asm_program_t for use when disassembling bits out of memory asm_program_t* fake_prog_for_arch(enum bfd_architecture arch) { int machine = 0; // TODO: pick based on arch asm_program_t *prog = new asm_program_t; prog->abfd = bfd_openw("/dev/null", NULL); assert(prog->abfd); bfd_set_arch_info(prog->abfd, bfd_lookup_arch(arch, machine)); //not in .h bfd_default_set_arch_mach(prog->abfd, arch, machine); bfd_set_arch_info(prog->abfd, bfd_lookup_arch(arch, machine)); init_disasm_info(prog); return prog; }
static void initialize_sections(asm_program_t *prog, bfd_vma base) { bfd_vma offset = 0; struct disassemble_info *disasm_info = &prog->disasm_info; assert(prog); bfd *abfd = prog->abfd; unsigned int opb = bfd_octets_per_byte(abfd); disasm_info->octets_per_byte = opb; init_disasm_info(prog); section_t **nextseg = &prog->segs; asection *section; /* Set to NULL in case there are zero segments. */ *nextseg = NULL; /* Look for the section loaded into the lowest memory address */ if (base != -1) { offset = base - asmir_get_base_address(prog); //fprintf(stderr, "Adjusting by %Lx\n", offset); } for(section = abfd->sections; section; section = section->next) { section_t *seg; bfd_byte *data; bfd_vma datasize = bfd_get_section_size_before_reloc(section); if(datasize == 0) continue; section->vma += offset; data = bfd_alloc2(abfd, datasize, sizeof(bfd_byte)); bfd_get_section_contents(abfd, section, data, 0, datasize); seg = bfd_alloc(abfd, sizeof(section_t)); seg->data = data; seg->datasize = datasize; seg->start_addr = section->vma; seg->end_addr = section->vma + datasize/opb; seg->section = section; seg->is_code = !!(section->flags & SEC_CODE); seg->next = NULL; *nextseg = seg; nextseg = &seg->next; } }
/* initialize bincode */ bincode_t *initialize_bincode(const char *file) { bfd *abfd; bincode_t *bin; //char *target = "x86_64-unknown-linux-gnu"; char *target = "i686-pc-linux-gnu"; bfd_init(); if (!bfd_set_default_target(target)) { bs_dbgmsg(" (!) bfd_set_default_target()\n"); return NULL; } if ((abfd = bfd_openr(file, target)) == NULL) { bs_dbgmsg(" (!) bfd_openr(): %s\n", file); return NULL; } if (!bfd_check_format(abfd, bfd_object)) { bs_dbgmsg(" (!) bfd_check_format()\n"); bfd_close(abfd); return NULL; } if((bin = malloc(sizeof(bincode_t))) == NULL) { bs_errmsg(" (!) malloc(): bin\n"); exit(EXIT_FAILURE); } bin->filename = strdup(abfd->filename); bin->abfd = abfd; bin->filesize = bfd_get_size(abfd); bin->start_addr = bfd_get_start_address(abfd); init_disasm_info(bin->abfd, &bin->disasm_info); bin->disasm_info.application_data = bin; initialize_section(bin); return bin; }
/* Uses trace_read_memory, which assumes set_trace_bytes is used to update for each instruction. */ asm_program_t* asmir_trace_asmp_for_arch(enum bfd_architecture arch) { int machine = 0; // TODO: pick based on arch asm_program_t *prog = malloc(sizeof(asm_program_t)); assert(prog); prog->abfd = bfd_openw("/dev/null", NULL); if (!prog->abfd) { bfd_perror("Unable to open fake bfd"); } assert(prog->abfd); bfd_set_arch_info(prog->abfd, bfd_lookup_arch(arch, machine)); //not in .h bfd_default_set_arch_mach(prog->abfd, arch, machine); bfd_set_arch_info(prog->abfd, bfd_lookup_arch(arch, machine)); init_disasm_info(prog); // Use a special read memory function prog->disasm_info.read_memory_func = trace_read_memory; return prog; }
// FIXME: the memory that gets allocated here is never freed. void initialize_sections(bfd *abfd, asm_program_t *prog) { struct disassemble_info *disasm_info = &prog->disasm_info; unsigned int opb = bfd_octets_per_byte(abfd); disasm_info->octets_per_byte = opb; init_disasm_info(prog); Segment *segs = NULL; for(asection *section = abfd->sections; section != (asection *) NULL; section = section->next){ Segment *seg, *ts; int is_code = 0; bfd_byte *data = NULL; bfd_vma datasize = bfd_get_section_size_before_reloc(section); if(datasize == 0) continue; data = (bfd_byte *) xalloc((size_t) datasize, (size_t) sizeof(bfd_byte)); bfd_get_section_contents(abfd, section, data, 0, datasize); seg = (Segment *) xalloc(1, sizeof(Segment)); seg->data = data; seg->datasize = datasize; seg->start_addr = section->vma; seg->end_addr = section->vma + datasize/opb; seg->section = section; if(section->flags & SEC_CODE == 0) is_code = 0; else is_code = 1; seg->is_code = is_code; if(is_code){ /*seg->status = (unsigned char *) xalloc((seg->end_addr - seg->start_addr), sizeof(char)); */ /* seg->insts = (Instruction **) xalloc((seg->end_addr - seg->start_addr), sizeof(Instruction *)); //init_disasm_info(&disasm_info, seg); for(bfd_vma pc = seg->start_addr; pc < seg->end_addr; ++pc){ Instruction *inst = get_inst_of(prog, pc, seg); // DJB: Hack for stmxcsr and ldmxcsr instrs as found // in atphttpd instr 806a36e //if(inst->opcode[0] == 0xae && inst->opcode[1] == 0xf) // inst->length++; seg->insts[pc - seg->start_addr] = inst; } */ seg->next = NULL; if(segs == NULL) segs = seg; else{ ts = segs; while(ts->next != NULL) ts = ts->next; ts->next = seg; } } prog->sections[seg->start_addr] = seg; } prog->segs = segs; }
void init_disasm_info(asm_program_t *prog) { init_disasm_info(prog->abfd, &prog->disasm_info); prog->disasm_info.application_data = prog; }