本贴所提及的主要程序有三个:
//cpp文件中
BEGIN_MESSAGE_MAP
END_MESSAGE_MAP
//头文件中
DECLARE_MESSAGE_MAP
virtual const AFX_MSGMAP* GetMessageMap() const;
void CMyMFCSpyDlg::OnSpyMFC()
{
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, "WaitForMySpyHookDll");
HHOOK hhk = NULL;
if(!IsWindow(m_hWndDest))
{
AfxMessageBox("NOT a valid handle");
}
if (!::SendMessage(m_hWndDest, WM_QUERYAFXWNDPROC, 0, 0))
{
AddHead2OutputBox("WM_QUERYAFXWNDPROC: Dest App is NOT a MFC application.\r\n");
return;
}
BeginWaitCursor();
/* 挂钩、注入、并等待返回结果 */
//挂钩
hhk = SetMFCSpyHook();
if(!hhk)
{
AfxMessageBox("设置钩子失败");
}
//通知钩子处理事务
::SendMessage(m_hWndDest, WM_NULL, WP_BEGINSPY, LP_BEGINSPY);
//等待处理完毕
WaitForSpyDll();
//通过FileMapObject读取目标信息
ShowDestInf();
::UnhookWindowsHookEx(hhk);
EndWaitCursor();
}
void WriteMsgMapInf2File(AFX_MSGMAP *pMsgMap)
{
AFX_MSGMAP_ENTRY MsgEntryEnd = {0, 0, 0, 0, 0, 0};
const AFX_MSGMAP_ENTRY *pEntrys = NULL;
UINT nTagMsgIndex = -1;
HANDLE hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, g_szDatFilePath);
if (hMap == NULL)
return;
char* pszBuff = (char*)::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS,
0, 0, //偏移
0 /*映射所有*/);
if (pszBuff == NULL)
{
return;
}
if (pMsgMap == NULL || g_pCWnd == NULL)
{
strcpy(pszBuff, "ITEM_END_ITEM_END_ITEM_END");
::UnmapViewOfFile(pszBuff);
::CloseHandle(hMap);
return;
}
// 定长 200
#define ItemLen 200
//写窗口对象内容
sprintf(pszBuff, "CWnd Address:0x%p, VT Address:0x%p", g_pCWnd, * ((int*)g_pCWnd) );
pszBuff += ItemLen;
//写消息映射表内容
pEntrys = pMsgMap->lpEntries;
while(memcmp(pEntrys, &MsgEntryEnd, sizeof(MsgEntryEnd)) != 0)
{
nTagMsgIndex = GetTagMsgIndex(pEntrys->nMessage);
if (nTagMsgIndex != -1)
{
sprintf(pszBuff, "%-20s", g_tagWndMsg[nTagMsgIndex].strMsg);
sprintf(pszBuff + 20, "nCode:%p, nID:%p, pfn:%p",
pEntrys->nCode,
pEntrys->nID,
pEntrys->pfn);
pszBuff += ItemLen;
}
pEntrys++;
}
strcpy(pszBuff, "ITEM_END_ITEM_END_ITEM_END");
::UnmapViewOfFile(pszBuff);
::CloseHandle(hMap);
}
AFX_MSGMAP * GetRlsMsgMap(CWnd *pWnd)
{
AFX_MSGMAP *pMsgMap = NULL;
__asm
{
push ecx;
push ebx;
mov ebx, pWnd;
mov ecx, dword ptr [ebx];
mov ecx, dword ptr [ecx + 0x30];
call ecx;
mov pMsgMap, eax;
pop ebx;
pop ecx;
}
return pMsgMap;
}
#define ToTagMsg(WndMsg) {WndMsg, #WndMsg} ,
struct tagWndMsg
{
DWORD dwMsg;
const char * strMsg;
};
tagWndMsg g_tagWndMsg[] = {
ToTagMsg(WM_FLIP)
ToTagMsg(WM_NULL)
};
//宏替换为:
tagWndMsg g_tagWndMsg[] = {
{WM_FLIP, "WM_FLIP"} ,
{WM_NULL, "WM_NULL" } ,
};
%{
#include <stdio.h>
#include <string.h>
/* This program
* converts the macros of windows message
* to tagWndMsg containing the value and string
*/
unsigned int g_nMsgNum = 0;
%}
MSGMACRO WM_[A-Z_]*
%x BLOCKCOMMENT
%%
\n { /* new line */ }
"//".* { /* eat up line comment */ }
"/*" { BEGIN BLOCKCOMMENT; }
<BLOCKCOMMENT>[^*\n]+ { /* eat up anything that's not a '*' */ }
<BLOCKCOMMENT>"*" { /* eat up '*'s not followed by '/'s */ }
<BLOCKCOMMENT>\n { /* new line */ }
<BLOCKCOMMENT>"*/" { BEGIN INITIAL; }
{MSGMACRO} { printf(" ToTagMsg(%s)\n", yytext); g_nMsgNum++;}
. { /* eat up whatever else */ }
%%
int main()
{
char *szMacro = "#define ToTagMsg(WndMsg) {WndMsg, #WndMsg} ,\r\n";
char *szTagMsg = "struct tagWndMsg\n"
"{\n"
" DWORD dwMsg;\n"
" const char * strMsg;\n"
"};\r\n";
char *szBeginAry = "tagWndMsg g_tagWndMsg[] = {\n";
char *szEndAry = "\n};";
printf(szMacro);
printf(szTagMsg);
printf(szBeginAry);
yylex();
printf(szEndAry);
printf("//Total Msg:%d", g_nMsgNum);
}
int yywrap()
{
return 1;
}
GenMsgAry.exe < WinUser.h > Dest.cpp
//mfc42d.Dll版本
PVOID GetDbgFromHandleAddr(HMODULE hModule)
{
return GetProcAddress(hModule, (LPCSTR) 2220);
}
//mfc42.Dll版本
PVOID GetRlsFromHandleAddr(HMODULE hModule)
{
return GetProcAddress(hModule, (LPCSTR) 2867);
}
%{
#include <stdio.h>
#include <string.h>
#include "Tokens.h"
unsigned int g_dwOffset = 0;
%}
CALL \xE8[\x00-\xFF]{4,4}
PUSH_NUM \x68[\x00-\xFF]{4,4}
VC6_RLS_STC_PATTERN \x56\x57\x6A\x01{CALL}\x8B\xF0\xFF\x74\x24\x0C\x8B\xCE{CALL}\x8B\xF8\x56\x8B\xCF{CALL}\x8B\xC7\x5F\x5E\xC2\x04\x00
//... 各种特征码
%%
{VC6_RLS_STC_PATTERN} {
return VC6_STC_RLS;
}
//... 找到特征码后各种对应处理方案
. {
g_dwOffset += yyleng;
}
\r|\n {
g_dwOffset += 1; //注意通配符 "." 是不匹配newline的
}
%%
int yywrap()
{
return 1;
}
int FindMFCVersion(FILE *fp)
{
yyin = fp;
yyrestart(fp);
g_dwOffset = 0;
switch (yylex())
{
case VC6_STC_DBG:
return VC6_STC_DBG;
break;
case VC6_STC_RLS:
return VC6_STC_RLS;
break;
case VS2013_STC_RLS:
return VS2013_STC_RLS;
case VS2013_STC_DBG:
return VS2013_STC_DBG;
break;
}
return 0;
}
unsigned int GetPatternOffset()
{
return g_dwOffset;
}
/bin
GenMsgAry.exe **提取Winuser.h中消息宏的程序
MFCSpyHook.dll **钩子,由句柄获取对方进程窗口对象
MyMFCSpy.exe **主程序
/CvtWinMsg **GenMsgAry.exe的源码
/FindMFCVersion **静态FromHandle特征码识别的源码
/MFCSpyHook ** MFCSpyHook.dll的源码
/MyMFCSpy ** MyMFCSpy.exe的源码
/ParserBin **用于识别汇编代码并逆运算的核心代码
/PatternRecgMFC **针对以上的核心写的窗口UI
PatternRecgMFC.exe **主程序
sample.txt **测试输入及中间文件
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!