手把手教你写游戏修改器(终极版)

关于怎样写植物大战僵尸游戏修改器的详细过程,在手把手教你写游戏修改器里面已经详细介绍了,这里就不再说了。前面那个修改器是基于控制台程序下面的,紧紧对于植物大战僵尸有用,采用上面那个教程已经将游戏修改器的制作流程和原理讲清楚了,现在我们开始做一个完整的游戏修改器。

1、建立一个对话框工程,建立过程VC怎样建立对话框工程中已经介绍了。这里不再介绍

2、绘制如下界面

其中个控件ID如下:

列表控件:IDC_PROCESSINFO

编辑框  :IDC_INPUT

静态文本框:IDC_SHOW

查看进程信息按钮:IDC_LOOKUPINFO

确定按钮 :IDC_OK

3、具体思路

首先应该得到目前所有进程的ID,因为后面要找到进程的句柄,因此当用户点击查看所有进程信息时显示目前计算机所有进程信息,并记录每个进程的ID。如下图

根据输入的进程编号,锁定用户想查找的进程。

然后根据用户输入的数据根据上篇文章说的方法进行查找就行,主要问题就是Windows编程中涉及的一些知识,都是一些简单的从控制台转换到Windows界面控制,应该不难。

下面直接给出代码:

#include "stdafx.h"

#include <windows.h>

#include <windowsx.h>

#include "resource.h"

#include "MainDlg.h"

#include <commctrl.h>

#include <tlhelp32.h>

typedef struct PROCESSINFOS {TCHAR Info[255];int no;DWORD ProcessID;} ProcessInfos;

ProcessInfos ProcessInfoS[200];

int MaxNum = 0;

int x=0;

DWORD tProcessID;

DWORD g_arList[999999];         //地址列表

int g_nListCnt=0;               //有效地址个数

TCHAR Mess1[20] = "进程编号:";

TCHAR Mess2[20] = "进程名称";

void InitListView(HWND hwnd)

{

HWND hwndListView=GetDlgItem(hwnd,IDC_PROCESSINFO);

//设置列表框控件格式

    DWORD dwExStyle =LVS_EX_GRIDLINES;

ListView_SetExtendedListViewStyle(hwndListView,dwExStyle);

//设置列

LVCOLUMN   column[2]; 

ZeroMemory(column,sizeof(column));

column[0].mask   =   LVCF_TEXT|LVCF_FMT|LVCF_WIDTH; 

column[0].pszText   =   Mess1; 

column[0].fmt   =   LVCFMT_CENTER; 

column[0].cx   =   80; 

column[1].mask   =   LVCF_TEXT|LVCF_FMT|LVCF_WIDTH; 

column[1].pszText   =   Mess2; 

column[1].fmt   =   LVCFMT_CENTER; 

column[1].cx   =   410; 

SendDlgItemMessage(hwnd, IDC_PROCESSINFO, LVM_INSERTCOLUMN,0, (LPARAM)&column[0]);

SendDlgItemMessage(hwnd, IDC_PROCESSINFO, LVM_INSERTCOLUMN,1, (LPARAM)&column[1]);

}

void ShowProcessInfo(HWND hwnd)

{

int i=0;

char ans[100];

LVITEM lvItem;

lvItem.mask = LVIF_TEXT;

    PROCESSENTRY32 pe32;

    pe32.dwSize = sizeof(pe32);

HWND hwndListView=GetDlgItem(hwnd,IDC_PROCESSINFO);

    HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

    if(hProcessSnap == INVALID_HANDLE_VALUE) return;

    BOOL bMore = ::Process32First(hProcessSnap,&pe32);

    while(bMore)

    {    

lvItem.iItem = i;

itoa(i,ans,10);

        lvItem.iSubItem = 0;

lvItem.pszText = ans;

ListView_InsertItem(hwndListView,(LPARAM)&lvItem);

ListView_SetItemText(hwndListView, i, 1, pe32.szExeFile);

wsprintf(ProcessInfoS[i].Info,pe32.szExeFile);

ProcessInfoS[i].no = i;

ProcessInfoS[i].ProcessID = pe32.th32ProcessID;

i++;

MaxNum++;

        bMore = ::Process32Next(hProcessSnap,&pe32);

    }

    ::CloseHandle(hProcessSnap);

}

int LockProcess(HWND hwnd)

{

int num;

TCHAR info[255];

ZeroMemory(info,sizeof(info));

GetDlgItemText(hwnd,IDC_INPUT,info,sizeof(info));

num = atoi(info);

if(num<MaxNum)

{

x=1;

tProcessID = ProcessInfoS[num].ProcessID;

// MessageBox(hwnd,ProcessInfoS[num].Info,TEXT(""),MB_OK);

SetDlgItemText(hwnd,IDC_SHOW,TEXT("请输入第一次查找的值:"));

return 1;

}

else

{

MessageBox(hwnd,TEXT("不存在改编号的进程!!!"),TEXT("错误"),MB_OK|MB_ICONERROR);

return 0;

}

}

BOOL CompareAPage(HANDLE hProcess,DWORD dwBaseAddr,DWORD dwValue)

{

//读取第一页

BYTE arBytes[4094];

if(!::ReadProcessMemory(hProcess,(LPVOID)dwBaseAddr,arBytes,4096,NULL))

{

return FALSE;        //此页不可读

}

DWORD *pdw;

for(int i=0;i<(int)4*1024-3;i++)

{

pdw = (DWORD *)&arBytes[i];

if(pdw[0]==dwValue)  //等于要查找的值

{

g_arList[g_nListCnt++] = dwBaseAddr+i;

}

}

return TRUE;

}

//第一次查找

BOOL FindFirst(HANDLE hProcess,DWORD dwValue)

{

const DWORD dwOneGB = 1024*1024*1024;    //1GB

const DWORD dwOnePage = 4*1024;          //4KB

if(hProcess==FALSE)

{

return FALSE;

}

//查看操作系统类型,确定开始地址

DWORD dwBase;

OSVERSIONINFO vi = {sizeof(vi)};

::GetVersionEx(&vi);

if(vi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)

dwBase = 4*1024*1024;              //4MB

else

{

dwBase = 640*1024;                  //64KB

}

//在开始地址到2GB地址空间寻找

for(;dwBase<2*dwOneGB;dwBase +=dwOnePage)

{

//比较一页大小的内存

CompareAPage(hProcess,dwBase,dwValue);

}

return TRUE;

}

void ShowList(HWND hwnd)

{

LVITEM lvItem;

lvItem.mask = LVIF_TEXT;

int i;

TCHAR ans[20];

TCHAR MessAdd[20];

HWND hwndListView=GetDlgItem(hwnd,IDC_PROCESSINFO);

for(i=0;i<g_nListCnt;i++)

{

ZeroMemory(ans,sizeof(ans));

ZeroMemory(MessAdd,sizeof(MessAdd));

lvItem.iItem = i;

itoa(i,ans,10);

        lvItem.iSubItem = 0;

lvItem.pszText = ans;

ListView_InsertItem(hwndListView,(LPARAM)&lvItem);

wsprintf(MessAdd,"%x",g_arList[i]);

ListView_SetItemText(hwndListView, i, 1, MessAdd);

// printf("%08X\n",g_arList[i]);

}

}

BOOL FindNext(HWND hwnd,HANDLE hProcess,DWORD dwValue)

{

//保存g_arList数组有效地址的个数,初始化g_nLisatCnt

int nOrgCnt = g_nListCnt;

g_nListCnt = 0;

//g_arList中寻找

BOOL bRet = FALSE;

DWORD dwReadValue;

for(int i=0;i<nOrgCnt;i++)

{

if(::ReadProcessMemory(hProcess,(LPVOID)g_arList[i],&dwReadValue,sizeof(DWORD),NULL))

{

if(dwReadValue==dwValue)

{

g_arList[g_nListCnt++] = g_arList[i];

bRet = TRUE;

}

}

}

    if(g_nListCnt>1)

{

SetDlgItemText(hwnd,IDC_INPUT,"");

}

if(g_nListCnt==1)

{

x=3;

SetDlgItemText(hwnd,IDC_SHOW,"请输入要修改的值:");

SetDlgItemText(hwnd,IDC_INPUT,"");

}

return bRet;

}

BOOL WriteMemory(HANDLE hProcess,DWORD dwAddr,DWORD dwValue)

{

return ::WriteProcessMemory(hProcess,(LPVOID)dwAddr,&dwValue,sizeof(DWORD),NULL);

}

BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

    switch(uMsg)

    {

        HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);

        HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand);

HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose);

    }

    return FALSE;

}

BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)

{

InitListView(hwnd);

SetDlgItemText(hwnd,IDC_SHOW,"输入锁定的进程编号:");

ZeroMemory(ProcessInfoS,sizeof(ProcessInfoS));

    return TRUE;

}

void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)

{

    switch(id)

    {

        case IDC_OK:

{

HANDLE hProcess;

if(0==x)

{

SetDlgItemText(hwnd,IDC_SHOW,"输入锁定的进程编号:");

int i = LockProcess(hwnd);

//查找进程的句柄

if(i==1)

{

hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,FALSE,tProcessID);

MessageBox(hwnd,TEXT("进程已锁定!!!"),TEXT("锁定进程成功"),MB_OK);

}

break;

}

if(1==x)

{

int iVal;

TCHAR Fnum[255];

hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,FALSE,tProcessID);

GetDlgItemText(hwnd,IDC_INPUT,Fnum,sizeof(Fnum));

iVal = atoi(Fnum);

FindFirst(hProcess,iVal);

wsprintf(Mess1,"序号");

wsprintf(Mess2,"地址");

InitListView(hwnd);

if(g_nListCnt>=1)

{

if(g_nListCnt>1)

{

MessageBox(hwnd,TEXT("第一次搜索完成!!!"),TEXT("成功"),MB_OK);

ShowList(hwnd);

SetDlgItemText(hwnd,IDC_SHOW,"请输入下一次的值:");

SetDlgItemText(hwnd,IDC_INPUT,"");

x=2;

}

if(g_nListCnt==1)

{

                            MessageBox(hwnd,TEXT("第一次搜索完成!!!"),TEXT("成功"),MB_OK);

ShowList(hwnd);

SetDlgItemText(hwnd,IDC_SHOW,"请输入要修改的值:");

SetDlgItemText(hwnd,IDC_INPUT,"");

x=3;

}

}

break;

}

if(2==x)

{

 DWORD iVal;

 TCHAR Fnum[255];  

 while(g_nListCnt>1)

 {

 hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,FALSE,tProcessID);

 GetDlgItemText(hwnd,IDC_INPUT,Fnum,sizeof(Fnum));

 iVal = atoi(Fnum);

 FindNext(hwnd,hProcess,iVal);

 //显示查找结果

 ShowList(hwnd);

 }

 break;

}

if(3==x)

{

 int iVal;

 TCHAR Fnum[255];

 hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,FALSE,tProcessID);

     GetDlgItemText(hwnd,IDC_INPUT,Fnum,sizeof(Fnum));

 iVal = atoi(Fnum);

 if(WriteMemory(hProcess,g_arList[0],iVal))

 {

 MessageBox(NULL,TEXT("修改成功"),TEXT("成功"),MB_OK);

 }

 break;

}

}

        break;

case IDC_LOOKUPINFO:

{

ShowProcessInfo(hwnd);

}

break;

        default:

break;

    }

}

void Main_OnClose(HWND hwnd)

{

    EndDialog(hwnd, 0);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

干了这一碗BUG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值