分析代码
实战部分
DebugView Not Connected
打印机删掉
添加串口
新建MFC动态库


MFCLEI.dll
// MFCLEI.cpp: 定义 DLL 的初始化例程。//#include "stdafx.h"#include "MFCLEI.h"#ifdef _DEBUG#define new DEBUG_NEW#endif////TODO:  如果此 DLL 相对于 MFC DLL 是动态链接的,//        则从此 DLL 导出的任何调入//        MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到//        该函数的最前面。////        例如: ////        extern "C" BOOL PASCAL EXPORT ExportedFunction()//        {//            AFX_MANAGE_STATE(AfxGetStaticModuleState());//            // 此处为普通函数体//        }////        此宏先于任何 MFC 调用//        出现在每个函数中十分重要。  这意味着//        它必须作为以下项中的第一个语句://        出现,甚至先于所有对象变量声明,//        这是因为它们的构造函数可能生成 MFC//        DLL 调用。////        有关其他详细信息,//        请参阅 MFC 技术说明 33 和 58。//// CMFCLEIAppBEGIN_MESSAGE_MAP(CMFCLEIApp, CWinApp)END_MESSAGE_MAP()// CMFCLEIApp 构造CMFCLEIApp::CMFCLEIApp(){    // TODO:  在此处添加构造代码,    // 将所有重要的初始化放置在 InitInstance 中}// 唯一的 CMFCLEIApp 对象CMFCLEIApp theApp;HWND g_Wnd;WNDPROC g_OldhProc;PWORD g_pHeight = (PWORD)0x1005338;PWORD g_pWidth =(PWORD)0x1005334;PWORD g_pMineCount = (PWORD)0x1005330;#define MINE 0x8FPBYTE g_pBase = (PBYTE)0x1005340;// CMFCLEIApp 初始化LRESULT CALLBACK WindowProc(    _In_ HWND hWnd,    _In_ UINT Msg,    _In_ WPARAM wParam,    _In_ LPARAM lParam){    if (Msg == WM_KEYDOWN && wParam == VK_F5)//如果键盘按下并且是f5    {        //一件秒杀        OutputDebugString(L"F5");        int nHeight = *g_pHeight;        int nWidth = *g_pWidth;        int nMineCount = *g_pMineCount;        CString strString;        strString.Format(L"宽度:%d, 高度:%d, 雷数:%d", nHeight, nWidth, nMineCount);        OutputDebugString(strString.GetBuffer());        //雷区基地址        //雷区中的元素标识        //01002EE4 | .  8B0D 34530001 MOV ECX, DWORD PTR DS : [<宽度x>];  宽度        //01002EEA | .  8B15 38530001 MOV EDX, DWORD PTR DS : [<高度y>];  高度        //01002EF0 | .  8D41 02       LEA EAX, DWORD PTR DS : [ECX + 0x2]        //01002EF3 | .  85C0          TEST EAX, EAX        //01002EF5 | .  56            PUSH ESI        //01002EF6 | .  74 19         JE SHORT winmine.01002F11        //01002EF8 | .  8BF2          MOV ESI, EDX        //01002EFA | .C1E6 05       SHL ESI, 0x5        //01002EFD | .  8DB6 60530001 LEA ESI, DWORD PTR DS : [ESI + 0x1005360]        //01002F03 | > 48 / DEC EAX        //01002F04 | .C680 40530001 > | MOV BYTE PTR DS : [EAX + <数组基地址>], 0x10        //01002F0B | .C60406 10 | MOV BYTE PTR DS : [ESI + EAX], 0x10        //01002F0F | . ^ 75 F2         \JNZ SHORT winmine.01002F03        int nFindCount = 0;        int y = 1;        for (int y=1;y<nHeight;y++)        {            CString strLine;            for (int x = 1; x < nWidth + 1; x++)            {                BYTE byCode = *(PBYTE)((DWORD)g_pBase + x + y * 32);                if (byCode == MINE)                {                    nFindCount++;                    int  xPos, yPos;                    xPos = (x << 4) - 4;                    yPos = (y << 4) + 0x27;                    SendMessage(hWnd, WM_RBUTTONDOWN, 0, MAKELPARAM(xPos, yPos));                    SendMessage(hWnd, WM_RBUTTONUP, 0, MAKELPARAM(xPos, yPos));                    SendMessage(hWnd, WM_RBUTTONDOWN, 0, MAKELPARAM(xPos, yPos));                    SendMessage(hWnd, WM_RBUTTONUP, 0, MAKELPARAM(xPos, yPos));                }                else                {                    int  xPos, yPos;                    xPos = (x << 4) - 4;                    yPos = (y << 4) + 0x27;                    SendMessage(hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(xPos, yPos));                    SendMessage(hWnd, WM_LBUTTONUP, 0, MAKELPARAM(xPos, yPos));                }                CString strCode;                strCode.Format(L"%02x", byCode);                strLine += strCode;            }            OutputDebugString(strLine.GetBuffer());        }        CString strCode;        strCode.Format(L"找到的雷数%d", nFindCount);        OutputDebugString(strCode.GetBuffer());    }    else if(Msg==WM_MOUSEMOVE)    {        //鼠标移动        int x, y;        x = LOWORD(lParam);        y = HIWORD(lParam);        x = (x + 4) >> 4;        y = (y - 0x27) >> 4;        BYTE byCode = *(PBYTE)((DWORD)g_pBase + x + y * 32);        if (byCode==MINE)        {            SetWindowText(hWnd, L"此处有雷!!");        }        else        {            CString strPos;            strPos.Format(L"(%d,%d", y, x);            SetWindowText(hWnd, strPos);        }    }    return CallWindowProc(g_OldhProc, hWnd, Msg, wParam, lParam);}BOOL CMFCLEIApp::InitInstance(){    CWinApp::InitInstance();    //1.通过查找窗口,获取窗口句柄    g_Wnd = ::FindWindow(L"扫雷", L"扫雷");    if (NULL== g_Wnd)    {        OutputDebugString(L"无法找到 扫雷窗口");        return false;    }    //2.设置窗口回调函数    g_OldhProc=(WNDPROC)SetWindowLong(g_Wnd,GWL_WNDPROC,(LONG)WindowProc);//设置窗口句柄(窗口句柄,索引值,)    if (NULL == g_OldhProc)    {        OutputDebugString(L"设置窗口回调函数 失败");        return false;    }    return TRUE;}
