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?

  • If you compile your windows program with debug information and importing the resulting debug info .pdb file with the corresponding menu command ( hex-rays.com/products/ida/support/idadoc/430.shtml ) you'll probably be able to see the CFIle definition. – w s Sep 20 '18 at 11:33
  • @ws Won't loading the file import the PDB automatically? – user202729 Sep 20 '18 at 11:59
  • IDA will usually ask if you want to load the PDB. – mrexodia Sep 20 '18 at 12:39
  • It still doesn't work. (post updated...) – user202729 Sep 20 '18 at 12:45
  • Is it IDA free by any chance ? Is it possible that you are running IDA on Linux ? – w s Sep 20 '18 at 14:54
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.