上一个内容: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 4760
CString 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
);
*/
/** 方式一调用api
CStringA 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());
}