blabberer

addsym windbg extension (extension to load names from ida to windbg)

Rate this Entry
Analysing unknown binaries especially malware drivers without symbols is a very tedious affair.

this windbg extension is an effort to reduce the tediousness by transferring the names ida generated to windbg

run the idc script to dump names to a sym file
and use the extension in windbg to resolve the symbols from that file

the idc script is posted below (tested in ida free 5 only and hacks are ida free 5 based if a chris eagle sees the script and knows of a better function that works seamlessly across the versions please comment back )

it loads the inputfile and gets IMAGE_NT_HEADERS->OptionalHeader->BaseofCode and creates a variable to subtract which is the difference between idc function FirstSeg()-BaseofCode (namely ImageBase)

then enumarates Name from FirstSeg() to MaxEA(); and dumps the bare offsets (RVA - IMAGEBASE ) and names to a file c:\\idasym\\GetInputFile().idasym in a format compatible to strtoul&sprintf()

like

00000300,DriverEntry
00017ce5,SomeCrapFunction()
00100000,aURLhttp://malwarebasedotcom/malware/foo.exe

bare offsets are dumped because it doesnt require rebasing in ida and wouldnt have to worry about aslr in windbg

also bare offsets can help in naming virtual allocated blocks
manually create an idasymfile
with offset,name
point it with an address in windbg and all offsets relative to that address will be named appropriately

simply analyse with ida and MakeName (visible in names window | publics) run the idc script in ida to overwrite an existing idasym file or create a new one

do !addsym <modname> <path> in windbg for an updated disassembly

idc script follows

Code:
#include <idc.idc>
static main(void)
{
    auto temp,elfaw_new ,baseofcode,tosubtract,symfile,segstart,segend,i,outfile,symname;
    // idafree doesnt seem to know anything about pe header HACK to get stuff
    temp = fopen(GetInputFilePath(),"rb");
    fseek(temp,0x3c,0);                 //to Read IMAGE_DOS_HEADER->elfaw_new
    elfaw_new = readlong(temp,0);
    fseek(temp,(elfaw_new+0x2c),0);     //to read  _IMAGE_NT_HEADERS->OptionalHeader->BaseofCode
    baseofcode = readlong(temp,0);
    tosubtract = FirstSeg()-baseofcode;
    fclose(temp);

    symfile = "c:\\IDASYM\\" + GetInputFile() + ".idasym";    
    outfile = fopen( symfile,"w");
    if (!outfile)
    {
        Message("failed to create file %s\n check if c:\\idasym folder exists",symfile);
    }
    else
    {
        Message("creating idasym file %s\n",symfile);
        segstart = 0;
        do
        {
            segstart = NextSeg(segstart);
            segend = SegEnd(segstart);
            for ( i = 0 ; i < segend-segstart ; i++)
            {
                symname = Name( segstart+i ) ;
                // discarding DOC AND UNDOC dummy names (does pro ida have convinience funcs ? 
                //must be tedious without them :( )             
                if (   
                    (symname != "" )                    &&  
                    (substr(symname,0,4) != "sub_")     &&  
                    (substr(symname,0,7) != "locret_")  && 
                    (substr(symname,0,4) != "loc_" )    && 
                    (substr(symname,0,4) != "off_" )    &&  
                    (substr(symname,0,4) != "seg_" )    &&  
                    (substr(symname,0,4) != "asc_" )    &&
                    (substr(symname,0,5) != "byte_" )   &&
                    (substr(symname,0,5) != "word_" )   &&       
                    (substr(symname,0,6) != "dword_" )  &&
                    (substr(symname,0,5) != "qword_" )  &&
                    (substr(symname,0,4) != "flt_" )    &&  
                    (substr(symname,0,4) != "dbl_" )    &&  
                    (substr(symname,0,6) != "tbyte__" ) &&
                    (substr(symname,0,5) != "stru_" )   &&  
                    (substr(symname,0,5) != "algn_" )   &&
                    (substr(symname,0,6) != "oword_" )  &&      
                    (substr(symname,0,4) != "unk_" ) 
                    )
                { 
                    fprintf(outfile,"%08x,%s\n", ((segstart+i)-tosubtract)  , Name(  segstart+i ) );
                }
            }
        }while (segend != BADADDR);
        fclose(outfile);
    }
}

source code for windbg extension follows

Code:
#include <engextcpp.hpp>
#include < iostream >
#include < fstream >
#include < string >
#include <tchar.h>

using namespace std;

class EXT_CLASS : public ExtExtension
{
public:
    EXT_COMMAND_METHOD(addsym);
};

EXT_DECLARE_GLOBALS();

