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 );
}