All pastes #921855 Raw Edit

Unnamed

public text v1 · immutable
#921855 ·published 2008-02-28 12:09 UTC
rendered paste body
#include <idc.idc>

#define USERLOAD_IDC

//
static get_str(fd, strs)
{
  auto name, saveoff;
  saveoff = ftell(fd);
  name = readlong( fd, 0 );
  if (name == 0)
  {
    name = readlong( fd, 0 );
    //Message("name offset: %04X\n", name);
    fseek( fd, strs + name, 0 );
    name = readstr( fd );
  }
  else
  {
    fseek( fd, saveoff, 0 );
    name = readstr( fd );
    if (strlen( name ) > 7)
    {
      name = substr( name, 0, 8 );
    }
  }
  fseek( fd, saveoff+8, 0 );
  return name;
}

static userload( input_file, real_file, filetype )
{
  auto file_name, fd;
  auto temp, imgbase;
  auto header, syms, secs, strs;
  auto nsyms, nsecs;
  auto i;

  auto chars;

  auto text, vtext;

  auto name, sc, sec, val, type, auxno;

  if (filetype != FT_PE)
  {
    Message( "!!! Not an executable file. Aborting... (%d) !!!\n", filetype );
    return -1;
  }

  Message( "\n\n-------- PE/COFF Symbol Name Parser ------------------\n\n" );

  file_name = input_file;
  Message( "Parsing input file '%s'\n", file_name );

  fd = fopen( file_name, "rb" );
  if (fd == 0)
  {
    Message( "!!! Unable to open input file !!!\n" );
    return -1;
  }

  // Reading first two bytes. Expecting to see 'MZ'
  temp = readshort( fd, 0 );
  if (temp != 0x5a4d)
  {
    Message( "!!! Not a PE/COFF executable file !!!\n" );
    fclose( fd );
    return -1;
  }

  // Reading location of PE/COFF Header
  fseek( fd, 0x3c, 0 );
  header = readlong( fd, 0 );

  fseek( fd, header, 0 );
  temp = readlong( fd, 0 );
  if (temp != 0x4550)
  {
    Message( "!!! Unsupported PE/COFF file !!!\n" );
    fclose( fd );
    return -1;
  }

  Message( "PE/COFF Header is at offset 0x%x\n", header );

  // Reading location of section and symbol tables.
  fseek( fd, header + 4 + 2, 0 ); // signature (4 bytes) + header + 2
  nsecs = readshort( fd, 0 );
  Message( "Number of sections in file is 0x%x\n", nsecs );

  fseek( fd, header + 4 + 16, 0 );
  temp = readshort( fd, 0 );       //size of optional header

  secs = header + 4 + 20 + temp;
  Message( "Sections table located at 0x%x\n", secs );

  fseek( fd, header + 4 + 20 + 0x1C, 0 );
  imgbase = readlong( fd, 0 );

  fseek( fd, header + 4 + 8, 0 );
  syms = readlong( fd, 0 );
  if (syms == 0)
  {
    Message( "!!! No symbol table. This is possible for some EXE files. Cannot proceed !!!\n" );
    fclose( fd );
    return -1;
  }
  Message( "Symbol table located at 0x%x\n", syms );

  fseek( fd, header + 4 + 12, 0 );
  nsyms = readlong( fd, 0 );
  Message( "Number of symbols is 0x%x\n", nsyms );

  strs = syms + (nsyms * 18);
  Message( "Strings table located at 0x%x\n", strs );

  // Running through symbols...
  for (i = 0; i < nsyms; i++)
  {
    //Message("Symbol: %03X, file offset: %08X\n", i, syms + (i * 18));
    fseek( fd, syms + (i * 18), 0 );
    name = get_str(fd, strs);
    val = readlong( fd, 0 );
    sec = readshort( fd, 0 );
    type = readshort( fd, 0 );
    sc = fgetc( fd );
    auxno = fgetc( fd );

    Message( "Symbol %X: name - '%s', type - 0x%x, value - 0x%x, section - 0x%x, sc - 0x%x, auxno - 0x%x\n", 
       i, name, type, val, sec, sc, auxno );
    
    if (sec<=0 || sec>=0xF000)
    {
      Message("Special section number: %d\n", sec);
    }
    else
    {
      fseek( fd, secs + ((sec-1) * 40) + 12, 0 );
      vtext = imgbase + readlong( fd, 0 );
      //Message( "Section %d starts at 0x%x\n", sec, vtext );      
      MakeNameEx( vtext + val, name, SN_CHECK | SN_NOWARN );
      Message("%a: %s\n", vtext + val, name);
    }
    if (auxno>0)
    {
      Message("Skipping %d aux syms\n", auxno);
      i = i + auxno;
    }
  }

  Message( "\n-------- PE/COFF Symbol Name Parser ------------------\n\n" );

  fclose( fd );
}

static main()
{
  userload( GetInputFilePath(), "", FT_PE );
}