asm_program_t* byte_insn_to_asmp(bfd_architecture arch, address_t addr, unsigned char *bb_bytes, unsigned int len) { asm_program_t *prog = fake_prog_for_arch(arch); unsigned char *bytes = (unsigned char*)bfd_alloc(prog->abfd, len); // copy the string, because the old one is freed when we return memcpy(bytes, bb_bytes, len); Instruction *inst = new Instruction; inst->address = addr; inst->length = len; inst->bytes = bytes; struct disassemble_info *disasm_info = &prog->disasm_info; disasm_info->buffer = bytes; disasm_info->buffer_vma = addr; disasm_info->buffer_length = len; disasm_info->section = NULL; asm_function_t *asmf = new asm_function_t; asmf->name = ""; asmf->start_addr = addr; asmf->end_addr = addr+len; asmf->instmap[addr] = inst; prog->functions[addr] = asmf; return prog; }
instmap_t * sqlite3_fileid_to_instmap(char *filename, int fileid) { char sql[1024]; char sql_seg[1024]; int r; int r_seg; sqlite3_stmt *ppstmt; sqlite3_stmt *ppstmt_seg; vector<vine_block_t *> results; Segment *seg, *ts; instmap_t *ret = new instmap_t; // FIXME: get arch from sqlite3 file ret->prog = fake_prog_for_arch(bfd_arch_i386); ret->prog->segs = NULL; struct disassemble_info *disasm_info = &ret->prog->disasm_info; sqlite3 *db; r = sqlite3_open(filename, &db); if(r){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); exit(1); } snprintf(sql_seg, sizeof(sql_seg), "SELECT start_address, end_address from" " segments where file_id = %d;", fileid); r_seg = sqlite3_prepare_v2(db, sql_seg, -1, &ppstmt_seg, NULL); if(r_seg != SQLITE_OK || ppstmt_seg == NULL){ fatal("sqlite3_fileid_to_instmap", "sqlite3_prepare failed for segs: %s", sqlite3_errmsg(db)); } // iterate through all segments, creating the appropriate // disassemble information. while(1){ r_seg = sqlite3_step(ppstmt_seg); if(r_seg == SQLITE_DONE) break; if(r_seg != SQLITE_ROW) break; sqlite_int64 startaddr = sqlite3_column_int64(ppstmt_seg, 0); sqlite_int64 endaddr = sqlite3_column_int64(ppstmt_seg, 1); // Set up segment. assert(( endaddr-startaddr) > 0); seg = (Segment *) malloc(sizeof(Segment)); memset(seg, 0, sizeof(Segment)); seg->data = (bfd_byte *) malloc(endaddr-startaddr); memset(seg->data, 0, endaddr-startaddr); seg->datasize = (endaddr-startaddr); seg->start_addr = startaddr; seg->end_addr = endaddr; seg->is_code = 1; // Next 4 lines are similar to what: // init_disasm_info(&disasm_info, seg); // does. disasm_info->buffer = seg->data; disasm_info->buffer_vma = startaddr; disasm_info->buffer_length = seg->datasize; disasm_info->section = NULL; // Query database for instructions // in segment snprintf(sql,sizeof(sql), "SELECT address,length,bytes" " from instrs where file_id = %d and address >= %llu and" " address <= %llu;", fileid, startaddr, endaddr); r = sqlite3_prepare_v2(db, sql, -1, &ppstmt, NULL); if(r != SQLITE_OK || ppstmt == NULL){ fatal("sqlite3_fileid_to_instmap", "sqlite3_prepare failed for instrs: %s", sqlite3_errmsg(db)); } // add seg to segments list. seg->next = NULL; if(ret->prog->segs == NULL) { ret->prog->segs = seg; } else{ ts = ret->prog->segs; // Note: this is O(n^2) in the number of segments, but n is usually small, // so I'm leaving it as is. while(ts->next != NULL) ts = ts->next; ts->next = seg; } while(1){ // Populate segment r = sqlite3_step(ppstmt); if(r == SQLITE_DONE) break; if(r != SQLITE_ROW) break; uint32_t bytes[4]; sqlite_int64 addr = sqlite3_column_int64(ppstmt, 0); sqlite_int64 len = sqlite3_column_int64(ppstmt, 1); const unsigned char * bytestr = sqlite3_column_text(ppstmt,2); char buf[3]; for(int j = 0; j < len; j++){ uint8_t byte = 0; sscanf((char *)bytestr, "%2x", &byte); bytestr +=2; seg->data[(addr-startaddr)+j] = byte; } Instruction *inst = get_inst_of(ret->prog, addr); if(inst != NULL){ ret->imap.insert(pair<address_t, Instruction *>(inst->address, inst)); } else { print_debug("warning", "Instruction %llu is NULL. skipping\n", addr); } } } return ret; }