上一个内容:37.添加简易的调试功能
以 37.添加简易的调试功能 它的代码为基础进行修改
效果图:

下图红框位置的功能实现

Dlls项目中添加一个Dialog

Dialog如下

然后给它添加一个类,MFC添加的类可能会报错添加 #include "afxdialogex.h" 这一句就好了

然后把类引入到Dlls.文件中,并且创建下图红框中的两个变量

然后dll实现代码如下图:

// CDllsApp 构造CDllsApp::CDllsApp()
{// TODO:  在此处添加构造代码,// 将所有重要的初始化放置在 InitInstance 中isShowWindow = false;
}// 唯一的 CDllsApp 对象CDllsApp theApp;
CDllsApp *PtheApp;// CDllsApp 初始化
HHOOK keyHook;
LRESULT CALLBACK KeyCallBack(int nCode, WPARAM w, LPARAM l);
BOOL CDllsApp::InitInstance()
{CWinApp::InitInstance();PtheApp = this;keyHook = SetWindowsHook(WH_KEYBOARD, KeyCallBack);AfxMessageBox(L"注入成功!");return TRUE;
}LRESULT CALLBACK KeyCallBack(int nCode, WPARAM w, LPARAM l) {if ((l&(1<<31)) == 0) {switch (w){case VK_HOME: {if (PtheApp->wndMain == NULL) {PtheApp->wndMain = new CWndMain();PtheApp->wndMain->Create(IDD_WNDMAIN);}PtheApp->isShowWindow = !PtheApp->isShowWindow;PtheApp->wndMain->ShowWindow(PtheApp->isShowWindow);break;}default:break;}}return CallNextHookEx(keyHook, nCode, w, l);
}CWndINJ.cpp文件中代码修改:

void CWndINJ::OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult)
{LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);// TODO: 在此添加控件通知处理程序代码*pResult = 0;int index = pNMItemActivate->iItem;if (index < 0)return;CString GamePath = ExeLst.GetItemText(index, 2);CString GameExe = ExeLst.GetItemText(index, 1);CString GameCmds = ExeLst.GetItemText(index, 3);CString GameDlls = ExeLst.GetItemText(index, 4);UpdateData(TRUE);PROCESS_INFORMATION prinfo{};bool Pause = B_PAUSE;if (B_INJCET && (GameDlls.GetLength() > 1)) {Pause = true;}m_INJCET.StartProcess(GameExe, GamePath, GameCmds.GetBuffer(), &prinfo, Pause);if (B_INJCET && (GameDlls.GetLength() > 1)) {m_INJCET.CreateRemoteData(prinfo.hProcess, GameExe, GameDlls);}if (B_DEBUG){PROCESS_INFORMATION odinfo{};//F:\其它\OllyDbg\Ollydbg.exe - p 4760CString dbgExe, dbgPath, dbgCmds;dbgExe = L"F:\\其它\\OllyDbg\\Ollydbg.exe";dbgPath = L"F:\\其它\\OllyDbg\\";dbgCmds.Format(L"%s -p %d", dbgExe, prinfo.dwProcessId);m_INJCET.StartProcess(dbgExe, dbgPath, dbgCmds.GetBuffer(), &odinfo, false);}if (B_PAUSE) {AfxMessageBox(L"按下确认,进程开始执行!");}ResumeThread(prinfo.hThread);// 用来指定创建时进程的主窗口的窗口工作站、桌面、标准句柄和外观。// STARTUPINFO si{};// si.cb = sizeof(si);//STARTUPINFO si{};//si.cb = sizeof(si);//CreateProcess(dbgExe,//    dbgExe.GetBuffer(),//    NULL, NULL,//    false,//    // 新进程的主线程处于挂起状态创建,在调用 ResumeThread 函数之前不会运行。//    0,//    NULL,//    dbgPath,//    &si,//    &odinfo//);//ResumeThread(odinfo.hThread);//m_INJCET.CodeRemoteData(&_data);/**CreateProcess(GameExe,GameCmds.GetBuffer(),NULL,NULL,FALSE,// 新进程的主线程处于挂起状态创建,在调用 ResumeThread 函数之前不会运行。CREATE_SUSPENDED,NULL,GamePath,&si,&prinfo);*//** 方式一调用apiCStringA GameExeA;GameExeA = GameExe;PLOADED_IMAGE image =  ImageLoad(GameExeA, NULL);DWORD dEntryPoint = image->FileHeader->OptionalHeader.AddressOfEntryPoint;CString wTxt;wTxt.Format(L"%X", dEntryPoint);AfxMessageBox(wTxt);ImageUnload(image)*//** 方式二(要在32位环境下运行)void* image = _imageload(GameExe.GetBuffer());IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)image;unsigned PEAddress =  dosHeader->e_lfanew + (unsigned)image;IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)PEAddress;DWORD dEntryPoint = ntHeader->OptionalHeader.AddressOfEntryPoint;CString wTxt;wTxt.Format(L"%X", dEntryPoint);AfxMessageBox(wTxt);_unloadimage(image);*///LPVOID adrRemote = VirtualAllocEx(prinfo.hProcess, 0, 0x3000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);//SIZE_T lwt;//WriteProcessMemory(prinfo.hProcess, adrRemote, INJECTCode, 0x200, &lwt);//CString wTxt;//wTxt.Format(L"%X", adrRemote);//AfxMessageBox(wTxt);// 让游戏继续运行//m_INJCET.CreateRemoteData(prinfo.hProcess, GameDlls.GetBuffer());}