首页
社区
课程
招聘
各位大大,在VB6中如何读取内存数据到一个二维数组?
发表于: 2010-10-11 08:36 6649

各位大大,在VB6中如何读取内存数据到一个二维数组?

2010-10-11 08:36
6649
想要做个程序读取指定地址的数据,但是在第二个语句:ReadProcessMemory gmePro, ByVal sitBase(sitNum), chessData(8, 25), 200,   运行时,只能读取当前指定地址的第一个数据,其他的数据无法读取或显示,请教各位大大,(我的代码 )如下,我的代码错在什么地方了,第一个ReadProcessMemory语句读出的数据是正确的,可第二个,测试了很多次,只能读取一个数据到当前的chessData(8, 25),二维数组中,如何才能正确的把指定地址的内存数据读取到指定的二维数组,并显示到文本框中呢?
'-----------------------------------------------API函数声明部分--------------------------------------
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
'关闭进程函数
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

'-------------------------------测试代码部分---------------------------------------
Private Sub Command1_Click()
Dim gmeH As Long
Dim gmePid As Long
Dim gmePro As Long
Dim sitNum As Long
Dim readByte As Long
Dim sitBase(3) As Long
    sitBase(0) = &H479418
    sitBase(1) = &H479FFC
    sitBase(2) = &H47ABE0
    sitBase(3) = &H47B7C4
Dim chessData(1 To 8, 1 To 25) As Byte
Dim x As Integer
Dim y As Integer
Dim s As String
gmeH = FindWindow(vbNullString, gmeCaption)
If gmeH = 0 Then MsgBox "程序未启动!"
GetWindowThreadProcessId gmeH, gmePid
gmePro = OpenProcess(PROCESS_ALL_ACCESS, False, gmePid)
If gmePro = 0 Then MsgBox "进程打开失败!"
ReadProcessMemory gmePro, ByVal sitNumBase, sitNum, 4, readByte
ReadProcessMemory gmePro, ByVal sitBase(sitNum), chessData(8, 25), 200, readByte
'Text2.Text = ""
For y = 1 To 8
    s = ""
    For x = 1 To 8
        s = s + CStr(chessData(8, 25)) + "|"
        Text2.Text = s
    Next x
Next y
Text1.Text = CStr(sitNum)
CloseHandle gmePid
CloseHandle gmePro
End Sub

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 517
活跃值: (35)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
很明显,ReadProcessMemory gmePro, ByVal sitBase(sitNum), chessData(8, 25), 200, readByte
你这里是想用200个字节的数据填写一个数组单元chessData(8, 25),而这个单元被定义为Byte,故你只能得到一个数据是非常正确的。不是程序的错,是你的错。
我觉得:
1、这里应该传的是地址,采用byref chessData(0, 0)试试看;
2、使用一维数组接收数据,使用循环填充二维数组;
3、你的循环也似乎有些问题。

未测试,仅做参考。
2010-10-11 08:57
0
雪    币: 163
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢你的建议,我先试试
2010-10-11 09:35
0
雪    币: 163
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
ByRef chessData(0,0)不行,提示缺少表达式,编译错误.
2010-10-11 09:39
0
雪    币: 163
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
使用一维数组,得到的还是第一个数据,如果是我的循环有问题,那么空上循环应该怎么写?
2010-10-11 09:49
0
雪    币: 517
活跃值: (35)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
For y = 1 To 8
    s = ""
    For x = 1 To 8
        s = s + CStr(chessData(8, 25)) + "|"
        Text2.Text = s
    Next x
Next y
始终读取的是同一个单元,难道没看见?


:
2010-10-11 14:34
0
雪    币: 163
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
汗^O^,是我没看清楚,抱歉.
2010-10-11 15:31
0
雪    币: 163
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
那我的这个循环语句,应该怎么写才正确呢??
2010-10-11 15:47
0
雪    币: 145
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
Dim bytMap(my * 32 - 1) As Byte
    Call ReadProcessMemory(hProcess, ByVal mapAddr, bytMap(0), my * 32, 0&)

能不能帮我解释一下,参数bytMap(0), my * 32这么写的意思,也就是说为什么这么写.
这里要看 ReadProcessMemory 的声明方式是 Byval 还是 Byref,第三个参数应该传入指向缓冲区的指针,而这儿楼主的声明应该是 Byref,所以是 bytMap(0), 如果按 Byval,应该是 Byval Varptr(bytMap(0))。

“第四个参数表示数组的元素个数。”
第四个参数是代表缓冲区的大小,因为是 Byte 类型,所以是my * 32,后面实际上省略了 * 1。如果缓冲区按 Long 声明,即Dim lngMap(my * 32 - 1) As Long,那么就是 my * 32 * 4。
2010-10-11 19:05
0
雪    币: 145
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
10
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long

您说应该是Byval Varptr(bytMap(0))这样写,是什么意思呀

传指针。

这里用Byval Varptr(bytMap(0)) 或 bytMap(0) 都可以。
2010-10-11 19:06
0
雪    币: 145
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
11
至少我看来,你的问题多多啊
2010-10-11 19:07
0
雪    币: 255
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
顶下…不懂………
2010-10-11 19:38
0
雪    币: 163
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
地确,我这段代码,如果把chessData(8,25)改为chessData(1,8),则可以正确读取第一列的数据,当然,循环语句相应改为:
For y = 1 To 8
    s = ""
    For x = 1 To 8
        s = s + CStr(chessData(x, y)) + "|"
        Print
        Text2.Text = s
    Next x
Next y
可这样的改动也只是能读取这个二维数据中的第一列数据,其他的数据无法读取或显示.换句话说,我觉得ReadProcessMemory函数的声明应该是没有问题的.
2010-10-12 07:46
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
看看
2010-10-12 15:41
0
雪    币: 163
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
最终还是我的循环语句有错误,需要用两个嵌套的For循环才能正常读出.谢谢BlueT和winnip的指点.
2010-10-12 17:44
0
游客
登录 | 注册 方可回帖
返回
//