1、首先我们要用FindWindow,知道游戏窗口的句柄,因为我们要通过它来得知游戏的运行后所在进程的ID,下面就是FindWindow的用法:
HWND FindWindow(
LPCTSTR lpClassName, // pointer to class name
LPCTSTR lpWindowName // pointer to window name
);
2、我们GetWindowThreadProcessId来得到游戏窗口相对应进程的进程ID,函数用法如下:
DWORD GetWindowThreadProcessId(
HWND hWnd, // handle of window
LPDWORD lpdwProcessId // address of variable for process identifier
);
3、得到游戏进程ID后,接下来的事是要以最高权限打开进程,所用到的函数OpenProcess的具体使用方法如下:
HANDLE OpenProcess(
DWORD dwDesiredAccess, // access flag
BOOL bInheritHandle, // handle inheritance flag
DWORD dwProcessId // process identifier
);
在dwDesiredAccess之处就是设存取方式的地方,它可设的权限很多,我们在这里使用只要使用PROCESS_ALL_ACCESS 来打开进程就可以,其他的方式我们可以查一下MSDN。
4、打开进程后,我们就可以用函数对存内进行操作,在这里我们只要用到WriteProcessMemory来对内存地址写入数据即可(其他的操作方式比如说:ReadProcessMemory等,我在这里就不一一介绍了),我们看一下WriteProcessMemory的用法:
BOOL WriteProcessMemory(
HANDLE hProcess, // handle to process whose memory is written to
LPVOID lpBaseAddress, // address to start writing to
LPVOID lpBuffer, // pointer to buffer to write data to
DWORD nSize, // number of bytes to write
LPDWORD lpNumberOfBytesWritten // actual number of bytes written
);
5、下面用CloseHandle关闭进程句柄就完成了。
这就是这类游戏外挂的程序实现部份的方法,好了,有了此方法,我们就有了理性的认识,我们看看实际例子,提升一下我们的感性认识吧,下面就是XX游戏的外挂代码,我们照上面的方法对应去研究一下吧:
const
ResourceOffset: dword = $004219F4;
resource: dword = 3113226621;
ResourceOffset1: dword = $004219F8;
resource1: dword = 1940000000;
ResourceOffset2: dword = $0043FA50;
resource2: dword = 1280185;
ResourceOffset3: dword = $0043FA54;
resource3: dword = 3163064576;
ResourceOffset4: dword = $0043FA58;
resource4: dword = 2298478592;
var
hw: HWND;
pid: dword;
h: Thandle;
tt: Cardinal;
begin
hw := FindWindow('XX', nil);
if hw = 0 then
Exit;
GetWindowThreadProcessId(hw, @pid);
h := OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if h = 0 then
Exit;
if flatcheckbox1.Checked=true then
begin
WriteProcessMemory(h, Pointer(ResourceOffset), @Resource, sizeof(Resource), tt);
WriteProcessMemory(h, Pointer(ResourceOffset1), @Resource1, sizeof(Resource1), tt);
end;
if flatcheckbox2.Checked=true then
begin
WriteProcessMemory(h, Pointer(ResourceOffset2), @Resource2, sizeof(Resource2), tt);
WriteProcessMemory(h, Pointer(ResourceOffset3), @Resource3, sizeof(Resource3), tt);
WriteProcessMemory(h, Pointer(ResourceOffset4), @Resource4, sizeof(Resource4), tt);
end;
MessageBeep(0);
CloseHandle(h);
close;
这个游戏是用了多地址对所要提交的数据进行了校验,所以说这类游戏外挂制作并不是很难,最难的是要找到这些地址。
-----------这不是C++的,但C++也是使用相同的API函数-------------
外卦编程常用API函数
CancelWaitableTimer 这个函数用于取消一个可以等待下去的计时器操作
CallNamedPipe 这个函数由一个希望通过管道通信的一个客户进程调用
ConnectNamedPipe 指示一台服务器等待下去,直至客户机同一个命名管道连接
CreateEvent 创建一个事件对象
CreateMailslot 创建一个邮路。返回的句柄由邮路服务器使用(收件人)
CreateMutex 创建一个互斥体(MUTEX)
CreateNamedPipe 创建一个命名管道。返回的句柄由管道的服务器端使用
CreatePipe 创建一个匿名管道
CreateProcess 创建一个新进程(比如执行一个程序)
CreateSemaphore 创建一个新的信号机
CreateWaitableTimer 创建一个可等待的计时器对象
DisconnectNamedPipe 断开一个客户与一个命名管道的连接
DuplicateHandle 在指出一个现有系统对象当前句柄的情况下,为那个对象创建一个新句柄
ExitProcess 中止一个进程
FindCloseChangeNotification 关闭一个改动通知对象
FindExecutable 查找与一个指定文件关联在一起的程序的文件名
FindFirstChangeNotification 创建一个文件通知对象。该对象用于监视文件系统发生的变化
FindNextChangeNotification 重设一个文件改变通知对象,令其继续监视下一次变化 7
FreeLibrary 释放指定的动态链接库
GetCurrentProcess 获取当前进程的一个伪句柄
GetCurrentProcessId 获取当前进程一个唯一的标识符
GetCurrentThread 获取当前线程的一个伪句柄
GetCurrentThreadId 获取当前线程一个唯一的线程标识符
GetExitCodeProces 获取一个已中断进程的退出代码
GetExitCodeThread 获取一个已中止线程的退出代码
GetHandleInformation 获取与一个系统对象句柄有关的信息
GetMailslotInfo 获取与一个邮路有关的信息
GetModuleFileName 获取一个已装载模板的完整路径名称
GetModuleHandle 获取一个应用程序或动态链接库的模块句柄
GetPriorityClass 获取特定进程的优先级别
GetProcessShutdownParameters 调查系统关闭时一个指定的进程相对于其它进程的关闭早迟情况
GetProcessTimes 获取与一个进程的经过时间有关的信息
GetProcessWorkingSetSize 了解一个应用程序在运行过程中实际向它交付了多大容量的内存
GetSartupInfo 获取一个进程的启动信息
GetThreadPriority 获取特定线程的优先级别
GetTheardTimes 获取与一个线程的经过时间有关的信息
GetWindowThreadProcessId 获取与指定窗口关联在一起的一个进程和线程标识符
LoadLibrary 载入指定的动态链接库,并将它映射到当前进程使用的地址空间
LoadLibraryEx 装载指定的动态链接库,并为当前进程把它映射到地址空间
LoadModule 载入一个Windows应用程序,并在指定的环境中运行
MsgWaitForMultipleObjects 等侯单个对象或一系列对象发出信号。如返回条件已经满足,则立即返回
SetPriorityClass 设置一个进程的优先级别
SetProcessShutdownParameters 在系统关闭期间,为指定进程设置他相对于其它程序的关闭顺序
SetProcessWorkingSetSize 设置操作系统实际划分给进程使用的内存容量
SetThreadPriority 设定线程的优先级别
ShellExecute 查找与指定文件关联在一起的程序的文件