标题: vb问题(3) [打印本页]
作者:
阿尔法孝直 时间: 2008-6-10 15:52 标题: vb问题(3)
请看下面一段程序:
(声明API函数部分省略。。。)
Private Sub Command1_Click()
Dim i As Byte , Data As Byte , MyStr As String*1
For i=0 To 255
Data=i
WriteProcessMemory MyProcess, Address, Data, 1, 0&
ReadProcessMemory MyProcess, Address, MyStr, 1, 0&
Data=Asc(MyStr)
Debug.Print Data
Next i
End Sub
问题是,程序运行后,显示如下结果:
0
1
2
3
4
5
中间省略……
124
125
126
127
0
0
0
中间省略……
0
0
0
现在我希望0~255的数据都能从内存读出来,如下:
1
2
3
4
5
中间省略……
251
252
253
254
255
问应该如何修改程序???
作者:
土狼 时间: 2008-6-10 16:20
不能肯定问题出在哪,感觉是读写过程中出了错
个人建议楼主不要用byte这种类型,大大方方的用integer,不在乎那点内存吧
作者:
阿尔法孝直 时间: 2008-6-10 16:23
没用,这个是ASCII编码问题,用Integer就更不行了。
作者:
司徒苍月 时间: 2008-6-10 17:13
ASCII编码7+1位校验,所以只能是2的7次方
作者:
Maxwell 时间: 2008-6-10 18:09
机器上没有VB,晚上回去没有网络,明天再看。。。
作者:
Maxwell 时间: 2008-6-11 10:40
昨天没时间试,简单猜测一下吧。
Private Sub Command1_Click()
Dim i As Byte , Data As Byte , MyStr As String*1
For i=0 To 255
Data=i
WriteProcessMemory MyProcess, Address, Data, 1, 0&
ReadProcessMemory MyProcess, Address, MyStr, 1, 0&
Data=Asc(MyStr)
Debug.Print Data
Next i
End Sub
首先i不应该定义为byte类型,不然循环会溢出。
MyStr应该是个引用,所以把MyStr的地址传给ReadProcessMemory恐怕会有问题,不过你前127个倒是显示出来了,估计还是跟String内部实现机制有关,String内部可能是unicode存储的,对高于127的字符需要特别处理,这个仅是猜测,但是MSDN中对String的描述中有一条就是不要用于任何跟数值有关的地方。你用另外一个byte类型的变量传给ReadProcessMemory不行吗?
作者:
Maxwell 时间: 2008-6-11 10:41
原帖由
司徒苍月 于 2008-6-10 17:13 发表
ASCII编码7+1位校验,所以只能是2的7次方
作者:
阿尔法孝直 时间: 2008-6-11 14:30
现在问题是怎么解决,我要搞一个内存修改器
作者:
fantasydog 时间: 2008-6-11 14:48
不了解VB。
不过Byte是unsigned char么?
Asc这个函数返回值又是啥?unsigned char?
有符号的东西其实蛮讨厌的,移位都移不动
作者:
Maxwell 时间: 2008-6-11 14:58
原帖由 阿尔法孝直 于 2008-6-11 14:30 发表
现在问题是怎么解决,我要搞一个内存修改器
你用另外一个byte类型的变量传给ReadProcessMemory不行吗?
二进制这事儿VB确实不太擅长,有这功夫都可以学学其他语言了,当然仅供参考,当前还是先解决问题为主。
作者:
Maxwell 时间: 2008-6-11 14:59
原帖由 fantasydog 于 2008-6-11 14:48 发表
不了解VB。
不过Byte是unsigned char么?
Asc这个函数返回值又是啥?unsigned char?
有符号的东西其实蛮讨厌的,移位都移不动
移位移不动是不是因为是const类型的?
作者:
阿尔法孝直 时间: 2008-6-11 15:34
原帖由
Maxwell 于 2008-6-11 14:58 发表
你用另外一个byte类型的变量传给ReadProcessMemory不行吗?
二进制这事儿VB确实不太擅长,有这功夫都可以学学其他语言了,当然仅供参考,当前还是先解决问题为主。
不行,好早就试过,会出错。
作者:
Maxwell 时间: 2008-6-11 16:14
原帖由 阿尔法孝直 于 2008-6-11 15:34 发表
不行,好早就试过,会出错。
查了一下第3个参数是ByVal lpBuffer As Any,这是byte不行的原因,另外string是用BSTR实现的,所以对于大于127的值可能有特别处理。
你贴一个能运行的代码吧,现在想了几个方案,不知道哪个能用,回头我试试。
作者:
龙王 时间: 2008-6-13 16:55
这里要用字符串数组,byte变量不行的,用VC++吧,用1个char 数组,然后CString
作者:
阿尔法孝直 时间: 2008-6-13 18:22
Sorry,VC++我不熟。
作者:
Maxwell 时间: 2008-6-14 01:29
我是说你先贴一段能运行但是结果不正确的代码,然后我好试试怎么能用,不要让我自己补全代码了。
作者:
fantasydog 时间: 2008-6-17 13:57 标题: 回复 #11 Maxwell 的帖子
不是,编译器直接报错。
就是不能移signed类型的,毕竟有个符号位在那里,处理起来相当麻烦。
我估计是编译器图省事,直接不准移位有符号数了。
再者,有符号数的移位通常意义也不大。乘除2的幂次的情况本来就少,也提高不了多少性能。
作者:
Maxwell 时间: 2008-6-17 14:34
晕,什么语言?c#?从来没觉得c/c++中有不能移位的,就连浮点型真想移都能移了。到了机器码那一级,有没有符号位处理上都基本一样。
作者:
阿尔法孝直 时间: 2008-6-20 15:51
代码贴上来,大家看看。
顺便帮忙解决一下数据写不进内存的问题。
[ 本帖最后由 阿尔法孝直 于 2008-6-20 15:55 编辑 ]
附件:
[简易内存读写器的代码]
RWMemory.rar (2008-6-20 15:55, 2.86 K) / 该附件被下载次数 129
http://xycq.org.cn/forum/attachment.php?aid=62933
作者:
Maxwell 时间: 2008-6-20 16:39
晕,到底是写不进去还是读不出来?哪个文件的哪个函数哪一行有问题,这样说明一下是不是更利于找问题?
作者:
阿尔法孝直 时间: 2008-6-20 16:55
第一个问题:
写内存的程序段:
Private Sub Command3_Click()
WriteProcessMemory nHandle, nAddress, CLng(Text2.Text), nByte, 0&
End Sub
就红色这句,改个数执行之后再按“读取”,又变成原来的数。
第二个问题:
读内存的程序段:
Private Sub Command1_Click()
On Error Resume Next
Dim nStr As String * 1
Dim Result As Long
Dim i As Byte
For i = 0 To nByte - 1
ReadProcessMemory nHandle, nAddress + i, nStr, 1, 0&
Result = Result + Asc(nStr) * 256 ^ i
Next i
Text2.Text = Trim(Str(Result))
End Sub
就红色的这两句,第一句执行时,凡是任何单字节在128~255之间的数据,读出来都是0,即
Asc(nStr)=0
作者:
Maxwell 时间: 2008-6-20 17:04
知道了,周末有事,下周来看看。
作者:
阿尔法孝直 时间: 2008-6-23 17:46
第一个问题自己改了代码后,解决了。
现在剩下第二个问题:
读内存的程序段:
Private Sub Command1_Click()
On Error Resume Next
Dim nStr As String * 1
Dim Result As Long
Dim i As Byte
For i = 0 To nByte - 1
ReadProcessMemory nHandle, nAddress + i, nStr, 1, 0&
Result = Result + Asc(nStr) * 256 ^ i
Next i
Text2.Text = Trim(Str(Result))
End Sub
就红色的这两句,第一句执行时,凡是任何单字节在128~255之间的数据,读出来都是0,即
Asc(nStr)=0
附件:
RWMemory.rar (2008-6-23 17:46, 2.98 K) / 该附件被下载次数 111
http://xycq.org.cn/forum/attachment.php?aid=63031
作者:
Maxwell 时间: 2008-6-24 10:52
想必楼主找到了一个可以写入的地址,不过我没有找到,我选择内存读写器,随机设置了几个地址写入都不成功。
作者:
阿尔法孝直 时间: 2008-6-24 11:20
随便打开一个游戏,比如曹操传,找到曹操的HP地址,看看行不行
作者:
Maxwell 时间: 2008-6-24 14:28
好容易想了个办法测试了一下代码,有两种方法能够正确执行,有一种多少有点hack,说一下另一种吧,用下面的代码可以实现原来想要的功能,其实这里面还是利用了x86特性将byte, word, dword用一行代码处理了。VarPtr是一个内置函数,用于取变量的地址,相当于c/c++中的单目运算符&。
Private Sub Command1_Click()
On Error Resume Next
Dim data As Long
ReadProcessMemory nHandle, nAddress, VarPtr(data), nByte, 0&
Text2.Text = Trim$(Str$(data))
End Sub
你说写已经没问题那我就不测了,我怕写进去我的程序崩掉,参考这个代码相信也能用一行解决问题。
作者:
阿尔法孝直 时间: 2008-6-24 16:42
没用,还是一样。
不过前面的情况有错,应该是:
128~254还是0,
0~127或255正常读出。
[ 本帖最后由 阿尔法孝直 于 2008-6-24 16:51 编辑 ]
作者:
Maxwell 时间: 2008-6-24 16:54
你在什么环境下测试的?如果255能读出来不可能128-254读不了
我测试的时候是读取自身进程的连续16个字节,其中有90,3,255,177,240。
作者:
阿尔法孝直 时间: 2008-6-24 17:18
原帖由
Maxwell 于 2008-6-24 16:54 发表
你在什么环境下测试的?如果255能读出来不可能128-254读不了
我测试的时候是读取自身进程的连续16个字节,其中有90,3,255,177,240。
在XP SP2下用VB6按F5直接运行程序
我写一个字节再读出来
确实不行
不过情况又有变化:变成0~128或255能读,129~254不能读
作者:
Maxwell 时间: 2008-6-24 17:24
你写的字节有没有写进去是个问题,所以我直接找一段地址挨着读,我后来试了一下,对于我测试的地址用你的代码写不进去。
作者:
阿尔法孝直 时间: 2008-6-24 17:53
金山游侠V检验的结果:
129~254能写进去,不过用金山游侠V读出来是0
内存数据是129~254,读出来是0
0~128或255读写都正常。
作者:
Maxwell 时间: 2008-6-24 17:59
金山游侠读出来是0怎么知道是写进去了?我觉得用string有它天然的缺陷,内部是BSTR,当byte用很难说会出什么问题。
作者:
阿尔法孝直 时间: 2008-6-24 18:02
原帖由 Maxwell 于 2008-6-24 17:59 发表
金山游侠读出来是0怎么知道是写进去了?
执行后,数据由非0变为0,说明写进去了。
作者:
Maxwell 时间: 2008-6-24 18:12
你是说写进去之后在被写的程序里数值变了,而金山游侠读出来的也是0?那是不是因为程序又重新刷回了0,找个别的程序写写试试。
作者:
阿尔法孝直 时间: 2008-6-24 18:22
不会。因为我用0~128或255时没出现这种问题,且换了其他程序也是一样。
作者:
Maxwell 时间: 2008-6-24 20:00
那你读一段现有非0数据,看看有没有落在这个范围内的,根据推测,问题不在代码上。
作者:
阿尔法孝直 时间: 2008-6-24 21:43
我试过,在0~128或255完全正常,没有任何问题
作者:
Maxwell 时间: 2008-6-24 21:59
既然试过没有问题那就不是读取代码的问题了,读取代码从机制上没有特殊处理过。建议找个记事本读读数据试试,游戏里面的不确定性比较多。
作者:
阿尔法孝直 时间: 2008-6-24 22:29
记事本MS是只读进程,写进去什么,读出来都是原来的值。
不过可完全访问的进程都是0~128或255读写正常。
作者:
Maxwell 时间: 2008-6-25 08:30
我的意思是从记事本里读连续100个位置,看看有没有在129-254之间的数字。或者读内存读写器试试,0x00400001-0x00400010之间有几个数。
作者:
阿尔法孝直 时间: 2008-6-25 10:40
这是我用金山游侠读取“记事本”进程十六进制0x1000040~0x100008F(十进制16777280~16777359)连续80个字节的结果(十六进制)
红色为0x81~0xFE(十进制129~254)
0E
| 1F
| BA
| 0E
| 00
| B4
| 09
| CD
| 21
| B8
| 01
| 4C
| CD
| 21
| 54
| 68
|
69
| 73
| 20
| 70
| 72
| 6F
| 67
| 72
| 61
| 6D
| 20
| 63
| 61
| 6E
| 6E
| 6F
|
74
| 20
| 62
| 65
| 20
| 72
| 75
| 6E
| 20
| 69
| 6E
| 20
| 44
| 4F
| 53
| 20
|
6D
| 6F
| 64
| 65
| 2E
| 0D
| 0D
| 0A
| 24
| 00
| 00
| 00
| 00
| 00
| 00
| 00
|
EC
| 85
| 5B
| A1
| A8
| E4
| 35
| F2
| A8
| E4
| 35
| F2
| A8
| E4
| 35
| F2
|
这是我用内存读写器读取“记事本”进程十进制16777280~16777359(十六进制0x1000040~0x100008F)连续80个字节的结果(十进制)14
| 31
| 0
| 14
| 0
| 0
| 9
| 0
| 33
| 0
| 1
| 76
| 0
| 33
| 84
| 104
|
105
| 115
| 32
| 112
| 114
| 111
| 103
| 114
| 97
| 109
| 32
| 99
| 97
| 110
| 110
| 111
|
116
| 32
| 98
| 101
| 32
| 114
| 117
| 110
| 32
| 105
| 110
| 32
| 68
| 79
| 83
| 32
|
109
| 111
| 100
| 101
| 46
| 13
| 13
| 10
| 36
| 0
| 0
| 0
| 0
| 0
| 0
| 0
|
0
| 0
| 91
| 0
| 0
| 0
| 53
| 0
| 0
| 0
| 53
| 0
| 0
| 0
| 53
| 0
|
作者:
Maxwell 时间: 2008-6-25 11:54
我测试了前3个红字的值,都与你提供的金山游侠的值相同。
我的系统win2003serversp2 vb6sp6,使用下面的读取代码
Private Sub Command1_Click()
On Error Resume Next
Dim data As Long
ReadProcessMemory nHandle, nAddress, VarPtr(data), nByte, 0&
Text2.Text = Trim$(Str$(data))
End Sub
欢迎光临 轩辕春秋文化论坛 (http://xycq.org.cn/forum/) |
Powered by Discuz! 5.0.0 |