Results 1 to 3 of 3

Thread: !addsym Windbg - IDA Symbol extension Redux

  1. #1
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries

    !addsym Windbg - IDA Symbol extension Redux

    !addsym Windbg - IDA Symbol extension Redux

    Once upon a time in days of yore, a young hobbit created a Windbg extension of great value and mystery, forged in hardship and sacrifice, and was all but forgotten.

    This is to be a retelling of that tale and where it takes us today.

    It begins with a blog post by Blabberer six years ago and ends with my rebuilding of the extension in Visual Studio 2013 and the results.

    I think this extension is a great idea, I'd like to see it evolve. I'm having a problem, some of the symbols are loaded into Windbg but not all and not correctly.

    The extension was borrowed by at least two others, with credit, one with a few minor changes and another released as an IDAPython script

    Adds IDA symbols as WinDbg synthetic symbols

    IDAScript to create Symbol file which can be loaded in WinDbg via AddSyntheticSymbol


    I started with the EngExtCpp-style extension sample project extcpp.cpp provided in the Windows Kits 8.1 x64, and popped it into VisualStudio 2013. First step was to Upgrade VC++ Compilers
    changing Platform Toolset to 'v120' (was 'v110').

    Then I copied Blabs extension code (ikonst updated) and added it to the sample project as another export EXT_COMMAND_METHOD(addsym);

    The only compile issue I really had was this one

    extcpp.cpp(96): error C2678: binary '!=' : no operator found which takes a left-hand operand of type
    'std::basic_istream<char,std::char_traits<char>>' (or there is no acceptable conversion)

    The error was underlined on the != character on 2 similar lines:

    while (getline(ifs, inbuff) != NULL);

    The error code doc is here

    Something to do with the left hand side being a const object, a function declared in <string>, and the value != NULL on the right hand side.

    This is wacky C++. I read various solutions involving namespaces, overloading, nothing I wanted to hear or understood. Finally realized that in this case at least, the while{} statement could be changed to eliminate the comparison completely with

    } while (getline(ifs, inbuff));

    What the hell, the return value NULL is no good with strings?

    Anyway, that pretty much fixed it and I could compile the Windbg extension as x32 or x64.


    Next step was to create the .idasym file from the IDC script. It's purpose is to transfer the Names ida generated to windbg. I also took that as meaning to include user-defined functions and perhaps variable names. The EngExtCpp extension uses AddSyntheticSymbol to accomplish that.

    The idc script itself parses names as such:
    symname = Name( segstart+i ) ;

    It works as expected, though the code could be modified to exclude certain segments from analysis for example. I don't think it picks up user-defined variable names. The python version above only picks up name changes that you prefix with something, so it limits the symbols to only what you might want.

    I did make one change, rather than hardcoding the directory where the .idasym file will be created I used this to just create it in the same IDA exe/database folder:
    symfile = GetInputFilePath() + ".idasym";

    The .idasym file seems to be correct in producing a list of "names", but the problem seems to be that not all of them are imported into Windbg.


    As an example, I disassembled Strings64.exe and renamed the first 2 functions to see if they would be transferred to Windbg.

    .load myextcpp.dll
    0:000> .chain
    Extension DLL search Path:
        C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x64\winext
    Extension DLL chain:
        myextcpp.dll: image 6.3.9600.17336, API 1.0.0, built Mon Apr 27 00:44:48 2020
            [path: C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x64\winext\myextcpp.dll]
    0:000> !addsym /?  // btw I didn't know that's how you called the damned built in EngExtCpp help!!
    !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
    // .reload [Options] [Module [= Address [, Size [, 
    0:000> .reload /f image00000001_3f420000.exe=000000013f420000,29000
    *** ERROR: Module load completed but symbols could not be loaded for image00000001_3f420000.exe
    Note that Strings64.exe is called 'image00000001_3f420000' by Windbg, for some reason it doesn't recognize the process name and uses its base address as an image name.
    0:000> lm
    start             end                 module name
    00000001`3f420000 00000001`3f449000   image00000001_3f420000   (no symbols)    
    0:000> !myextcpp.addsym image00000001_3f420000 C:\Utilities\Strings\Strings64.exe.idasym
    total symbols in idasym file is 1321 press ctrl+break to interrupt symbol resolving 
    500 symbols resolved
    1000 symbols resolved
    total 1321 symbols resolved 
    Good up until this point but here's the beginning addresses of what symbols were imported, only starting at 3f4313e8, which is somewhere in a random proc in the middle of the file, in the middle of an opcode no less, then it starts with names in the .idata section.

    0:000> x image00000001_3f420000!*
    00000001`3f4313e8 image00000001_3f420000!_positive = <no type information>
    00000001`3f433000 image00000001_3f420000!RegQueryValueExW = <no type information>
    00000001`3f433008 image00000001_3f420000!RegQueryValueExA = <no type information>

    Here are the first 5 lines from the .idasym file, where it should have started to import symbols:


    I had a similar problem with a compiled x32 extension on a win32 app, it only began importing names from the .idata section

    0:000> x winid!*
    00436000 winid!RegQueryValueExA = <no type information>

    OK, that's too much writing for now, but I wanted to go over everything I did, and figure out what I did wrong.


  2. #2
    Super Moderator
    Join Date
    Dec 2004
    Blog Entries
    It Was completely 32bit then (IDAFREE5 ,WIN7X86 , vcvars32 windbg32)

    it seems you are testing 64bit so did you recompile the src for x64

    yes checking for NULL isn't recommended (string::getline(istream,string) returns a void* converted to a bool so checked for NULL
    passed compilation in old compilers newer version don't accept it

    what you did By removing the != NULL is the right construct

    if you are hell bent on writing super duper error checking read this excellent article

    anyway I just recompiled it vs2017 x64 (as usual I use the dev cmd prompt in vscode terminal ) and it seems to work properly

    created a new directory and copied the existing src def and bat files

    mkdir addsym64
    cd addsym64
    copy ..\addsym\addsym.cpp .\addsym64.cpp
    copy ..\addsym\addsym.def .\addsym64.def
    copied two bat files  one to initialize vs one to compile and link extension
    dir contents

    :\>dir /b
    added help EXPORTS to addsym64.def and renamed EXPORT addsym to addsym64

    diff addsym64.def ..\addsym\addsym.def
    <       help
    <     addsym64
    >     addsym

    included engextcpp.cpp instead of engextcpp.hpp to avoid implementing the mandatory exports (init,uninit,notify,help) in addsym64.cpp

    renamed command from addsym to addsym64

    removed the != NULL part

    diff addsym64.cpp ..\addsym\addsym.cpp
    < #include <engextcpp.cpp>
    > #include <engextcpp.hpp>
    <     EXT_COMMAND_METHOD(addsym64);
    >     EXT_COMMAND_METHOD(addsym);
    <     addsym64,
    >     addsym,
    <     } while (getline(ifs, inbuff));
    >     } while (getline(ifs, inbuff) != NULL);
    <     while (getline(fs, buff))
    >     while (getline(fs, buff) != NULL)
    the contents of runvs.bat

    :\>cat runvs64.bat
    %comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
    the contents of bld.bat

    :\>cat bld.bat
    @ECHO off
    set INCLUDE=%INCLUDE%;C:\Program Files (x86)\Windows Kits\10\Debuggers\inc
    set LIB=%LIB%;C:\Program Files (x86)\Windows Kits\10\Debuggers\lib
    set LINKLIBS=dbgeng.lib
    cl /LD /Zi /W4  /EHsc /nologo /Od %1.cpp /link /RELEASE /DEF:addsym64.def %LINKLIBS%
    we are ready to compile and link a 64 bit extension

    :\>C:\WINDOWS\system32\cmd.exe /k "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
    ** Visual Studio 2017 Developer Command Prompt v15.9.22
    ** Copyright (c) 2017 Microsoft Corporation
    [vcvarsall.bat] Environment initialized for: 'x64'
    :\>bld.bat addsym64
    C:\Program Files (x86)\Windows Kits\10\Debuggers\inc\engextcpp.cpp(1849): warning C4245: 'argument': conversion from 'int' to 'ULONG64', signed/unsigned mismatch
       Creating library addsym64.lib and object addsym64.exp
    :\>dir /s /b *.dll
    ok it built it seems lets test

    open strings.exe in idafree 7 run the idc

    creating idasym file c:\IDASYM\strings64.exe.idasym

    :\>cdb -c ".load .\addsym64.dll;!addsym64 strings64 c:\idasym\strings64.exe.idasym;x strings64!main;q" f:\sysint\strings64.exe | f:\git\usr\bin\awk.exe "/Reading/,/quit/"
    0:000> cdb: Reading initial command '.load .\addsym64.dll;!addsym64 strings64 c:\idasym\strings64.exe.idasym;x strings64!main;q'
    total symbols in idasym file is 1319 press ctrl+break to interrupt symbol resolving
    *** ERROR: Module load completed but symbols could not be loaded for f:\sysint\strings64.exe
    500 symbols resolved
    1000 symbols resolved
    total 1319 symbols resolved
    00007ff6`2cc03310 strings64!main = <no type information>

  3. #3
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries
    Well that works great now on an x64 app! I went back and used your original code, which I apologize for not doing first. I had used the ikonst version which was said to be modified to work with kernel drivers whereas the original code did not (which doesn't really make sense considering your example in the blog post), but I guess it didn't work for me. I haven't tried a kernel driver yet. This was all done with IDA 7 free on Win7.

    Functions as well as variables renamed in IDA now show up as symbols in Windbg, very useful. Nice work Blabs

Similar Threads

  1. Replies: 5
    Last Post: May 7th, 2014, 15:49
  2. Ida pro 6.1 remote debugging Windbg
    By dbenchtk in forum Advanced Reversing and Programming
    Replies: 0
    Last Post: October 20th, 2013, 18:35
  3. Dumping memory with Windbg
    By AttonRand in forum The Newbie Forum
    Replies: 0
    Last Post: July 9th, 2012, 15:27
  4. Windbg breakpoint with condition
    By rxxxxxx333 in forum The Newbie Forum
    Replies: 0
    Last Post: January 12th, 2011, 01:19
  5. Windbg “dt” output converter
    By ZaiRoN in forum Blogs Forum
    Replies: 5
    Last Post: January 2nd, 2008, 11:29


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts