예제 #1
0
static guint32
lookup_var (test_entry_t *entry, const char *name)
{
	if (!strcmp ("file-size", name))
		return entry->data_size;
	if (!strcmp ("pe-signature", name))
		return get_pe_header (entry) - 4;
	if (!strcmp ("pe-header", name))
		return get_pe_header (entry); 
	if (!strcmp ("pe-optional-header", name))
		return get_pe_header (entry) + 20; 
	if (!strcmp ("section-table", name))
		return get_pe_header (entry) + 244; 
	if (!strcmp ("cli-header", name))
		return get_cli_header (entry);
	if (!strcmp ("cli-metadata", name)) 
		return get_cli_metadata_root (entry);
	if (!strcmp ("tables-header", name)) {
		guint32 metadata_root = get_cli_metadata_root (entry);
		guint32 tilde_stream = get_metadata_stream_header (entry, 0);
		guint32 offset = READ_VAR (guint32, entry->data + tilde_stream);
		return metadata_root + offset;
	}

	printf ("Unknown variable in expression %s\n", name);
	exit (INVALID_VARIABLE_NAME);
}
예제 #2
0
static guint32
get_cli_header (test_entry_t *entry)
{
	guint32 offset = get_pe_header (entry) + 20; /*pe-optional-header*/
	offset += 208; /*cli header entry offset in the pe-optional-header*/
	return translate_rva (entry, READ_VAR (guint32, entry->data + offset));
}
//--------------------------------------------------------------------------
bool win32_debmod_t::set_debug_hook(ea_t base)
{
  // the debug hook for borland is located at the very beginning of
  // the program's text segment, with a clear signature before
  peheader_t pe;
  ea_t peoff = get_pe_header(base, &pe);
  if ( peoff == BADADDR )
    return false;

  ea_t text = base + pe.text_start;
  uchar buf[4096];
  if ( _read_memory(text, buf, sizeof(buf)) != sizeof(buf) )
    return false;

  ssize_t bcc_hook_off = find_bcc_sign(buf, sizeof(buf));
  if ( bcc_hook_off == -1 )
    return false;

  uint32 bcc_hook;
  if ( _read_memory(text+bcc_hook_off, &bcc_hook, 4) != 4 )
    return false;

  // now the bcc_hook might be already relocated or not.
  // it seems that vista loads files without relocating them for
  // the 'open file' dialog box. This is an heuristic rule:
  if ( bcc_hook < base + pe.text_start || bcc_hook > base + pe.imagesize )
    return false;

  const uint32 active_hook = 2; // borland seems to want this number
  return _write_memory(bcc_hook, &active_hook, 4) == 4;
}
//--------------------------------------------------------------------------
// calculate dll image size
// since we could not find anything nice, we just look
// at the beginning of the DLL module in the memory and extract
// correct value from the file header
uint32 win32_debmod_t::calc_imagesize(ea_t base)
{
  peheader_t nh;
  ea_t offset = get_pe_header(base, &nh);
  if ( offset == BADADDR )
    return 0;
  return nh.imagesize;
}
예제 #5
0
static guint32
translate_rva (test_entry_t *entry, guint32 rva)
{
	guint32 pe_header = get_pe_header (entry);
	guint32 sectionCount = READ_VAR (guint16, entry->data + pe_header + 2);
	guint32 idx = pe_header + 244;

	while (sectionCount-- > 0) {
		guint32 size = READ_VAR (guint32, entry->data + idx + 8);
		guint32 base = READ_VAR (guint32, entry->data + idx + 12);
		guint32 offset = READ_VAR (guint32, entry->data + idx + 20);

		if (rva >= base && rva <= base + size)
			return (rva - base) + offset;
		idx += 40;
	}
	printf ("Could not translate RVA %x\n", rva);
	exit (INVALID_RVA);
}
//--------------------------------------------------------------------------
// get name from export directory in PE image in debugged process
bool win32_debmod_t::get_pe_export_name_from_process(
  ea_t imagebase,
  char *name,
  size_t namesize)
{
  peheader_t pe;
  ea_t peoff = get_pe_header(imagebase, &pe);
  if ( peoff != BADADDR && pe.expdir.rva != 0)
  {
    ea_t ea = imagebase + pe.expdir.rva;
    peexpdir_t expdir;
    if ( _read_memory(ea, &expdir, sizeof(expdir)) == sizeof(expdir) )
    {
      ea = imagebase + expdir.dllname;
      name[0] = '\0';
      _read_memory(ea, name, namesize);  // don't check the return code because
      // we might have read more than necessary
      if ( name[0] != '\0' )
        return true;
    }
  }
  return false;
}
예제 #7
0
exe_info_t* get_exe_info(FILE* stream, uint32_t offset)
{
    exe_info_t* exe_info = (exe_info_t*) malloc(sizeof(exe_info_t));

    if (! exe_info)
        return NULL;

    // Get MZ header
    exe_info->mz_header = get_mz_header(stream, offset);
    if (! exe_info->mz_header)
    {
        free(exe_info);
        return NULL;
    }

    // Set additional parameters (1 block = 512 bytes, 1 paragraph = 16 bytes)
    exe_info->extra_offset = 0x0200 * exe_info->mz_header->blocks_in_file;

    if ((exe_info->extra_offset)
    &&  (exe_info->mz_header->bytes_in_last_block > 0x0000)
    &&  (exe_info->mz_header->bytes_in_last_block < 0x0200))
        exe_info->extra_offset -= 0x0200 - exe_info->mz_header->bytes_in_last_block;

    exe_info->data_offset  = 0x0010 * exe_info->mz_header->paragraphs_in_header;
    exe_info->is_segmented = (exe_info->mz_header->reloc_table_offset == RELOCATION_TABLE_OFFSET) ? 1 : 0;
    exe_info->ne_header    = NULL;
    exe_info->le_header    = NULL;
    exe_info->lx_header    = NULL;
    exe_info->pe_header    = NULL;

    if (exe_info->is_segmented)
    {
        // Get segmented info
        load_segmented_info(stream, &exe_info->segmented_offset, &exe_info->segmented_syncword);
    }
    else
    {
        exe_info->segmented_offset   = 0x0000;
        exe_info->segmented_syncword = 0x0000;
    }

    if ((! exe_info->segmented_offset) || (! exe_info->segmented_syncword))
        return exe_info;

    switch (exe_info->segmented_syncword)
    {
        case NE_HEADER_SYNC:
            exe_info->ne_header = get_ne_header(stream, exe_info->segmented_offset);
            break;

        case LE_HEADER_SYNC:
            exe_info->le_header = get_le_header(stream, exe_info->segmented_offset);
            break;

        case LX_HEADER_SYNC:
            exe_info->lx_header = get_lx_header(stream, exe_info->segmented_offset);
            break;

        case PE_HEADER_SYNC:
            exe_info->pe_header = get_pe_header(stream, exe_info->segmented_offset);
            break;

        default:
            break;
    }

    return exe_info;
}