您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > vb制作游戏外挂教程菜鸟级(牛)
有个问题必须首先考虑:使用VB编写的修改器需要VB的执行库才能执行。如果考虑到有些使用者(实际上可能是大部分使用者)没有执行库,那么在最后制作的ZIP压缩档中就必须包含这些庞大的档。在下面的教程里我将制作一个修改器,如果为它再制作一个安装程序,那么整个修改器的体积将超过1MB。其中包括一个很好的安装和反安装程序,但大部分还是VB40032.DLL这个档。除了以上这点,使用VB制作修改器是非常简单的。一旦制作了多次后,你会发现能很快地制作出一个修改器。而且使用VB制作的修改器能够毫无困难地解决游戏执行时的动态内存分配问题,因此即使是最新的游戏,也可以使用VB制作修改器。在本教程中将不涉及动态内存分配,因为虽然简单,但仍然属于一个高级的选项。一些背景知识不象C语音,VB不会自动包括普通的API函数的声明,因此我们必须把他们加入我们的项目文件。在几乎所有的修改器中会使用到6个主要的函数,讨论如下:1.FindWindow(ClassName,WindowTitle)-FindWindow返回符合指定的类名(ClassName)和窗口名(WindowTitle)的窗口句柄。对我们来说,可以让ClassName为空(Null),只给出游戏的WindowTitle。函数应该这样声明:DeclareFunctionFindWindowLibuser32AliasFindWindowA(ByVallpClassNameAsString,ByVallpWindowNameAsString)AsLong2.GetWindowThreadProcessId(WindowHandle,ProcessId)-在这里我们把FindWindow函数中得到的句柄作为参数,来获得进程标识符(ProcessId)。声明如下:DeclareFunctionGetWindowThreadProcessIdLibuser32(ByValhwndAsLong,lpdwProcessIdAsLong)AsLong3.OpenProcess(DesiredAccess,Inherit,ProcessId)-这个函数将返回一个我们目标进程的句柄,可以用来对目标进行读写操作。DesiredAccess参数的值决定了句柄对进程的存取权利,对我们来说,要使用PROCESS_ALL_ACCESS(完全存取权限)。Inherit应该总是False。ProcessId是从GetWindowThreadProcessId函数中取得的。DeclareFunctionOpenProcessLibkernel32(ByValdwDesiredAccessAsLong,ByValbInheritHandleAsLong,ByValdwProcessIdAsLong)AsLong4.CloseHandle(ProcessHandle)-每一个打开的句柄必须呼叫这个函数来关闭。DeclareFunctionCloseHandleLibkernel32(ByValhObjectAsLong)AsLong5.WriteProcessMemory(ProcessHandle,Address,value,Sizeofvalue,BytesWritten)-把指定的值value写入由Address指定的目标地址。DeclareFunctionWriteProcessMemoryLibkernel32(ByValhProcessAsLong,ByVallpBaseAddressAsAny,ByVallpBufferAsAny,ByValnSizeAsLong,lpNumberOfBytesWrittenAsLong)AsLong6.ReadProcessMemory(ProcessHandle,Address,value,Sizeofvalue,BytesWritten)-把Address指定的目标地址的值存入value位置的变量中。DeclareFunctionWriteProcessMemoryLibkernel32(ByValhProcessAsLong,ByVallpBaseAddressAsAny,ByVallpBufferAsAny,ByValnSizeAsLong,lpNumberOfBytesWrittenAsLong)AsLong这些函数一环扣一环,缺一不可。更详细的内容可以参考VB的帮助档。一个简单的修改器范例如何使上面介绍的这些函数一起工作,制作出我们需要的修改器呢?下面是一个为Windows的计算器程序制作修改器的例子。这个修改器将读出计算器窗口中显示的数值,并在点击一个按钮后在计算器窗口中显示我们的名字。首先我们需要找到计算器显示窗口中显示值的地址。本教程不是关于如何进行内存搜索,因而我将只作简单的说明:-在计算器窗口中输入123456-使用你喜欢的任何一种内存地址搜索程序寻找字符串123456-使用另一个值重复上面的过程直到只返回1个地址那是制作我们的修改器需要的唯一一个地址。在我的计算器程序里这个地址是40B181hex,4239745dec。用你找到的地址替代在下面的代码里使用的这个地址。现在让我们开始设计修改器的接口:-在VB中新建一个项目,加入一个文本框(Textbox)、一个按钮和一个定时器(timer)。文本框用来显示从计算器窗口取得的字符串,按钮用来把我们的名字传到计算器窗口-把窗体(form)的标题(Caption)内容设为CalculatorTrainer-把文本框改名为txtDisplay并清除Text内容-把定时器改名为ReadTimer并把间隔(interval)设为500-把按钮的标题改为DisplayName,按钮的名字改为btnPasteName在这个修改器中我们将使用所有6个函数,ReadProcessMemory、WriteProcessMemory、OpenProcess、GetWindowThreadProcessId、FindWindow和CloseHandle。在项目中插入一个新的模块,增加下列代码。(下面的一些行自动换行了,在你的模块中每一句必须在一行里,或使用延长符_)DeclareFunctionFindWindowLibuser32AliasFindWindowA(ByVallpClassNameAsString,ByVallpWindowNameAsString)AsLongDeclareFunctionGetWindowThreadProcessIdLibuser32(ByValhwndAsLong,lpdwProcessIdAsLong)AsLongDeclareFunctionOpenProcessLibkernel32(ByValdwDesiredAccessAsLong,ByValbInheritHandleAsLong,ByValdwProcessIdAsLong)AsLongDeclareFunctionWriteProcessMemoryLibkernel32(ByValhProcessAsLong,ByVallpBaseAddressAsAny,ByVallpBufferAsAny,ByValnSizeAsLong,lpNumberOfBytesWrittenAsLong)AsLongDeclareFunctionReadProcessMemoryLibkernel32(ByValhProcessAsLong,ByVallpBaseAddressAsAny,ByVallpBufferAsAny,ByValnSizeAsLong,lpNumberOfBytesWrittenAsLong)AsLongDeclareFunctionCloseHandleLibkernel32(ByValhObjectAsLong)AsLong下面我们要开始写在定时器窗口中显示我们名字的代码了。首先我们使用FindWindow函数取得目标窗口的句柄。把这个返回值保存在一个变量中,并检查它的值是否出错来确保定时器程序正在执行。(FindWindow函数出错时返回0)DimhwndAsLonghwnd=FindWindow(vbNullString,Calculator)If(hwnd=0)ThenMsgBoxWindownotfound!ExitSubEndIf注意在这里我们传递了一个Null值给FindWindow函数,而不是ClassName。因此任何名为Calculator的窗口都符合条件。如果知道计算器程序窗口的ClassName,你可以传给它,但这不是必须的。现在使用得到的窗口句柄来取得进程标识符(ProcessId)。注意pid是作为参数传递给函数的,而不是被赋以函数返回值。DimpidAsLongGetWindowThreadProcessIdhwnd,pid再利用变量pid得到计算器程序的进程句柄。再次检查函数的返回值,如果是非法数据则退出程序。DimpHandleAsLongpHandle=OpenProcess(PROCESS_ALL_ACCESS,False,pid)If(pHandle=0)ThenMsgBoxCouldn’tgetaprocesshandle!ExitSubEndIf在我们的修改器中WriteProcessMemory函数是最重要的部分,而且非常容易出错。不妨让我们再仔细讨论一下它的参数。WriteProcessMemory(ByValhProcessAsLong,ByVallpBaseAddressAsAny,ByVallpBufferAsAny,ByValnSizeAsLong,lpNumberOfBytesWrittenAs)hProcess是目标进程的句柄,从上面的OpenProcess函数中取得的。lpBaseAddress是在计算器程序的虚拟内存中将要被修改的地址,也就是使用内存搜索程序找到的那个地址。(在我的程序里是&H40B181)lpBuffer是将要写如上述地址的数据,可以是一个数值、数组、字符串或其它任何数据类型。nSize是希望写入lpBaseAddress的字节数。这个位置应该与你的数据类型相符。如果写入的是一个长整数(long),这里应该是4。如果写入的是一个字符串,那么这里应该是字符串的长度。lpNumberOfBytesWritten是函数执行返回后,写入目标地址的实际字节数。它能被用来确认函数实际的执行情况。把我们的数据放到函数中,得到WriteProcessMemorypHandle,&H40B181,Beans,5,0&。我把0传递到lpNumberOfBytesWritten位置是因为不需要检查两次实际写入的字节数。最后通过传递进程句柄给CloseHandle()函数来关闭由OpenProcess打开的句柄。CloseHandlehProcess现在将所有的代码输入我们的编辑器中。双击按钮,显示它的代码编辑窗口。代码应该加到名为btnPasteName的Click事件中。(不必输入注释)PrivateSubbtnPasteName_Click()声明一些需要的变量DimhwndAsLong储存FindWindow函数返回的句柄DimpidAsLong储存进程标识符(ProcessId)DimpHandleAsLong储存进程句柄首先取得目标窗口的句柄hwnd=FindWindow(vbNullString,Calculator)If(hwnd=0)ThenMsgBoxWindownotfound!ExitSubEndIf取得进程标识符GetWindowThreadProcessIdhwnd,pid使用进程标识符取得进程句柄pHandle=OpenProcess(PROCESS_ALL_ACCESS,False,pid)If(pHandle=0)ThenMsgBoxCouldn’tgetaprocesshandle!ExitSubEndIf在内存
本文标题:vb制作游戏外挂教程菜鸟级(牛)
链接地址:https://www.777doc.com/doc-2854003 .html