欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

逆向MFC程序

程序员文章站 2022-04-02 18:00:43
@[toc] 1 MFC执行流程 1.1 环境支持 vs 2017 afxwin.h,afxcdialogex.h 1.2 分析 ​ 在 vs 调试窗口中 有一个“反汇编窗口”,同样也可以下断点,步过步入等。 则可以汇编层可以详细的 步过/步入 每一个 详细的步骤 得以知道详细的系统/库的API调用 ......

@

1 mfc执行流程

1.1 环境支持

  • vs 2017
  • afxwin.h,afxcdialogex.h

1.2 分析

​ 在 vs 调试窗口中 有一个“反汇编窗口”,同样也可以下断点,步过步入等。

则可以汇编层可以详细的 步过/步入 每一个 详细的步骤---得以知道详细的系统/库的api调用、获取栈回溯情况等等

1.3 实践探索

1.3.1 创建一个mfc程序

主要重写cwinapp::initinstance() 和 自定义个一个对话框类(以实现一个简单界面)

注意: 对话框资源文件我没列出来,因为只有一个对话框和一个按钮点击

我的demo如下:

  • 自定义程序入口
//cmywinapp.cpp
#include "mywinapp.h"
#include"wnddlg.h"

mywinapp app;
mywinapp::mywinapp(){}
mywinapp::~mywinapp(){}
begin_message_map(mywinapp,cwinapp)
end_message_map()
bool mywinapp::initinstance()
{
    wnddlg * twnd = new wnddlg;
    m_pmainwnd = (cdialog*)twnd;
    twnd->domodal();
    cwinapp::initinstance();
    return 0;
}
  • 自定义对话框
// wnddlg.cpp: 实现文件
//

#include "stdafx.h"
#include "wnddlg.h"
#include "afxdialogex.h"
#include"resource.h"

// wnddlg 对话框
implement_dynamic(wnddlg, cdialogex)
wnddlg::wnddlg(cwnd* pparent /*=nullptr*/): cdialogex(idd_dialog1, pparent){}
wnddlg::~wnddlg(){}
void wnddlg::dodataexchange(cdataexchange* pdx)
{
    cdialogex::dodataexchange(pdx);
}
begin_message_map(wnddlg, cdialogex)
    on_bn_clicked(idc_button1, &wnddlg::onbnclickedbutton1)
end_message_map()
// wnddlg 消息处理程序
void wnddlg::onbnclickedbutton1()
{
    messagebox("hello leibso-huanghai/黄海");
}

1.3.2 下关键断点并调试

比如这儿 我想探索关键函数 initinstance()的位置

  • 1.关键断点

    逆向MFC程序

    注意: domodal()是模态对话框,当你断这儿的时候f10,只有当退出的时候才会步过

  • 2.调出反汇编窗口

    逆向MFC程序

  • 3.查看调用堆栈窗口

    逆向MFC程序

    解析: 很清晰的看出mfc程序的调用顺序是winmain()-->afxwinmain()-->initinstance()

  • 结束了吗?

    并没有。。

1.4 转向mfc库源文件中观测

  • 继续上面的步骤在反汇编窗口键入f10
  • 直到走出这个initinstance()
  • 我们会发现来到了一片绿洲-- 库代码
  • 鼠标中键往上滑动发现当前的源文件 路径+名
  • 这就是我们的 mfc库源文件之一

逆向MFC程序

  • 注意: 这里的路径有可能不是你正确的路径(因为可能重复卸载安装了vs的缘故)

    • 解决:使用文件搜索工具 (我这里使用的是everything)-- 搜索处此名为winmain.cpp

      逆向MFC程序

      这个标记的就是了

  • 然后用vs打开这个文件,你会发现你的断点就在上面清晰的源代码就出来了

逆向MFC程序

2 逆向

我们看了源代码后可以发现如此复杂的想从入口函数一步一步往后找有点浪费精力

所以--使用特征码

2.1 特征码的选择(比如我这里还是想找到initinstance())

那在刚才的反汇编窗口中找到关键汇编代码,行数越多越精确

注:关键代码 不能包含地址之类的这样可能会出问题,因为可能会有重定位之类数据不确定的问题

如图:

逆向MFC程序

那:

这几条语句就可以作为我们的特征码

mov         eax,dword ptr [edx]  
mov         esi,esp  
mov         ecx,dword ptr [eax+58h]  
mov         dword ptr [ebp-24h],ecx  
mov         edi,esp  
mov         ecx,dword ptr [ebp-24h] 

2.2 使用调试工具(od) 搜索特侦码

使用od动态调试 搜索以下代码序列,就可以得到这个函数的地方了

如图:

逆向MFC程序

之后就可以下断点 动态分析了

咐语

其他平台程序的逆向也可以使用这种方法:搭建平台-->写一个demo程序-->熟悉流程-->找目标特征码