Welcome to the new Woodmann RCE Messageboards Regroupment
Please be patient while the rest of the site is restored.

To all Members of the old RCE Forums:
In order to log in, it will be necessary to reset your forum login password ("I forgot my password") using the original email address you registered with. You will be sent an email with a link to reset your password for that member account.

The old vBulletin forum was converted to phpBB format, requiring the passwords to be reset. If this is a problem for some because of a forgotten email address, please feel free to re-register with a new username. We are happy to welcome old and new members back to the forums! Thanks.

All new accounts are manually activated before you can post. Any questions can be PM'ed to Kayaker.

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

Support forums for OllyDbg 32-bit Assembler-Level Debugger.
Developed by Oleh Yuschuk (http://www.ollydbg.de)
Locked
5aLIVE
Senior Member
Posts: 215
Joined: Tue Dec 16, 2003 7:35 am

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

Post 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.
blabberer
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post 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
5aLIVE
Senior Member
Posts: 215
Joined: Tue Dec 16, 2003 7:35 am

Post 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?
blabberer
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post 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
5aLIVE
Senior Member
Posts: 215
Joined: Tue Dec 16, 2003 7:35 am

Post 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]
blabberer
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post by blabberer »

thanks for report module names should be visible now :) check earlier post
for modified dll
5aLIVE
Senior Member
Posts: 215
Joined: Tue Dec 16, 2003 7:35 am

Post 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

blabberer
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post 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]
Attachments
ord2name_odbg110_plugin.rar
(145.14 KiB) Downloaded 122 times
after_ord2name.PNG
before_ord2name.PNG
5aLIVE
Senior Member
Posts: 215
Joined: Tue Dec 16, 2003 7:35 am

Post 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.
5aLIVE
Senior Member
Posts: 215
Joined: Tue Dec 16, 2003 7:35 am

Post 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]
Locked