示例#1
0
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;
}
示例#2
0
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;
}