3

Background

I was using IDA to reverse engineer an DLL which uses MFC100.

I was reading Reversing an MFC application: How to find class memory layouts? and https://stackoverflow.com/questions/13126694/idapro-loading-c-header-files-into-idapro-for-structures , where two answers suggest going to the correct header file and copy&paste the struct defintion (which is hard, because C++ has templates and vftable. Also, nested classes...), and one answer suggests making a test program and use IDA to decompile it to get the struct declaration, which is not possible because programs don't (appear to) store struct declaration. (see below)


Consider a small example. (with CStdioFile and some MFC thing)

#include <afxwin.h>

class HelloApplication : public CWinApp
{
public:
    virtual BOOL InitInstance();
};

HelloApplication HelloApp;

class HelloWindow : public CFrameWnd
{       
    CButton* m_pHelloButton;
public: 
    HelloWindow();
};


BOOL HelloApplication::InitInstance()
{       
    m_pMainWnd = new HelloWindow(); 
    m_pMainWnd->ShowWindow(m_nCmdShow); 
    m_pMainWnd->UpdateWindow(); 
    return TRUE;
}


HelloWindow::HelloWindow()
{       
    Create(NULL,            
        "Hello World!",         
        WS_OVERLAPPEDWINDOW|WS_HSCROLL,             
        CRect(0,0,140,80));     
    m_pHelloButton = new CButton();
    m_pHelloButton->Create("Hello World!",WS_CHILD|WS_VISIBLE,CRect(20,20,120,40),this,1);

    // some code for file reading
    CStdioFile Inputfile, Outputfile;
    CFileException FileExc;
    UINT nOpenFlags;
    CString s;
    nOpenFlags = CFile::modeRead;
    if (!Inputfile.Open("Console.txt", nOpenFlags, &FileExc)) {
        FileExc.ReportError();
        return;
    }
    nOpenFlags = CFile::modeWrite | CFile::modeCreate;
    if (!Outputfile.Open("Output.txt", nOpenFlags, &FileExc)) {
        FileExc.ReportError();
        return;
    }
    while (Inputfile.ReadString(s))
        Outputfile.WriteString(s+'\n');
    Inputfile.Close();
    Outputfile.Close();

}

Command line used (assuming the file above is named a.cpp):

cl.exe a.cpp /EHsc /link /debug /subsystem:windows

Here, I intentionally use /debug to make reverse engineering easier.

When IDA ask me if I want to load the PDB file, I chose "Yes".

However:

When loading the executable with IDA, neither the "Local Types" window nor the "Structures" window shows anything about CFile. Therefore, the functions which use them, use offsets to refer to the members.

Pseudocode of CFile::CFile

In this particular case I use CFile, but I assume it's similar for other classes.

I know I can go to the header file in atlmfc\ to read the class definition and work out the member names, but that's too tedious and IDA may have it built-in already. So:


The question

Is there any way to quickly give IDA the definition of CFile?

user202729
  • 675
  • 1
  • 4
  • 14

1 Answers1

1

The main problem is: /Zi is required. Including just /debug is not enough. That's because the type information is stored in the compiler .pdb file. See also Compiler PDB file and the Linker PDB file - Stack Overflow.

The command line can looks like this:

cl.exe /Zi a.cpp /EHsc /link /subsystem:windows

Note that /Zi implies /debug (therefore it's not necessary to specify /debug when /Zi is included)

Hint: It's not necessary to build the executable. Just compile the file itself is enough (using /c).


There are some other problems that one may get while doing that:

  1. The error message

    << It appears that MS DIA SDK is not installed.
    Please try installing "Microsoft Visual C++ 2008 Redistributable Package / x86" >>
    

    appears in the "Output window".

    Solution: just install Microsoft Visual C++ 2008 Redistributable Package (x86).

  2. Internal IDA Error
    

    Oops! internal error 984 occured. Further work is not possible and IDA will close.

    It's a bug that is fixed in IDA 6.9.

  3. The classes just don't appear in "Local Types" tab.

    Check the output window to see if the error message mentioned in problem 1 appears.


By the way, it is possible to import any C++ type into IDA using this method, not just specifically MFC.

user202729
  • 675
  • 1
  • 4
  • 14