// takes two arguments first is an exprssion second is a string (path of idasymbol file)
// !addsym   modulename viz nt / address viz 0x804d7200 etc  c:\idasym\xxx.idasym

EXT_COMMAND( 
    addsym,
    "windbg extension to use names that are generated by ida \n do .reload /f MODULE.ext=base,size 
     prior to using this extension",
    "{;e;MODULE;An expression or address like nt / 0x804d7000 }{;x;path;path to idasym file \n
     viz c:\\idasym\\MODULE.EXT.idasym}" 
    )
{
    ULONG offset;    
    ifstream ifs ,fs;
    char *symoff;
    string inbuff,buff;
    int i = 0;
    int j = 1;
    ULONG64 imagebase = GetUnnamedArgU64(0);    
    ifs.open(GetUnnamedArgStr(1));
    if ( (ifs.rdstate() & ifstream::failbit ) != 0)
    {
        Out("failed to open idasym file\n");
        goto exit;
    }
    do
    {
        i++;
    }while ( getline(ifs,inbuff) != NULL);
    Out("total symbols in idasym file is %d press ctrl+break to interrupt symbol resolving \n",i-1);
    ifs.close();
    fs.open(GetUnnamedArgStr(1));
    if ( (fs.rdstate() & ifstream::failbit ) != 0)
    {
        Out("failed to open idasym file\n");
        goto exit;
    }
    i = 0;
    while ( getline(fs,buff) != NULL)
    {
        i++;
        if (m_Control3->GetInterrupt() == S_OK)
        {
            break;
        }
        offset = strtoul(buff.c_str(),&symoff,16);
        m_Symbols3->AddSyntheticSymbol((imagebase + offset ),4,symoff+1,DEBUG_ADDSYNTHSYM_DEFAULT,NULL);  
        if (i == 500)
        {
            Out("%d symbols resolved\n",i*j);
            i = 0;
            j++;
        }
    }
    Out("total %d symbols resolved \n",((500*(j-1))+i) );
    fs.close();
exit: 
    Out("done\n");
}
usage of extesnion follows (aswsp.sys of avastfree picked at random )

Code:
lkd> .load addsym
lkd> !addsym
ERROR: !addsym: extension exception 0x80070057.
    "Missing required argument '<MODULE>'"
lkd> !addsym /?
!addsym <MODULE> <path>
  <MODULE> - An expression or address like nt / 0x804d7000 
  <path> - path to idasym file 
           viz c:\idasym\MODULE.EXT.idasym (consumes remainder of input string)
windbg extension to use names that are generated by ida 
do .reload /f MODULE.ext=base,size prior to using this extension
lkd> !addsym aswsp
ERROR: !addsym: extension exception 0x80040205.
    "Unable to evaluate expression 'aswsp'"
lkd> lm m aswsp*
start    end        module name
lkd> .reload /f aswsp.sys
ERROR: Module load completed but symbols could not be loaded for \??\C:\WINDOWS\system32\drivers\aswSP.sys
lkd> lm m aswsp*
start    end        module name
a968e000 a96ef600   aswSP      (no symbols)           
lkd> x aswsp!*
lkd> !addsym aswsp
ERROR: !addsym: extension exception 0x80070057.
    "Missing required argument '<path>'"
lkd> !addsym aswsp c:\idasym\aswsp.sys.idasy
failed to open idasym file
done
lkd> !addsym aswsp c:\idasym\aswsp.sys.idasym
total symbols in idasym file is 1457 press ctrl+break to interrupt symbol resolving 
500 symbols resolved
1000 symbols resolved
total 1457 symbols resolved 
done
lkd> lm m aswsp*
start    end        module name
a968e000 a96ef600   aswSP      (no symbols)           
lkd> x aswsp!*
a969be30 aswSP!nullsub_1 = <no type information>
a96a980e aswSP!nullsub_2 = <no type information>
a96b6ed4 aswSP!memcpy = <no type information>
a96b6ee0 aswSP!memset = <no type information>
a96b6eec aswSP!strncmp = <no type information>
a96b6ef8 aswSP!ObReferenceObjectByName = <no type information
idc script . source and compiled dll attached below
Attached Thumbnails Attached Files

Submit "addsym windbg extension (extension to load names from ida to windbg)" to Digg Submit "addsym windbg extension (extension to load names from ida to windbg)" to del.icio.us Submit "addsym windbg extension (extension to load names from ida to windbg)" to StumbleUpon Submit "addsym windbg extension (extension to load names from ida to windbg)" to Google

Updated March 18th, 2014 at 17:02 by blabberer

Categories
Uncategorized

Comments