用VB编写游戏修改器图文教程

2003-07-18 19:20 | poorboy

※前言※


这篇教程是针对不会编程的人写的,语言及技术上力求尽量简单,SO在大虾的眼里一定超简单:)。
目前我们用的动态修改器都有提供保存修改地址的功能,更甚者金山游侠2002还有生成可执行文件修改器的功能。不过用这些修改器修改不太灵活,比如:如果你要修改的地方有几千处,难道你还一一的改?但如果自己编写的话就可以让电脑代劳^0^(下面会讲到)。另一方面把自己的修改成果以修改器的形式和别人分享,会使自己(修改)所付出的劳动更有意义。

我写这篇文章不是要教读这篇文章的人成为VB高手(我也没这个能力),所以有些问题我不会讲的很清楚,对于读者来说也不必过分注意一些技术细节,很多东西你照着做就行了。另外此教程只是针对游戏中地址固定的游戏,如果游戏中地址不固定(动态分配),那就需要用到汇编知识了,修改动态地址的游戏不在教程的讨论范围内

※基础篇※


在讲如何编写前有必要讲一下基础的VB语法,以使你能看懂后面写的代码:3

下面是本教程将会用到的语句:
=============================================================================
Dim 名称 as 类型

说明:上面的语句是一个声明变量的语句,所谓变量简单的说就是一个‘容器’,用来存放‘数值’,而声明变量就是告诉系统建立一个‘容器’。‘类型’是用来告诉系统这个‘容器’有多大。

例如:Dim eyesonline As Long '建立一个名为eyesonline的容器(变量),并且这个变量在内存中占用4个字节。
==============================================================================
If 条件 Then
程序语句1
End If

If 条件 Then
程序语句1
Else
程序语句2
End If
说明:上面的语句的意思是,如果(所给的)‘条件’成立,就执行‘程序语句1’(注:程序语句1可以是多个语句的组合,程序语句2也一样),如果‘条件’不成立,(Else)将执行‘程序语句2’。

例如 If eyesonline = 253 Then '注意这行的‘=’是比较是否相等的意思,在‘条件’语句中‘=’就是这个意思,如果相等则‘条件’成立,如果不相等则‘条件’不成立
eyesonline = 874 '而这一行及下面一行的‘=’是将874或233这个数存入eyesonline这个变量中
Else
eyesonline = 233
End If

====================================================================
For i=1 To X
程序语句3
Next i

说明:这个语句是个循环语句,它的作用是让电脑连续X次执行程序语句3。
====================================================================
eyesonline(参数1,参数2,参数3,....参数N)
说明:这是一个名为eyesonline的函数,在使用时要填入相应的参数。参数间要用‘,’隔开。
在VB中有时函数不一定要带有‘()’(准确的说是不能带),下面你会看到,这里说一下以防你
看到会奇怪,我也是才知道,呵呵

====================================================================

※分析篇※


程序:

我们要用自己做的程序来修改另外一个程序(进程),但是我们的程序怎样知道哪个程序(VGS)是我们要
修改的呢。这里要用到一个工具软件:spy++。
先起动VGS然后再起动spy++
见图一:

我们可以从列表中找到VGS的进程(上图中选中的那项)
然后在VGS的进程选项上单击右键,在弹出的菜单中选Properties....这项
见图二、三


在图三中红框中的信息就是我们所需要的(复制下来),只要将这个信息告诉我们的程序,它就知道要修改的程序(VGS)在哪里。

游戏:

本教程中要改的游戏是《前线任务--决择》
在这个游戏中武器装备分四类,先找出一个武器的数量的地址,通过观察游戏运行的内存可以看出,游戏中四类装备分别存放在四个区域,每类装备的数据基本上连续放在一块的,每个武器有两个值是我们要改的:‘数量’,‘可用/不可用’(简称y/n),‘数量’要改为9,‘y/n’要改为1

比如:手持武器的第一个武器的‘数量’起始地址是404D7BA,‘y/n’的地址是404D7BC,第一个武器的‘数量’与第二个武器的‘数量’地址相差C,第一个武器的‘y/n’与第二个武器的‘y/n’也相差C。手持武器有27个,知道差值及武器的数量,我们就可以用一个循环让程序自动修改了:

For i=1 To 27
WriteProcessMemory hOK, ByVal a1, temp1, 1, 0
a1 = a1 + &HC
WriteProcessMemory hOK, ByVal a2, temp2, 1, 0
a2 = a2 + &HC
Next i

WriteProcessMemory是一个往目标进程的内存地址中写入数值的函数,第一个参数是要修改的进程的句柄(也就是门牌号),第二个参数是保存有地址的变量,第三个参数保存有要填入数值的变量,第四个参数是要写入的字节数,第五个参数我也不太清楚:D设为0就行了

※行动※


首先我们要打开VB新建一个标准工程。
见图四、五


点击菜单栏中的‘工程->添加模块’新建一个模块将以下代码复制到里面
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
或者你可以用APILOAD这个程序生成以上代码
见图六

然后双击图五中的我所标出的4将界面切换回到窗体设计界面上。
我们要用到三个控件:图五中的1、2、3,分别将其拖到窗体上(图五5)然后适当改变他们的大小以适应你的要求。
我们将要用到三个控件分别是:Label控件图五1、CommandButton控件图五2、CheckBox控件图五3

Label控件要用的属性有:Caption
CommandButton控件要用的属性有:Caption
CheckBox控件要用的属性有:Value、Caption

先选中要设置的控件,然后在图五6的区域设置。找到相关的属性选一个或填入值即可。
Label控件可以用来显示一些文字,如你的名字。设置Caption属性
CommandButton控件是个按钮,用户按下后会执行一些代码,设置Caption属性可以在控件上显示一些文字,用来说明这个按钮有什么用。
CheckBox控件是用来作开关用的。设置Caption属性,写入说明文字让使用者知道这个开关有什么作用。设置Value属性为Checked,让程序起动时它就是开的。
下图是设计好的图片
图七、八:



设计好界面后就可以双击(窗体上的)CommandButton控件产生一个Click事件

Private Sub Command1_Click()
自定义代码区
End Sub

见图九:


在Click事件的自定代码区写入我们的代码,当程序运行时,用户按下按钮就会执行自定义代码区的代码。

以下是我写的代码:
Private Sub Command1_Click()
Dim temp1 As Long
Dim temp2 As Long
Dim hwnd As Long
Dim hOK As Long
Dim ID As Long '声明变量
hwnd = FindWindow("CVGS Double-Secret-Probation Mutex", vbNullString) '获得VGS的窗口句柄,并将句柄保存在hwnd变量中
If hwnd = False Then '测试hwnd变量,如果VGS没有起动
MsgBox ("VGS没有打开") '则提示用户打开程序MsgBox()这个函数的作用是弹出一个小窗口显示""中的字符
Exit Sub '退出Click事件
Else
GetWindowThreadProcessId hwnd, ID '获得VGS进程的ID,并保存在ID变量中
hOK = OpenProcess(PROCESS_ALL_ACCESS, 0, ID) '以获得编辑VGS进程的全部权限,反OpenProcess函数将反回一个值并保存在hOK变量中
If hOK = 0 Then '测试有没有获得修改权限
MsgBox ("没有找开修改权限")
Exit Sub
Else '如果获得修改权限将执行以下代码
'开关1
If Check1.Value = Checked Then '如果Check1被打开,则执行下面的语句
Dim a1 As Long, a2 As Long, b1 As Long, b2 As Long '声明变量
Dim c1 As Long, c2 As Long, d1 As Long, d2 As Long '声明变量
a1 = &H404D7BA '将地址404D7BA存入变量a1,加&H表示404D7BA是个十六的数值
a2 = &H404D7BC
b1 = &H404D9B2
b2 = &H404D9B4
c1 = &H404DABA
c2 = &H404DABC
d1 = &H404D90A
d2 = &H404D90C
temp1 = &H9
temp2 = &H1
Dim i As Integer
For i = 1 To 27
WriteProcessMemory hOK, ByVal a1, temp1, 1, 0
a1 = a1 + &HC
WriteProcessMemory hOK, ByVal a2, temp2, 1, 0
a2 = a2 + &HC
Next i
For i = 1 To 20
WriteProcessMemory hOK, ByVal b1, temp1, 1, 0
b1 = b1 + &HC
WriteProcessMemory hOK, ByVal b2, temp2, 1, 0
b2 = b2 + &HC
Next i
For i = 1 To 25
WriteProcessMemory hOK, ByVal c1, temp1, 1, 0
c1 = c1 + &HC
WriteProcessMemory hOK, ByVal c2, temp2, 1, 0
c2 = c2 + &HC
Next i
For i = 1 To 12
WriteProcessMemory hOK, ByVal d1, temp1, 1, 0
d1 = d1 + &HC
WriteProcessMemory hOK, ByVal d2, temp2, 1, 0
d2 = d2 + &HC
Next i
End If
'开关2
If Check2.Value = Checked Then
Dim a001 As Long, a002 As Long, a003 As Long
Dim b001 As Long, b002 As Long, b003 As Long
Dim c001 As Long, c002 As Long, c003 As Long
a001 = &H406A514
a002 = &H406A548
a003 = &H406A57C
b001 = &H406A5AC
b002 = &H406A5E4
b003 = &H406A618
c001 = &H406A64C
c002 = &H406A680
c003 = &H406A6B4
temp1 = &HA
temp2 = &HB
WriteProcessMemory hOK, ByVal a001, temp2, 1, 0
WriteProcessMemory hOK, ByVal a002, temp1, 1, 0
WriteProcessMemory hOK, ByVal a003, temp1, 1, 0
WriteProcessMemory hOK, ByVal b001, temp2, 1, 0
WriteProcessMemory hOK, ByVal b002, temp1, 1, 0
WriteProcessMemory hOK, ByVal b003, temp1, 1, 0
WriteProcessMemory hOK, ByVal c001, temp2, 1, 0
WriteProcessMemory hOK, ByVal c002, temp1, 1, 0
WriteProcessMemory hOK, ByVal c003, temp1, 1, 0
End If
MsgBox ("complete!")
End If
End If
CloseHandle (hOK)
End Sub

写完上面的代码(或你自己的代码)后就可以编译生成程序,选"文件->生成***.EXE"
然后运行试试。

见图十



如果你看不懂上面的代码,下面的模板你可以用。


Dim hwnd As Long
Dim hOK As Long
Dim ID As Long
hwnd = FindWindow("", vbNullString) '在""中写上要修改程序的类名,用spy++得到
If hwnd = False Then
MsgBox ("") '在""写入‘XXX没有找开’,XXX是你要修改的程序名
Exit Sub
Else
GetWindowThreadProcessId hwnd, ID
hOK = OpenProcess(PROCESS_ALL_ACCESS, 0, ID)
If hOK = 0 Then
MsgBox ("没有找开修改权限")
Exit Sub
Else
在此区域写上你自己的代码
MsgBox ("complete!")
End If
End If
CloseHandle (hOK)


※总结※


其实我对VB也不太了解,但只所以选择VB来写这篇教程是因为:
1、VB易学
2、VB非常强大
3、网上有精简版才几M,虽然很多功能都去掉了但做修改器还是绰绰有余的,其它的编程工具体积太大。

VB的精简版和SPY++及APILOAD这三个软件我已经打包上传到眼睛的FTP中,你也可以到网上下载。

第一次写教程,脑子里一片空白,想到哪写到哪,肯定有不足之处,欢迎指正。另外如果你看了有什么不懂的地方可以留言问我或其他人(天幻有很多VB高手)

如果你对VB有兴趣,我在这里推荐两本书:VB6程序员指南、VB6语言参考手册(都已上传到眼睛的FTP中)


-