Base knowledge
概念
- MFC 应用程序是基于Microsoft 基础类(MFC) 库的Windows 可执行应用程序.MFC 可执行程序通常分为五类:标准 Windows 应用程序、对话框、基于窗体的应用程序、资源管理器样式的应用程序和 Web 浏览器样式的应用程序。
- 程序中的字符串都会以C开头,例如
CCorrect
Step to reverse
- 识别

程序运行有gui

- 使用xspy跟踪程序窗口(将图中放大镜拖到需逆向的程序中)

得到以下内容
温馨提示:鼠标双击选中地址后,鼠标右键立刻复制
target window pid: 0x000008cc, thread tid: 0x00005820
hook thread tid: 0x00005820
----------获取ATL/WTL相关信息-------------
got DWLP_DLGPROC = 0x009D43B3
got GWLP_WNDPROC = 0x009D8F56
----------获取MFC相关信息-------------
mfc version:110, static linked?: true, debug?: false
CWnd::FromHandlePermanent = 0x009D9F0F
CWnd = 0x00F9FCB0
HWND: 0x00180C7E
class:00F9FCB0(CDialogEx,size=0xb8)
CDialogEx:CDialog:CWnd:CCmdTarget:CObject
[vtbl+0x00]GetRuntimeClass = 0x009D3F27(Junk_Instruction.exe+ 0x003f27 )
[vtbl+0x01]dtor = 0x009D1FF0(Junk_Instruction.exe+ 0x001ff0 )
[vtbl+0x02]Serialize = 0x009D1190(Junk_Instruction.exe+ 0x001190 )
[vtbl+0x03]OnCmdMsg = 0x00A9BF79(Junk_Instruction.exe+ 0x0cbf79 )
[vtbl+0x04]OnFinalRelease = 0x009DAB97(Junk_Instruction.exe+ 0x00ab97 )
[vtbl+0x05]IsInvokeAllowed = 0x00AE6AE8(Junk_Instruction.exe+ 0x116ae8 )
[vtbl+0x06]GetDispatchIID = 0x00A96898(Junk_Instruction.exe+ 0x0c6898 )
[vtbl+0x07]GetTypeInfoCount = 0x00A751CB(Junk_Instruction.exe+ 0x0a51cb )
[vtbl+0x08]GetTypeLibCache = 0x00A751CB(Junk_Instruction.exe+ 0x0a51cb )
[vtbl+0x09]GetTypeLib = 0x009DE573(Junk_Instruction.exe+ 0x00e573 )
[vtbl+0x0A]GetMessageMap = 0x009D20C0(Junk_Instruction.exe+ 0x0020c0 )
[vtbl+0x0B]GetCommandMap = 0x009DE549(Junk_Instruction.exe+ 0x00e549 )
[vtbl+0x0C]GetDispatchMap = 0x009DE555(Junk_Instruction.exe+ 0x00e555 )
[vtbl+0x0D]GetConnectionMap = 0x009DE54F(Junk_Instruction.exe+ 0x00e54f )
[vtbl+0x0E]GetInterfaceMap = 0x009DA126(Junk_Instruction.exe+ 0x00a126 )
[vtbl+0x0F]GetEventSinkMap = 0x009DE55B(Junk_Instruction.exe+ 0x00e55b )
[vtbl+0x10]OnCreateAggregates = 0x00A3B480(Junk_Instruction.exe+ 0x06b480 )
[vtbl+0x11]GetInterfaceHook = 0x00A96898(Junk_Instruction.exe+ 0x0c6898 )
[vtbl+0x12]GetExtraConnectionPoints= 0x00A96898(Junk_Instruction.exe+ 0x0c6898 )
[vtbl+0x13]GetConnectionHook = 0x00A96898(Junk_Instruction.exe+ 0x0c6898 )
message map=0x00B4F724(Junk_Instruction.exe+ 0x17f724 )
msg map entries at 0x00B4F730(Junk_Instruction.exe+ 0x17f730 )
OnMsg:WM_SYSCOMMAND(0112),func= 0x009D21F0(Junk_Instruction.exe+ 0x0021f0 )
OnMsg:WM_PAINT(000f),func= 0x009D2300(Junk_Instruction.exe+ 0x002300 )
OnMsg:WM_QUERYDRAGICON(0037),func= 0x009D2410(Junk_Instruction.exe+ 0x002410 )
OnCommand: notifycode=0000 id=03e9,func= 0x009D2420(Junk_Instruction.exe+ 0x002420 )
OnCommand: notifycode=0000 id=03e9,func= 0x009D2420(Junk_Instruction.exe+ 0x002420):
OnCommand 是 MFC 中用来处理窗口控件的命令消息的宏函数。它通常与 按钮点击、菜单选择、控件事件(比如输入框变化)等消息有关。
notifycode=0000 这个值表示控件产生的 通知码(Notification Code),用于标识特定的消息类型。其中0表示button
func= 0x009D2420 收到oncommand命令后调用的函数(注意baseaddr,这里是0x009D2420 - 0x002420)
OnMsg:WM_SYSCOMMAND(0112),func= 0x009D21F0(Junk_Instruction.exe+ 0x0021f0):
OnMsg: 处理的窗口信息.WM_SYSCOMMAND(0112)表示信息号为0112,表示点击关闭按钮(X)、最大化/最小化按钮等
- 注意此处可以定义非系统消息常量,进而通过sendmessage给当前窗口,使其执行对应函数.如图:

可以通过以下脚本,向窗口发送信息
// 1.cpp : 定义控制台应用程序的入口点。
//注意是MFC运行。
#include "stdafx.h"
#include<stdio.h>
#include<string.h>
#include "windows.h"
int main()
{
HWND h = FindWindowA("944c8d100f82f0c18b682f63e4dbaa207a2f1e72581c2f1b",NULL);
//HWND h = FindWindowA(NULL, "Flag就在控件里");
//HWND h = FindWindowA("944c8d100f82f0c18b682f63e4dbaa207a2f1e72581c2f1b", "Flag就在控件里");
//这里用到两个关键函数,一个是获取窗口句柄函数,第二个就是根据句柄发送消息函数。获取句柄的FindWindowA中第一个可以传入类名,第二个可以传入标题,因为我们两个都有,所以任意一个都可以锁定程序窗口。
if (h)
{
SendMessage(h, 0x464, NULL, NULL);
//发送函数中第二个是区别其他消息的常量值,这里题目用了自定义常量值,所以我们要对应一致。
}
getchar();
return 0;
}