IDA’s .IDS Files Part II

Originally posted 06/07/2007 on OpenRCE.org

While reverse engineering a SymbianOS worm last February, I noticed that IDA wouldn’t convert some by-ordinal imports from SymbianOS DLLs into their real names:


.idata:00405678 ;
.idata:00405678 ; Imports from PBKENG[101f4cce].DLL
.idata:00405678 ;
.idata:00405678   IMPORT __imp_PBKENG_18  ; DATA XREF: .text:off_404568
.idata:0040567C   IMPORT __imp_PBKENG_21  ; DATA XREF: .text:off_4045A8
.idata:00405680   IMPORT __imp_PBKENG_43  ; DATA XREF: .text:off_404518
.idata:00405684   IMPORT __imp_PBKENG_72  ; DATA XREF: .text:off_404588
.idata:00405688   IMPORT __imp_PBKENG_73  ; DATA XREF: .text:off_404578
.idata:0040568C   IMPORT __imp_PBKENG_101 ; DATA XREF: .text:off_404528
.idata:00405690   IMPORT __imp_PBKENG_110 ; DATA XREF: .text:off_404538
.idata:00405694   IMPORT __imp_PBKENG_173 ; DATA XREF: .text:off_404508
.idata:00405698   IMPORT __imp_PBKENG_180 ; DATA XREF: .text:off_404548
.idata:0040569C   IMPORT __imp_PBKENG_185 ; DATA XREF: .text:off_404558
.idata:004056A0   IMPORT __imp_PBKENG_254 ; DATA XREF: .text:off_404598

I installed the SymbianOS SDK and then came up with a convoluted series of scripts wrapped around the GNU tool suite that would extract the function names and their ordinals from the relevant .LIB, and then create an IDC script that would rename any import-by-ordinal to its real name.  A friend chuckled at this Rube Goldberg-esque contraption and suggested that I use the IDSUTIL package instead.

It couldn’t be easier:  just type “ar2idt pbkeng.lib && zipids pbkeng.idt” to produce an .IDS file for the pbkeng.lib static library.  Now inside of IDA, go to File->Load File->IDS File, and select the .IDS file that was created.  Alternatively, you can put this in the %IDA%\ids\epoc6\arm directory to have IDA load it automatically (after a restart).  Here are the results of applying it:


.idata:00405678 ;
.idata:00405678 ; Imports from PBKENG[101f4cce].DLL
.idata:00405678 ;
.idata:00405678 ; CPbkContactItem::CardFields(void)const
.idata:00405678   IMPORT CardFields__C15CPbkContactItem
.idata:00405678                           ; DATA XREF: .text:off_404568
.idata:0040567C ; CPbkContactEngine::CloseContactL(long)
.idata:0040567C   IMPORT CloseContactL__17CPbkContactEnginel
.idata:0040567C                           ; DATA XREF: .text:off_4045A8
.idata:00405680 ; CPbkContactEngine::CreateContactIteratorLC(int)
.idata:00405680   IMPORT CreateContactIteratorLC__17CPbkContactEnginei
.idata:00405680                           ; DATA XREF: .text:off_404518
.idata:00405684 ; CPbkFieldInfo::FieldId(void)const
.idata:00405684   IMPORT FieldId__C13CPbkFieldInfo
.idata:00405684                           ; DATA XREF: .text:off_404588

To address the specific problem that’s been coming up lately, let’s see how to convert the MFC .DEF file into an .IDS file.  First, here’s a snippet from the .DEF file:


; This is a part of the Microsoft Foundation Classes C++ library.
; Copyright (C) 1992-1998 Microsoft Corporation
; All rights reserved.

LIBRARY MFC42

EXPORTS
DllGetClassObject @ 1 PRIVATE
DllCanUnloadNow @ 2 PRIVATE
DllRegisterServer @ 3 PRIVATE
DllUnregisterServer @ 4 PRIVATE
?classCCachedDataPathProperty@CCachedDataPathProperty@@2UCRuntimeClass@@B @ 5 DATA
?classCDataPathProperty@CDataPathProperty@@2UCRuntimeClass@@B @ 6 DATA
; MFC 4.2(final release)
??0_AFX_CHECKLIST_STATE@@QAE@XZ @ 256 NONAME

We can see that lines starting with a “;” are comments, any line containing the string ” @ ” is an actual export declaration, and everything else is part of the DEF file structure.  We only want the export declarations.  Let’s run a quick sed/awk script on the .DEF file:

sed -e '/^ *;/d' MFC42.def | sed -n -e '/ @ /p' | gawk '{ print $3 " Name="$1 }' > MFC42.idt && zipids MFC42.idt

The first part of that command erases any comment-lines (those that begin with any number of spaces and then a semi-colon); the second part accepts any line that contains the string ” @ “; and the third part converts the results into the .IDT file format.

To complete the job, we need to manually add a line that says “0 Name=MFC42.dll” to the top of the file.  Also, be sure to name the .IDT file the same as the DLL/LIB base name, e.g. mfc42.idt.  As before, we then run zipids on it to produce an .IDS file, which can be loaded into IDA and/or put into the %IDA%\ids directory to have it loaded automatically when appropriate.

Before applying the .IDS file:

.idata:4BB710DC   extrn __imp_MFC42_6467:dword ; DATA XREF: MFC42_6467

Afterwards:

.idata:4BB710DC ; public: __thiscall AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2(class AFX_MODULE_STATE *)
.idata:4BB710DC   extrn ??0AFX_MAINTAIN_STATE2@@QAE@PAVAFX_MODULE_STATE@@@Z:dword

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: