vb用API修改内存实例(做外挂)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
你说你想用VB做外挂,有人说:“对不起,我想这是不可能的,因为VB是一个如此简单的编程语音。"如果有人这么告诉你,别去理他。我可以肯定告诉你,对于制作修改器这种简单的程序,VB完全可以胜任。
然而,有个问题必须首先考虑:使用VB编写的修改器需要VB的运行库才能运行。如果考虑到有些使用者(实际上可能是大部分使用者)没有运行库,那么在最后制作的ZIP压缩文件中就必须包含这些庞大的文件。在下面的教程里我将制作一个修改器,如果为它再制作一个安装程序,那么整个修改器的体积将超过1MB。其中包括一个很好的安装和反安装程序,但大部分还是VB40032.DLL 这个文件。
除了以上这点,使用VB制作修改器是非常简单的。一旦制作了多次后,你会发现能很快地制作出一个修改器。而且使用VB制作的修改器能够毫无困难地解决游戏运行时的动态内存分配问题,因此即使是最新的游戏,也可以使用VB制作修改器。在本教程中将不涉及动态内存分配,因为虽然简单,但仍然属于一个高级的选项。
一些背景知识
不象C语音,VB不会自动包括普通的API函数的声明,因此我们必须把他们加入我们的项目文件。在几乎所有的修改器中会使用到6个主要的函数,讨论如下:
1. FindWindow(ClassName, WindowTitle) - FindWindow 返回符合指定的类名( ClassName
)和窗口名( WindowTitle )的窗口句柄。对我们来说,可以让ClassName 为空( Null ),只给出游戏的
WindowTitle。函数应该这样声明:Declare Function FindWindow Lib "user32" Alias
"FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String)
As Long
2. GetWindowThreadProcessId(WindowHandle, ProcessId) - 在这里我们把FindWindow
函数中得到的句柄作为参数,来获得进程标识符(ProcessId )。声明如下:Declare Function
GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId
As Long) As Long
3. OpenProcess(DesiredAccess, Inherit, ProcessId) -
这个函数将返回一个我们目标进程的句柄,可以用来对目标进行读写操作。DesiredAccess
参数的值决定了句柄对进程的存取权利,对我们来说,要使用PROCESS_ALL_ACCESS (完全存取权限)。Inherit 应该总是
False。ProcessId 是从GetWindowThreadProcessId 函数中取得的。Declare Function
OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
4. CloseHandle(ProcessHandle) - 每一个打开的句柄必须呼叫这个函数来关
闭。Declare Function
CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
5. WriteProcessMemory(ProcessHandle, Address, value, Sizeofvalue, BytesWritten) - 把指定的值value 写入由Address 指定的目标地址。Declare Function
WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
6. ReadProcessMemory(ProcessHandle, Address, value, Sizeofvalue, BytesWritten) - 把Address 指定的目标地址的值存入value 位置的变量中。Declare Function
WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
这些函数一环扣一环,缺一不可。更详细的内容可以参考VB的帮助文件。一个简单的修改器范例
如何使上面介绍的这些函数一起工作,制作出我们需要的修改器呢?下面是一个为Windows的计算器程序制作修改器的例子。这个修改器将读出计算器窗口中显示的数值,并在点击一个按钮后在计算器窗口中显示我们的名字。
首先我们需要找到计算器显示窗口中显示值的地址。本教程不是关于如何进行内存搜索,因而我将只作简单的说明:
·在计算器窗口中输入123456
·使用你喜欢的任何一种内存地址搜索程序寻找字串123456
·使用另一个值重复上面的过程直到只返回1个地址
那是制作我们的修改器需要的唯一一个地址。在我的计算器程序里这个地址是40B181 hex, 4239745
dec。用你找到的地址替代在下面的代码里使用的这个地址。
现在让我们开始设计修改器的界面:
·在VB中新建一个项目,加入一个文本框( Textbox )、一个按钮和一个计时器( timer
)。文本框用来显示从计算器窗口取得的字串,按钮用来把我们的名字传到计算器窗口
·把表单( form )的标题( Caption )属性设为Calculator Trainer
·把文本框改名为txtDisplay 并清除Text 属性
·把计时器改名为ReadTimer 并把间隔( interval )设为500
·把按钮的标题改为Display Name,按钮的名字改为btnPasteName
在这个修改器中我们将使用所有6个函数,ReadProcessMemory、WriteProcessMemory、OpenProcess、GetWindowThreadProcessId、FindWindow 和CloseHandle。在项目中插入一个新的模块,增加下列代码。(下面的一些行自动换行了,在你的模块中每一句必须在一行里,或使用延长符_)
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long