在 IDA 中自动查找 MFC 类内存布局?

逆向工程 艾达 微信
2021-06-11 13:24:41

背景

我正在使用 IDA 对使用 MFC100 的 DLL 进行逆向工程。

我正在阅读Reversing an MFC application: How to find class memory layouts? https://stackoverflow.com/questions/13126694/idapro-loading-c-header-files-into-idapro-for-structures,其中两个答案建议转到正确的头文件并复制和粘贴结构定义(这很难,因为 C++ 有模板和 vftable。另外,嵌套类......),一个答案建议制作一个测试程序并使用 IDA 反编译它以获得结构声明,这是不可能的,因为程序没有(似乎)存储结构声明。(见下文)


考虑一个小例子。CStdioFile和一些 MFC 的东西)

#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();

}

使用的命令行(假设上面的文件名为a.cpp):

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

在这里,我故意使用/debug使逆向工程更容易。

当 IDA 询问我是否要加载 PDB 文件时,我选择了“是”。

然而:

使用 IDA 加载可执行文件时,“本地类型”窗口和“结构”窗口均未显示任何有关CFile. 因此,使用它们的函数使用偏移量来引用成员。

CFile::CFile 的伪代码

在这种特殊情况下,我使用CFile,但我认为其他类也类似。

我知道我可以进入头文件atlmfc\来读取类定义并计算成员名称,但这太乏味了,IDA 可能已经内置了它。所以:


问题

有什么办法可以快速给IDA下定义CFile

1个回答

主要问题是:/Zi是必需的。仅仅包括/debug是不够的。那是因为类型信息存储在编译器.pdb文件中。另请参阅编译器 PDB 文件和链接器 PDB 文件 - 堆栈溢出

命令行看起来像这样:

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

请注意,这/Zi意味着/debug(因此无需指定/debug何时/Zi包含在内)

提示:没有必要构建可执行文件。只需编译文件本身就足够了(使用/c)。


这样做时可能会遇到一些其他问题:

  1. 错误信息

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

    出现在“输出窗口”中。

    解决方案:只需安装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.
    

    是 IDA 6.9 中修复的错误

  3. 这些类只是没有出现在“本地类型”选项卡中。

    检查输出窗口以查看是否出现问题 1 中提到的错误消息。


顺便说一句,使用这种方法可以将任何 C++ 类型导入 IDA,而不仅仅是 MFC。