上一个内容:38.控制功能实现
以 38.控制功能实现 它的代码为基础进行修改
效果图:
点击设置之后的样子
点击删除
点击删除之后的样子
实现步骤:
首先添加一个菜单资源,右击项目资源选择下图红框
然后选择Menu
然后双击请在此输入,搞成下图中的样子
然后给列表添加右击事件
CWndAddGame.h文件,新加 SetData函数。修改了Init、OnBnClickedButton3函数
#pragma once
// CWndAddGame 对话框
class CWndAddGame : public CDialogEx
{
DECLARE_DYNAMIC(CWndAddGame)
public:
CWndAddGame(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CWndAddGame();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ADDGAME };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
CString GameName;
CString GamePath;
CString GameFullPath;
CString GameCmds;
CString DllPath;
void* father;
bool IsCreate;
int index;
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedButton4();
afx_msg void OnBnClickedButton3();
public:
void Init(void* _father, bool Create = true, int _index = 0);
void SetData(CString& _GameName,
CString& _GamePath,
CString& _GameExe,
CString& _GameCmds,
CString& _DllPath);
};
CWndAddGame.cpp文件:
#include "pch.h"
#include "GAMEHACKER2.h"
#include "CWndAddGame.h"
#include "afxdialogex.h"
#include "CWndINJ.h"
// CWndAddGame 对话框
IMPLEMENT_DYNAMIC(CWndAddGame, CDialogEx)
CWndAddGame::CWndAddGame(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_ADDGAME, pParent)
, GameName(_T(""))
, GamePath(_T(""))
, GameFullPath(_T(""))
, DllPath(_T(""))
{
}
CWndAddGame::~CWndAddGame()
{
}
void CWndAddGame::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, GameName);
DDX_Text(pDX, IDC_EDIT2, GamePath);
DDX_Text(pDX, IDC_EDIT3, GameFullPath);
DDX_Text(pDX, IDC_EDIT4, GameCmds);
DDX_Text(pDX, IDC_EDIT5, DllPath);
}
BEGIN_MESSAGE_MAP(CWndAddGame, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON1, &CWndAddGame::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &CWndAddGame::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON4, &CWndAddGame::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON3, &CWndAddGame::OnBnClickedButton3)
END_MESSAGE_MAP()
// CWndAddGame 消息处理程序
void CWndAddGame::OnBnClickedButton1()
{
static TCHAR BASED_CODE szFilter[] = _T("exe (*.exe)|*.exe|dat (*.dat)|*.dat|All (*.*)|*.*||");
// CFileDialog是mfc封装好的打开文件或另存为窗口
CFileDialog dialog(TRUE, NULL, NULL, 6,szFilter);
UpdateData(TRUE);
if (dialog.DoModal() == IDOK)
{
// 游戏可执行文件
GameFullPath = dialog.GetPathName();
// 游戏名称
GameName = dialog.GetFileTitle();
// 游戏路径
GamePath = dialog.GetFolderPath() + L"\\";
UpdateData(FALSE);
}
}
void CWndAddGame::OnBnClickedButton2()
{
UpdateData(TRUE);
static TCHAR BASED_CODE szFilter[] = _T("动态链接库 (*.dll)|*.dll|All (*.*)|*.*||");
// CFileDialog是mfc封装好的打开文件或另存为窗口
CFileDialog dialog(TRUE, NULL, NULL, 6, szFilter);
if (dialog.DoModal() == IDOK)
{
// 注入模块路径
DllPath = dialog.GetPathName();
UpdateData(FALSE);
}
}
void CWndAddGame::OnBnClickedButton4()
{
CDialog::OnCancel();
}
void CWndAddGame::OnBnClickedButton3()
{
CWndINJ* p = (CWndINJ*)father;
UpdateData(TRUE);
if (IsCreate) {
p->AddGame(GameName, GameFullPath, GamePath, GameCmds, DllPath);
}
else {
p->SaveGame(GameName, GameFullPath, GamePath, GameCmds, DllPath, index);
}
CDialog::OnCancel();
}
void CWndAddGame::Init(void* _father, bool Create, int _index)
{
father = _father;
IsCreate = Create;
index = _index;
}
void CWndAddGame::SetData(CString& _GameName, CString& _GamePath, CString& _GameExe, CString& _GameCmds, CString& _DllPath)
{
GameName = _GameName;
GamePath = _GamePath;
GameCmds = _GameCmds;
GameFullPath = _GameExe;
DllPath = _DllPath;
}
CWndINJ.h文件中的代码,新加 OnMenuSet、OnMenuDel、OnNMRClickList1、SaveLstToIni、SaveGame。新加变量 lstSel
#pragma once
#include "CWndAddGame.h"
#include "INJCET.h"
// CWndINJ 对话框
class CWndINJ : public CDialogEx
{
DECLARE_DYNAMIC(CWndINJ)
public:
CWndINJ(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CWndINJ();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_PAGE_0 };
#endif
protected:
INJCET m_INJCET;
virtual BOOL OnInitDialog();
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
CListCtrl ExeLst;
afx_msg void OnBnClickedButton1();
// 注入
BOOL B_INJCET;
// 调试
BOOL B_DEBUG;
// 暂停
BOOL B_PAUSE;
CWndAddGame wndAddGame;
CString AppPath;
// 配置文件路径
CString GameIni;
public:
void Init(CString& _AppPath);
void AddGame(CString& GameName,
CString& GamePath,
CString& GameFullPath,
CString& GameCmds,
CString& DllPath);
void SaveGame(CString& GameName,
CString& GamePath,
CString& GameFullPath,
CString& GameCmds,
CString& DllPath,
int index);
void LoadGame();
afx_msg void OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnNMRClickList1(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnMenuSet();
afx_msg void OnMenuDel();
int lstSel;
void SaveLstToIni();
};
CWndINJ.cpp文件中的代码
// CWndINJ.cpp: 实现文件
//
#include "pch.h"
#include "GAMEHACKER2.h"
#include "CWndINJ.h"
#include "afxdialogex.h"
#include <ImageHlp.h>
#include <fstream>
#pragma comment(lib, "ImageHlp.lib")
//void _stdcall INJECTCode() {
// AfxMessageBox(L"aa");
// unsigned address = 0xCCCCCCCC;
// PREMOTE_DATA p = (PREMOTE_DATA)address;
// p->f_LoadLibrary(p->dllName);
//}
// CWndINJ 对话框
IMPLEMENT_DYNAMIC(CWndINJ, CDialogEx)
CWndINJ::CWndINJ(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_PAGE_0, pParent)
, B_INJCET(FALSE)
, B_DEBUG(FALSE)
, B_PAUSE(FALSE)
{
}
CWndINJ::~CWndINJ()
{
}
BOOL CWndINJ::OnInitDialog()
{
CDialogEx::OnInitDialog();
LONG_PTR lStyle;
// 得到窗口的样式,GWL_STYLE在GetWindowLongPtr说明中有
lStyle = GetWindowLongPtr(ExeLst.m_hWnd, GWL_STYLE);
lStyle |= LVS_REPORT;
SetWindowLongPtr(ExeLst.m_hWnd, GWL_STYLE, lStyle);
DWORD dStyle = ExeLst.GetExtendedStyle();
dStyle |= LVS_EX_FULLROWSELECT;
dStyle |= LVS_EX_GRIDLINES;
ExeLst.SetExtendedStyle(dStyle);
ExeLst.InsertColumn(0, L"名称", 0, 200);
ExeLst.InsertColumn(1, L"可执行文件", 0, 400);
ExeLst.InsertColumn(2, L"文件夹", 0, 400);
ExeLst.InsertColumn(3, L"命令行", 0, 400);
ExeLst.InsertColumn(4, L"注入模块", 0, 400);
return 0;
}
void CWndINJ::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, ExeLst);
DDX_Check(pDX, IDC_CHECK1, B_INJCET);
DDX_Check(pDX, IDC_CHECK2, B_DEBUG);
DDX_Check(pDX, IDC_CHECK3, B_PAUSE);
}
BEGIN_MESSAGE_MAP(CWndINJ, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON1, &CWndINJ::OnBnClickedButton1)
ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CWndINJ::OnNMDblclkList1)
ON_NOTIFY(NM_RCLICK, IDC_LIST1, &CWndINJ::OnNMRClickList1)
ON_COMMAND(ID_32771, &CWndINJ::OnMenuSet)
ON_COMMAND(ID_32772, &CWndINJ::OnMenuDel)
END_MESSAGE_MAP()
// CWndINJ 消息处理程序
void CWndINJ::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
/*ExeLst.InsertItem(0, L"DNF");
ExeLst.SetItemText(0, 1, L"dlls.dll");*/
用来指定创建时进程的主窗口的窗口工作站、桌面、标准句柄和外观。
//STARTUPINFO si{};
//si.cb = sizeof(si);
//PROCESS_INFORMATION prinfo{};
//CreateProcess(L"C:\\Users\\am\\Desktop\\易道云\\游戏保护\\练手游戏\\初级\\JX2\\Sword2.exe",
// NULL,NULL,NULL,
// FALSE,
// // 新进程的主线程处于挂起状态创建,在调用 ResumeThread 函数之前不会运行。
// CREATE_SUSPENDED,
// NULL,
// L"C:\\Users\\am\\Desktop\\易道云\\游戏保护\\练手游戏\\初级\\JX2\\",
// &si,
// &prinfo
// );
///**
// 注入功能写在这里(CreateProcess与ResumeThread函数之间)
//*/
让游戏继续运行
//ResumeThread(prinfo.hThread);
wndAddGame.Init(this);
wndAddGame.DoModal();
}
void CWndINJ::Init(CString& _AppPath)
{
AppPath = _AppPath;
GameIni.Format(L"%s\\config\\Games.ini", AppPath);
LoadGame();
}
void CWndINJ::AddGame(CString& GameName, CString& GamePath, CString& GameFullPath, CString& GameCmds, CString& DllPath)
{
int count = GetPrivateProfileInt(L"main", L"count", 0, GameIni);
count++;
CString key;
key.Format(L"count_%d", count);
WritePrivateProfileString(key, L"GameName", GameName, GameIni);
WritePrivateProfileString(key, L"GamePath", GamePath, GameIni);
WritePrivateProfileString(key, L"GameFullPath", GameFullPath, GameIni);
WritePrivateProfileString(key, L"GameCmds", GameCmds, GameIni);
WritePrivateProfileString(key, L"DllPath", DllPath, GameIni);
CString wCount;
wCount.Format(L"%d", count);
WritePrivateProfileString(L"main", L"count", wCount, GameIni);
int iCount = ExeLst.GetItemCount();
ExeLst.InsertItem(iCount, GameName);
ExeLst.SetItemText(iCount, 1, GamePath);
ExeLst.SetItemText(iCount, 2, GameFullPath);
ExeLst.SetItemText(iCount, 3, GameCmds);
ExeLst.SetItemText(iCount, 4, DllPath);
}
void CWndINJ::SaveGame(CString& GameName, CString& GamePath, CString& GameFullPath, CString& GameCmds, CString& DllPath, int index)
{
CString key;
key.Format(L"count_%d", index);
WritePrivateProfileString(key, L"GameName", GameName, GameIni);
WritePrivateProfileString(key, L"GamePath", GamePath, GameIni);
WritePrivateProfileString(key, L"GameFullPath", GameFullPath, GameIni);
WritePrivateProfileString(key, L"GameCmds", GameCmds, GameIni);
WritePrivateProfileString(key, L"DllPath", DllPath, GameIni);
int iCount = index-1;
ExeLst.SetItemText(iCount, 0, GameName);
ExeLst.SetItemText(iCount, 1, GamePath);
ExeLst.SetItemText(iCount, 2, GameFullPath);
ExeLst.SetItemText(iCount, 3, GameCmds);
ExeLst.SetItemText(iCount, 4, DllPath);
}
void CWndINJ::LoadGame()
{
int count = GetPrivateProfileInt(L"main", L"count", 0, GameIni);
for (int i = 0; i < count; i++) {
CString GameName, GameExe, GamePath, GameCmds, GameDlls, _AppName;
_AppName.Format(L"count_%d", i+1);
wchar_t wRead[0xFF];
GetPrivateProfileString(_AppName, L"GameName", L"", wRead, 0xFF, GameIni);
GameName.Format(L"%s", wRead);
GetPrivateProfileString(_AppName, L"GamePath", L"", wRead, 0xFF, GameIni);
GameExe.Format(L"%s", wRead);
GetPrivateProfileString(_AppName, L"GameFullPath", L"", wRead, 0xFF, GameIni);
GamePath.Format(L"%s", wRead);
GetPrivateProfileString(_AppName, L"GameCmds", L"", wRead, 0xFF, GameIni);
GameCmds.Format(L"%s", wRead);
GetPrivateProfileString(_AppName, L"DllPath", L"", wRead, 0xFF, GameIni);
GameDlls.Format(L"%s", wRead);
ExeLst.InsertItem(i, GameName);
ExeLst.SetItemText(i, 1, GameExe);
ExeLst.SetItemText(i, 2, GamePath);
ExeLst.SetItemText(i, 3, GameCmds);
ExeLst.SetItemText(i, 4, GameDlls);
}
}
void* _imageload(wchar_t* filename) {
std::ifstream streamReader(filename, std::ios::binary);
streamReader.seekg(0, std::ios::end);
unsigned filesize = streamReader.tellg();
char* _data = new char[filesize];
streamReader.seekg(0, std::ios::beg);
streamReader.read(_data, filesize);
streamReader.close();
return _data;
}
void _unloadimage(void* _data) {
delete[] _data;
}
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());
}
void CWndINJ::OnNMRClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pActive = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
if (pActive->iItem != -1) {
lstSel = pActive->iItem;
// 获取最后一个消息发生时的鼠标位置
DWORD dwPos = GetMessagePos();
CPoint point(LOWORD(dwPos), HIWORD(dwPos));
CMenu menu;
menu.LoadMenuW(IDR_MENU1);
CMenu* pop = menu.GetSubMenu(0);
pop->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x,point.y, this);
}
}
void CWndINJ::OnMenuSet()
{
// TODO: 在此添加命令处理程序代码
//AfxMessageBox(L"按下了设置");
CString GameName = ExeLst.GetItemText(lstSel, 0);
CString GamePath = ExeLst.GetItemText(lstSel, 2);
CString GameExe = ExeLst.GetItemText(lstSel, 1);
CString GameCmds = ExeLst.GetItemText(lstSel, 3);
CString GameDlls = ExeLst.GetItemText(lstSel, 4);
wndAddGame.Init(this, false, lstSel+1);
wndAddGame.SetData(GameName, GamePath, GameExe, GameCmds, GameDlls);
wndAddGame.DoModal();
}
void CWndINJ::OnMenuDel()
{
// TODO: 在此添加命令处理程序代码
//AfxMessageBox(L"按下了删除");
ExeLst.DeleteItem(lstSel);
SaveLstToIni();
}
void CWndINJ::SaveLstToIni()
{
int count = ExeLst.GetItemCount();
for (int i = 0; i < count; i++) {
CString GameName = ExeLst.GetItemText(i, 0);
CString GamePath = ExeLst.GetItemText(i, 2);
CString GameExe = ExeLst.GetItemText(i, 1);
CString GameCmds = ExeLst.GetItemText(i, 3);
CString GameDlls = ExeLst.GetItemText(i, 4);
int tempI = i + 1;
CString key;
key.Format(L"count_%d", tempI);
WritePrivateProfileString(key, L"GameName", GameName, GameIni);
WritePrivateProfileString(key, L"GamePath", GameExe, GameIni);
WritePrivateProfileString(key, L"GameFullPath", GamePath, GameIni);
WritePrivateProfileString(key, L"GameCmds", GameCmds, GameIni);
WritePrivateProfileString(key, L"DllPath", GameDlls, GameIni);
}
CString wCount;
wCount.Format(L"%d", count);
WritePrivateProfileString(L"main", L"count", wCount, GameIni);
}