Results 1 to 10 of 10

Thread: How to view OllDbg plugin API names instead of import ordinals?

  1. #1

    How to view OllDbg plugin API names instead of import ordinals?

    Just for fun I wanted to disassemble the plugin called OllyFlow v0.71 by Henryouly.

    First I tried loading it into IDA and prompted to supply the path for the ollydbg.dll module which doesn't exist.
    kao on the tuts4you forum showed me a neat trick and renamed ollydbg.exe to ollydbg.dll to make IDA correctly display the used imported OllyDbg plugin API names instead of the ordinals.

    By creating a .map file and importing it into Olly using the MapConv plugin let me see the missing API names.

    I want to know if it is possible to display these API names in Olly without the assistance of IDA?

    edit: if I hit Ctrl-N I get:


    Hitting Enter on a selected import to find its references I get:


    Then following a reference in the disassembler shows:


    So the names are there but they aren't available for searching using Ctrl-N.
    Is the any way to resolve the import API names?


    Thanks in advance,
    5aLIVE.
    Last edited by 5aLIVE; August 11th, 2013 at 09:10.

  2. #2
    Super Moderator
    Join Date
    Dec 2004
    Posts
    1,456
    Blog Entries
    15
    your attachments are not visible

    i am not sure what names are shown as ordinals in ollyflow

    i just loaded ollydbg on ollydbg and in the debugger ollydbg
    went to executable modules (alt+e) -> right click -> view names (ctrl+N)

    all imports by ollydflow seems to be visible for me

    Code:
    Names in OllyFlow, item 0
     Address=100080F8
     Section=.rdata
     Type=Import
     Name=OLLYDBG.#101__Readmemory
    
    
    Names in OllyFlow, item 5
     Address=10008108
     Section=.rdata
     Type=Import
     Name=OLLYDBG.#172__Sendshortcut

  3. #3
    Hi Blabberer, thank you for taking the time to look at this. I've fixed the image links in my initial post now.

    I am now able to see the OllyFlow plugin API names using the method you describe.

    Here are the API names:


    I didn't make it clear that I wanted to know if it there is a way to view the imported plugin API names when loading the plugin on its own using loaddll.exe. Is it possible to do this?
    Last edited by 5aLIVE; August 12th, 2013 at 06:21.

  4. #4
    Super Moderator
    Join Date
    Dec 2004
    Posts
    1,456
    Blog Entries
    15
    well you made me finish an unfinished project that's been breathing dust for 6 years now
    i started this when someone asked a similar question somewhere else but never got to finish this

    tested on ollyflow.dll only may have bugs use with caution and report back if you find this plugin erased your ollydbg directory
    use ctrl+n again to view modified import names

    Code:
    #include <windows.h>
    #include <stdio.h>
    #include "plugin.h"
    
    HINSTANCE	hinst; 
    HWND		hwmain;
    
    void ord2name(void) {
        char buffer[0x10],label[TEXTLEN];
        ulong importpointer,thunkpointer,address,seladdr;
        t_module *dllwithord = NULL;
        t_dump *dump = (t_dump *)Plugingetvalue(VAL_CPUDASM);	
        seladdr = dump->sel0;
        dllwithord = Findmodule(seladdr);
        for(address = dllwithord->codebase; address < dllwithord->codebase+dllwithord->codesize; address++)
        {
            Readmemory(buffer,address, 16, MM_SILENT|MM_RESTORE);
            if ((*buffer == 0xFF) && (*(buffer+1) == 0x25))
            {
                memset(label,0,256);
                importpointer = 0;
                thunkpointer = 0;
                Readmemory((void *)&importpointer, address+2, 4, MM_SILENT|MM_RESTORE);
                if ((importpointer > dllwithord->codebase)  && (importpointer < dllwithord->base+dllwithord->size))
                {
                    Readmemory((void *)&thunkpointer, importpointer, 4, MM_SILENT|MM_RESTORE);
                    if (Findname(thunkpointer, NM_EXPORT, label) != 0)
                    {
                        Insertname(importpointer,NM_IMPORT,label);
                    }
                }
            }
        }		
        Redrawdisassembler();
    };
    
    BOOL WINAPI DllMain( HINSTANCE hi, DWORD reason, LPVOID reserved )
    {
        UNREFERENCED_PARAMETER( reserved );
        if (reason==DLL_PROCESS_ATTACH)
            hinst=hi;
        return 1;
    };
    
    extc int _export _cdecl ODBG_Plugininit( int ollydbgversion, HWND hw, ulong *features )
    {
        UNREFERENCED_PARAMETER( features );
        if (ollydbgversion<PLUGIN_VERSION)
        {
            return -1;
        }
        Addtolist(0,0,"ollydbg 1.10 import ordinal to import name Plugin ord2name  by blabberer");
        hwmain=hw;
        return 0;
    };
    
    extc int _export _cdecl ODBG_Plugindata( char shortname[32] )
    {
        strcpy_s( shortname, 30, "ord2name" );
        return PLUGIN_VERSION;
    };
    
    extc int _export _cdecl ODBG_Pluginmenu( int origin, char data[4096], void *item )
    {
        UNREFERENCED_PARAMETER( item );
        switch (origin) 
        {
        case PM_MAIN:
            strcpy_s( data, 4000, "0 &ord2name" );
            return 1;
        default: 
            break;
        };
        return 0;
    };
    
    extc void _export cdecl ODBG_Pluginaction(int origin,int action,void *item) 
    {
        UNREFERENCED_PARAMETER( item );
        if (origin==PM_MAIN) 
        {
            switch (action)
            {
            case 0:
                ord2name();
                break;
            default:
                break;
            };
        };
    };
    attachement modified with latest correction

    Code:
    F:\plug110\test\ord2name>fc ord2name.cpp old_ord2name_odbg_plugin\ord2name.cpp
    Comparing files ord2name.cpp and OLD_ORD2NAME_ODBG_PLUGIN\ORD2NAME.CPP
    ***** ord2name.cpp
    void ord2name(void) {
        char buffer[0x10],label[TEXTLEN],decode[TEXTLEN],comment[TEXTLEN];
        ulong importpointer,thunkpointer,address,seladdr;
    ***** OLD_ORD2NAME_ODBG_PLUGIN\ORD2NAME.CPP
    void ord2name(void) {
        char buffer[0x10],label[TEXTLEN];
        ulong importpointer,thunkpointer,address,seladdr;
    *****
    
    ***** ord2name.cpp
                    {
                              Decodeaddress(thunkpointer,seladdr,ADC_DIFFMOD,decode,
    TEXTLEN,comment);
                              Insertname(importpointer,NM_IMPORT,decode);
                    }
    ***** OLD_ORD2NAME_ODBG_PLUGIN\ORD2NAME.CPP
                    {
                        Insertname(importpointer,NM_IMPORT,label);
                    }
    *****
    
    
    F:\plug110\test\ord2name>
    modifed code and attachment posted in a later thread
    Last edited by blabberer; August 21st, 2013 at 01:11. Reason: attachement modifed and posted in a later thread

  5. #5
    Thank you very much indeed for taking this off the dusty shelf.

    It appears to work well, but with one small glitch. If you look at the first three import names in the list you can see that they are missing the prefixed name of the import library, KERNEL32 in this case.

    Last edited by 5aLIVE; August 13th, 2013 at 03:00.

  6. #6
    Super Moderator
    Join Date
    Dec 2004
    Posts
    1,456
    Blog Entries
    15
    thanks for report module names should be visible now check earlier post
    for modified dll

  7. #7
    You're very welcome. The affected module names can now be seen but they are lowercase when all the others are in uppercase.

    I also noticed that the module name for RtlUnwind before your ord2name plugin is run is shown as KERNEL32 after running the plugin it changes to "ntdll" as can be seen below.

    Code:
     
    Before plugin use:
    
    Names in OllyFlow
    Address    Section    Type    (  Name                                    Comment
    008780E4   .rdata     Import  (  KERNEL32.GetACP
    008780E8   .rdata     Import  (  KERNEL32.GetOEMCP
    00878034   .rdata     Import  (  KERNEL32.RtlUnwind
    
    
    After plugin use:
    Names in OllyFlow
    Address    Section    Type    (  Name                                    Comment
    008780E4   .rdata     Import  (  kernel32.GetACP
    008780E8   .rdata     Import  (  kernel32.GetOEMCP
    00878034   .rdata     Import  (  ntdll.RtlUnwind

  8. #8
    Super Moderator
    Join Date
    Dec 2004
    Posts
    1,456
    Blog Entries
    15
    case was easier just or ADC_UPPERCASE job done
    but finding how ollydbg handles forwarded api naming was time consuming

    finally think i ironed out both the issues you reported
    in the process i also added support for mfc ordinals to names

    reversing mfc in ollydbg should be a bit easier with names now instead of #5560

    note to all this plugin gets the names in ollyflow because name is available natively

    for mfc application the name information do not exist in the dll
    so you would need the pdb for each of the mfcXXS.dll where xx can be from 42 to 90 and s can be null and d to indicate mfc version 42 debug dll

    to fetch pdb and load it in ollydbg you can look for my symbol loader plugin i posted earlier in this forum

    mfc ordinal to name tested on one throwaway box and one exe (google mfc crackme first hit crackme by illitirit in dogs on acid forum)
    any bug reports welcome
    also in general if name info is available in either pdb or natively this plugin should handle it now.

    Name:  before_ord2name.PNG
Views: 4191
Size:  35.8 KBName:  after_ord2name.PNG
Views: 3834
Size:  37.1 KB


    Code:
    #include <windows.h>
    #include <stdio.h>
    #include "plugin.h"
    
    // skif 0xff 0x25 jmp <import> opcodes to grab address
    #define SKIPBYTES 2 
    
    HINSTANCE	hinst; 
    HWND		hwmain;
    
    void ord2name(void) 
    {
        unsigned long importpointer = 0;
        unsigned long thunkpointer = 0;
        unsigned long address = 0;
        unsigned long seladdr = 0;
        char buffer[TEXTLEN] = {0}; 
        char label[TEXTLEN] = {0};
        char decode[TEXTLEN] = {0}; 
        char impname[TEXTLEN] = {0};
        char comment[TEXTLEN] = {0};
        char strstr_buff[TEXTLEN] = {0};
        t_module *dllwithord = NULL;
        t_dump *dump = (t_dump *)Plugingetvalue(VAL_CPUDASM);	
        seladdr = dump->sel0;
        dllwithord = Findmodule(seladdr);
        for(address = dllwithord->codebase; address < dllwithord->codebase+dllwithord->codesize; address++)
        {
            Readmemory(buffer,address, MAXCMDSIZE, MM_SILENT|MM_RESTORE);
            if ((*buffer == 0xFF) && (*(buffer+1) == 0x25))
            {
                importpointer = 0;
                thunkpointer = 0;
                char *pch;
                Readmemory((void *)&importpointer, (address + SKIPBYTES ), sizeof(unsigned long), MM_SILENT|MM_RESTORE);
                if ((importpointer > dllwithord->codebase)  && (importpointer < dllwithord->base+dllwithord->size))
                {
                    Readmemory((void *)&thunkpointer, importpointer, sizeof(unsigned long), MM_SILENT|MM_RESTORE);
                    if (Findname(thunkpointer, NM_EXPORT, label) != 0) 
                    {
    
                        Findname(importpointer, NM_IMPORT, impname);  
                        Decodeaddress(thunkpointer,seladdr,ADC_DIFFMOD | ADC_UPPERCASE ,decode,TEXTLEN,comment); 
                        strncpy_s( strstr_buff, decode,sizeof(decode));
                        pch = strstr(strstr_buff , label);
                        *pch = '\0';
                        if( ( strncmp(strstr_buff,impname,strlen(strstr_buff))) == 0)
                        {
                            Insertname(importpointer,NM_IMPORT,decode);
                        }
                    }
                    if (Findname(thunkpointer, NM_LIBRARY, label) != 0) 
                    {
                        Insertname(importpointer,NM_IMPORT,label);
                    }
                }
            }
        }		
        Redrawdisassembler();
    };
    
    BOOL WINAPI DllMain( HINSTANCE hi, DWORD reason, LPVOID reserved )
    {
        UNREFERENCED_PARAMETER( reserved );
        if (reason==DLL_PROCESS_ATTACH)
            hinst=hi;
        return 1;
    };
    
    extc int _export _cdecl ODBG_Plugininit( int ollydbgversion, HWND hw, ulong *features )
    {
        UNREFERENCED_PARAMETER( features );
        if (ollydbgversion<PLUGIN_VERSION)
        {
            return -1;
        }
        Addtolist(0,0,"ollydbg 1.10 import ordinal to import name Plugin ord2name  by blabberer");
        hwmain=hw;
        return 0;
    };
    
    extc int _export _cdecl ODBG_Plugindata( char shortname[32] )
    {
        strcpy_s( shortname, 30, "ord2name" );
        return PLUGIN_VERSION;
    };
    
    extc int _export _cdecl ODBG_Pluginmenu( int origin, char data[4096], void *item )
    {
        UNREFERENCED_PARAMETER( item );
        switch (origin) 
        {
        case PM_MAIN:
            strcpy_s( data, 4000, "0 &ord2name" );
            return 1;
        default: 
            break;
        };
        return 0;
    };
    
    extc void _export cdecl ODBG_Pluginaction(int origin,int action,void *item) 
    {
        UNREFERENCED_PARAMETER( item );
        if (origin==PM_MAIN) 
        {
            switch (action)
            {
            case 0:
                ord2name();
                break;
            default:
                break;
            };
        };
    };
    attached a vs2010 express project with compiled binary below
    ord2name_odbg110_plugin.rar

  9. #9
    Brilliant! The addition of mfc ordinals naming is bound to be a great help. I have a little program in mind that uses MFC to test this on. So I'll report back my findings once I get your winapihelp plugin up and running.

    update #1: Well, I'm not entirely sure which symbol loader plugin you mean so I tried using a patched OllyDbg with symsrv.dll copied to a fresh copy of Olly.

    A snippet from the Ollys log shows:
    C:\WINDOWS\WinSxS\x86_Microsoft.VC80.MFCLOC_1fc8b3b9a1e18e3b_8.0.50727.6195_x-ww_6a5bb789\MFC80ENU.DLL
    Debugging information (Microsoft format) available

    Viewing the modules names after running the ord2name plug has no effect so presumably I am doing something wrong?

    Taking a peek inside mfc80.udd shows ordinals only, by contrast other system .udd files have both ordinals and API names. So it is appears to me that I need a different method of obtaining debug symbols for mfc80.dll. Can you tell me how to grab and load .pdb file please?

    Do I use the method you describe in this thread?

    update #2:
    Well, I can't get patched Olly 1.10 to download symbol files as I had done before. It just seems to halt when loading a system file. So I installed and configured Olly 2.0h and it downloads the .pdb files without a hitch.

    Switching back to Olly 1.10 and renaming the symserv.dll allows the system files to load.

    From the log, I see:
    C:\WINDOWS\WinSxS\x86_Microsoft.VC80.MFC_1fc8b3b9a1e18e3b_8.0.50727.6195_x-ww_150c9e8b\mfc80.dll
    Invalid or compressed Image Export Directory
    Debugging information (Microsoft format) available

    So that looks like what I need.

    Next I type into the modified commandline plugin:
    loadpdb C:\WINDOWS\WinSxS\x86_Microsoft.VC80.MFC_1fc8b3b9a1e18e3b_8.0.50727.6195_x-ww_150c9e8b\mfc80.dll

    The log then shows:

    35 C:\SYMSERV*HTTP://MSDL.MICROSOFT.COM/DOWNLOAD/SYMBOLS
    dbghelp dll loaded and address retrieved
    No Symbols - skipping

    Can you tell me where I am going wrong here?

    update #3: I restored the name of symsrv.dll and copied the file symsrv.yes from the Olly 2.0h to Olly 1.10 and it no longer stalls at a system file.

    So from the log window as before, I see:
    C:\WINDOWS\WinSxS\x86_Microsoft.VC80.MFC_1fc8b3b9a1e18e3b_8.0.50727.6195_x-ww_150c9e8b\mfc80.dll
    Invalid or compressed Image Export Directory
    Debugging information (Microsoft format) available

    And again typing into the modified command line plugin:
    loadpdb C:\WINDOWS\WinSxS\x86_Microsoft.VC80.MFC_1fc8b3b9a1e18e3b_8.0.50727.6195_x-ww_150c9e8b\mfc80.dll

    This time, the log now shows:
    35 C:\SYMSERV*HTTP://MSDL.MICROSOFT.COM/DOWNLOAD/SYMBOLS
    dbghelp dll loaded and address retrieved

    But the ord2name plugin doesn't update the ordinals to API names. Erm... yes it does after I copied your updated plugin to the Olly folder. I'm not sure how that happened, but it did and its fixed now.

    All the API names can now be seen, which is great, with the exception of one stray ordinal as shown below.

    0042D3D0 Import mfc80.#6283

    All the other named ordinals look like this:
    0042D4A8 Import CArchive::Write
    0042D4AC Import CArchive::WriteCount
    0042D47C Import CFileDialog::~CFileDialog
    0042D160 Import CWinApp::WriteProfileInt
    0042D164 Import CWinApp::WriteProfileStringA

    Shouldn't the API names all be prefixed with the module name mfc80? I also notice that all module names remain in lowercase type before and after running the ord2name plugin.
    Last edited by 5aLIVE; August 24th, 2013 at 12:17.

  10. #10
    It also works for OLEAUT32.DLL.

    Before:


    And after:

Similar Threads

  1. Using OllyDbg to view exe & dll
    By lookoverthere in forum The Newbie Forum
    Replies: 4
    Last Post: April 13th, 2011, 12:28
  2. how to view your memory breakpoints?
    By jaked in forum OllyDbg Support Forums
    Replies: 4
    Last Post: September 27th, 2005, 06:56
  3. how to view registers?
    By hippofear in forum OllyDbg Support Forums
    Replies: 2
    Last Post: July 28th, 2005, 20:51
  4. OllDbg: Memory Log
    By nexus in forum The Newbie Forum
    Replies: 2
    Last Post: December 13th, 2003, 13:24
  5. Compare OllDbg and SoftICE for debuging applicatio
    By searchsa in forum OllyDbg Support Forums
    Replies: 1
    Last Post: February 25th, 2003, 05:55

Bookmarks

Posting Permissions

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