Page 1 of 1

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

Posted: Mon Aug 05, 2013 2:37 pm
by 5aLIVE
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:
[img]http://i41.tinypic.com/2rp5g5w.jpg[/img]

Hitting Enter on a selected import to find its references I get:
[img]http://i41.tinypic.com/10oh9vs.png[/img]

Then following a reference in the disassembler shows:
[img]http://i41.tinypic.com/30jmona.jpg[/img]

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.

Posted: Sun Aug 11, 2013 5:03 am
by blabberer
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: Select all

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

Posted: Sun Aug 11, 2013 9:59 am
by 5aLIVE
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:
[IMG]http://i43.tinypic.com/nmymgn.png[/IMG]

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?

Posted: Mon Aug 12, 2013 7:10 pm
by blabberer
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: Select all


#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: Select all


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

Posted: Tue Aug 13, 2013 2:50 am
by 5aLIVE
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.

[IMG]http://i44.tinypic.com/jt9wz8.png[/IMG]

Posted: Tue Aug 13, 2013 6:02 am
by blabberer
thanks for report module names should be visible now :) check earlier post
for modified dll

Posted: Tue Aug 13, 2013 6:47 am
by 5aLIVE
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: Select all

 
[B]Before plugin use:[/B]

Names in OllyFlow
Address    Section    Type    (  Name                                    Comment
008780E4   .rdata     Import  (  KERNEL32.GetACP
008780E8   .rdata     Import  (  KERNEL32.GetOEMCP
00878034   .rdata     Import  (  KERNEL32.RtlUnwind


[B]After plugin use:[/B]
Names in OllyFlow
Address    Section    Type    (  Name                                    Comment
008780E4   .rdata     Import  (  kernel32.GetACP
008780E8   .rdata     Import  (  kernel32.GetOEMCP
00878034   .rdata     Import  (  ntdll.RtlUnwind


Posted: Wed Aug 21, 2013 1:08 am
by blabberer
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.

[ATTACH]2801[/ATTACH][ATTACH]2802[/ATTACH]

Code: Select all

#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
[ATTACH]2803[/ATTACH]

Posted: Wed Aug 21, 2013 9:56 am
by 5aLIVE
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.

Posted: Sun Sep 01, 2013 12:44 pm
by 5aLIVE
It also works for OLEAUT32.DLL. :)

Before:
[IMG]http://i41.tinypic.com/2cddh05.png[/IMG]

And after:
[IMG]http://i44.tinypic.com/xgacs2.png[/IMG]