急!VB程序能否读取&修改其他程序的内存单元?

时间:2021-10-19 01:18:11
怎么做??
我只能给这么多分,
我已倾家荡产了。
请不要再删我的帖子了。
55555555

14 个解决方案

#1


VB不支持指针,所以修改内存需要装入VC的DLL才行!

#2


能否说详细点?
如具体的DLL文件名和方法,
我现在很需要。
我可以把所有的分给你,不过请先教我咋送分好吗?

#3


我说的是用VC自己写一个DLL以后,让VB去调用啊!
.....我不明白你有什么必要这样做?说具体点吧!

#4


在VB中,你可以用三个未公开的函数取得内存地址
VarPtr,StrPtr和ObjPtr
然后将调用WIN32 SDK中的API完成你想要完成的功能。

#5


我要做一个游戏修改器(都是女人惹的祸!)
要让其修改游戏程序的内存单元,就是这么回事。
网友 taolei 提供下列信息

用windows API可以做到。相关的API有:
OpenProcess
VirtualQueryEx
ReadProcessMemory
WriteProcessMemory等。  

但是我找不到具体的调用方法介绍。

再:请问JamesDT
VarPtr,StrPtr和ObjPtr
这三个函数的具体调用参数说明一下可以吗?
还有,我会加分的,各位兄弟救我一下吧!

#6


VarPtr 取得变量的地址
StrPtr 取得String的地址
ObjPtr 取得对象的地址
均只有一个参数,返回Long

#7


我在尽量的加分,帮帮忙啊!
为何我只能加到127分???

#8


用纯粹的vb是不行的吧?
就是用c做,好象也只能用在win98里,nt和win2000是不行的,除非你的程序运行在ring0级。

#9


To QQRN:
  告诉你一个不幸的消息,用VB是实现不了你的要求的。
  你必须获得CPU的Ring0权限,才能修改其物理内存或拦截API等。而API中提供的几个函数对物理内存的修改是没有用处的。
  因为你想编写动态修改游戏的程序,VB肯定是不能胜任的,你必须用VC++来实现你想要的功能。最简单的做法是编写一个DLL,将其注入到其它进程中去,或者取得RING0权限后拦截相应的API函数。
  这些都是牵涉到底层的操作。所以VB是帮不上你的忙的!呵呵
  如果你有兴趣用VC++编写,我这里有一些例子!如:怎样取得RING0权限等等

#10


to JamesDT :
能否帮我做个DLL,只要能修改指定程序的指定内存单元就行了!
就算不能修改NT的也无妨!
至于C语言,我现在想学也太急了点了。
先说谢谢了!!!

555555555555,天,为何要如此待我!!!VB居然…………

#11


是同以进程的,还是不同进程的?

#12


QQRN:下面是如何修改进程内存的例子,在NT上测试通过,在95/98上也应该没问题。祝你好运。
Option Explicit
Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
'dwDesiredAccess   存取方式,一般用PROCESS_ALL_ACCESS就可以
'bInheritHandle    这里不用,必须是0
'dwProcessId       进程ID,自己想办法得到它,可用GetWindowThreadProcessId等函数,
'                  或是在VB里用Shell命令执行程序返回的值
'返回              进程Handle

Declare Function ReadProcessMemory Lib "Kernel32.dll" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesRead As Long) As Long
Declare Function WriteProcessMemory Lib "Kernel32.dll" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Any) As Long
'hProcess          进程Handle
'lpBaseAddress     指定的地址
'lpBuffer          读/写的缓冲区
'nSize             lpBuffer的大小(字节数)
'lpNumberOfBytesWritten 完成读写的字节数
'返回              非0 成功,0 失败

Type MEMORY_BASIC_INFORMATION
    BaseAddress As Long
    AllocationBase As Long
    AllocattionProtect As Long
    RegionSize As Long
    State As Long
    Protect As Long
    Type As Long
End Type
Declare Function VirtualQueryEx Lib "Kernel32.dll" (ByVal hProcess As Long, ByVal lpAddress As Long, info As MEMORY_BASIC_INFORMATION, ByVal dwLength As Long) As Long
Declare Function CloseHandle Lib "Kernel32.dll" (ByVal handle As Long) As Long


Public Const PROCESS_TERMINATE = &H1&
Public Const PROCESS_CREATE_THREAD = &H2&
Public Const PROCESS_SET_SESSIONID = &H4&
Public Const PROCESS_VM_OPERATION = &H8&
Public Const PROCESS_VM_READ = &H10&
Public Const PROCESS_VM_WRITE = &H20&
Public Const PROCESS_DUP_HANDLE = &H40&
Public Const PROCESS_CREATE_PROCESS = &H80&
Public Const PROCESS_SET_QUOTA = &H100&
Public Const PROCESS_SET_INFORMATION = &H200&
Public Const PROCESS_QUERY_INFORMATION = &H400&
Public Const PROCESS_ALL_ACCESS = &H1F0FFF

Public Const PAGE_NOACCESS = &H1
Public Const PAGE_READONLY = &H2
Public Const PAGE_READWRITE = &H4
Public Const PAGE_WRITECOPY = &H8
Public Const PAGE_EXECUTE = &H10
Public Const PAGE_EXECUTE_READ = &H20
Public Const PAGE_EXECUTE_READWRITE = &H40
Public Const PAGE_EXECUTE_WRITECOPY = &H80
Public Const PAGE_GUARD = &H100
Public Const PAGE_NOCACHE = &H200
Public Const PAGE_WRITECOMBINE = &H400
Public Const MEM_COMMIT = &H1000
Public Const MEM_RESERVE = &H2000
Public Const MEM_DECOMMIT = &H4000
Public Const MEM_RELEASE = &H8000
Public Const MEM_FREE = &H10000
Public Const MEM_PRIVATE = &H20000
Public Const MEM_MAPPED = &H40000
Public Const MEM_RESET = &H80000
Public Const MEM_TOP_DOWN = &H100000
Public Const MEM_4MB_PAGES = &H80000000
Public Const SEC_FILE = &H800000
Public Const SEC_IMAGE = &H1000000
Public Const SEC_VLM = &H2000000
Public Const SEC_RESERVE = &H4000000
Public Const SEC_COMMIT = &H8000000
Public Const SEC_NOCACHE = &H10000000
Public Const MEM_IMAGE = SEC_IMAGE

'Sample
Private FirstRWAddress As Long
Const BLOCKSIZE = 4096&
Sub test()
    Dim hProcess As Long
    Dim ProcessId As Long
    Dim r As Long
    Dim temp As Long
    ProcessId = Shell("NotePad.exe")
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, ProcessId)
    If hProcess = 0 Then
        MsgBox "OpenProcess Fail."
        Exit Sub
    End If
    ListValidMemory hProcess
    Dim b(0 To BLOCKSIZE - 1) As Byte
    r = ReadProcessMemory(hProcess, FirstRWAddress, b(0), BLOCKSIZE, temp)
    If r = 0 Then
        MsgBox "ReadProcessMemory Fail."
        CloseHandle hProcess
        Exit Sub
    End If
    
    r = WriteProcessMemory(hProcess, FirstRWAddress, b(0), BLOCKSIZE, temp)
    If r = 0 Then
        MsgBox "WriteProcessMemory Fail."
    End If
    CloseHandle hProcess
End Sub

'一个进程的独立运行空间是4Gb,在搜索某个数据时,从头到尾读一次就不是好方法。
'进程的运行空间简单可分为只读、可读写和禁用的三种类型,
'要得到这些地址,就要用VirtualQueryEx的方法
'下面的程序可以列出进程的只读和可读写的地址空间
Sub ListValidMemory(ByVal hProcess As Long)
    Dim base As Long
    base = 0
    Dim r As Long
    Dim info As MEMORY_BASIC_INFORMATION
    
    While base >= 0
        If VirtualQueryEx(hProcess, base, info, Len(info)) = 0 Then
            Exit Sub
        End If
        If info.Type <> 0 Then
            If info.Protect = PAGE_READWRITE Then
                Debug.Print Hex(base), info.RegionSize, "Page ReadWrite"
                If FirstRWAddress = 0 Then
                    FirstRWAddress = base
                End If
            ElseIf info.Protect = PAGE_READONLY Then
                Debug.Print Hex(base), info.RegionSize, "Page ReadOnly"
            ElseIf info.Protect = PAGE_EXECUTE_READ Then
                Debug.Print Hex(base), info.RegionSize, "Page Execute Read"
            ElseIf info.Protect = PAGE_EXECUTE_READWRITE Then
                Debug.Print Hex(base), info.RegionSize, "Page Execute ReadWrite"
            End If
            '如果是想搜索游戏数据,一般只需要在PAGE_READWRITE类型的地址空间里搜索就行了。
        End If
        base = base + info.RegionSize
    Wend
End Sub


#13


To:taolei

对不起了,这几天忙着编程,没来得及给你加分,抱歉。


#14


前天,我带着刚编好的游戏修改器来到学校,手上的磁盘就被人抢走了,正高兴的时候,他们又跑回来了。

“QQ啊!你弄的游戏修改器怎么用不了啊!是不是在玩我啊!”
“QQ,你的那个东西害得我的机子死了,是怎么回事啊!”
“QQ,你这家伙居然敢骗我!欠揍啊!”

“我……我没有啊!……我明明在WIN2000上改过啊!!!”小弟我惊恐万分。

“么事?你要我的“无罢漏”中“瘟两千”!!!”
“什么啊!谁象你那么白痴在WIN2000里玩游戏!!”
“天啊!你不会是又叫我重装系统吧,上周你刚把我的机子重装了3次系统。”

半个小时后,我在一片愤怒的叫声之中逃了出来。后面还跟着几句让我心惊肉跳的话:
“死QQ!下次不带来别想进教室!”
“你听好了QQ,作不好我记你十次旷课!还有你以前的记录一起加上!!!”

我带着一对黑眼圈,衣衫褴褛的刚上公车,就被司机一脚踢下:“乞丐还想上我的车!”
“………………虽说我穷,但是一圆八毛七分钱我还是有的!!!…………别急着开车啊……等等我啊!!!”
终于,我拖着一瘸一瘸的腿进了家门,想起刚才被门卫盘问了近一个小时,不禁气血翻腾,连忙自我安慰:“这样的门卫才能确保安全”尽量不想昨天刚被盗的新车。
经过一天一夜的努力……
终于,在RESET了N次,重装WIN98 N/100次,FDISK N/10000次之后,得出一个结论!
亲爱的taolei给的方法只能在WIN2000里用。我倒!
不过的确能改。所以分数照给!
我要重新发个帖子,希望大家来看看啊!就只多加了几个字——“WIN98”
还有,亲爱的taolei,请到来拿分
http://www.csdn.net/expert/TopicView.asp?id=47566

#1


VB不支持指针,所以修改内存需要装入VC的DLL才行!

#2


能否说详细点?
如具体的DLL文件名和方法,
我现在很需要。
我可以把所有的分给你,不过请先教我咋送分好吗?

#3


我说的是用VC自己写一个DLL以后,让VB去调用啊!
.....我不明白你有什么必要这样做?说具体点吧!

#4


在VB中,你可以用三个未公开的函数取得内存地址
VarPtr,StrPtr和ObjPtr
然后将调用WIN32 SDK中的API完成你想要完成的功能。

#5


我要做一个游戏修改器(都是女人惹的祸!)
要让其修改游戏程序的内存单元,就是这么回事。
网友 taolei 提供下列信息

用windows API可以做到。相关的API有:
OpenProcess
VirtualQueryEx
ReadProcessMemory
WriteProcessMemory等。  

但是我找不到具体的调用方法介绍。

再:请问JamesDT
VarPtr,StrPtr和ObjPtr
这三个函数的具体调用参数说明一下可以吗?
还有,我会加分的,各位兄弟救我一下吧!

#6


VarPtr 取得变量的地址
StrPtr 取得String的地址
ObjPtr 取得对象的地址
均只有一个参数,返回Long

#7


我在尽量的加分,帮帮忙啊!
为何我只能加到127分???

#8


用纯粹的vb是不行的吧?
就是用c做,好象也只能用在win98里,nt和win2000是不行的,除非你的程序运行在ring0级。

#9


To QQRN:
  告诉你一个不幸的消息,用VB是实现不了你的要求的。
  你必须获得CPU的Ring0权限,才能修改其物理内存或拦截API等。而API中提供的几个函数对物理内存的修改是没有用处的。
  因为你想编写动态修改游戏的程序,VB肯定是不能胜任的,你必须用VC++来实现你想要的功能。最简单的做法是编写一个DLL,将其注入到其它进程中去,或者取得RING0权限后拦截相应的API函数。
  这些都是牵涉到底层的操作。所以VB是帮不上你的忙的!呵呵
  如果你有兴趣用VC++编写,我这里有一些例子!如:怎样取得RING0权限等等

#10


to JamesDT :
能否帮我做个DLL,只要能修改指定程序的指定内存单元就行了!
就算不能修改NT的也无妨!
至于C语言,我现在想学也太急了点了。
先说谢谢了!!!

555555555555,天,为何要如此待我!!!VB居然…………

#11


是同以进程的,还是不同进程的?

#12


QQRN:下面是如何修改进程内存的例子,在NT上测试通过,在95/98上也应该没问题。祝你好运。
Option Explicit
Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
'dwDesiredAccess   存取方式,一般用PROCESS_ALL_ACCESS就可以
'bInheritHandle    这里不用,必须是0
'dwProcessId       进程ID,自己想办法得到它,可用GetWindowThreadProcessId等函数,
'                  或是在VB里用Shell命令执行程序返回的值
'返回              进程Handle

Declare Function ReadProcessMemory Lib "Kernel32.dll" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesRead As Long) As Long
Declare Function WriteProcessMemory Lib "Kernel32.dll" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Any) As Long
'hProcess          进程Handle
'lpBaseAddress     指定的地址
'lpBuffer          读/写的缓冲区
'nSize             lpBuffer的大小(字节数)
'lpNumberOfBytesWritten 完成读写的字节数
'返回              非0 成功,0 失败

Type MEMORY_BASIC_INFORMATION
    BaseAddress As Long
    AllocationBase As Long
    AllocattionProtect As Long
    RegionSize As Long
    State As Long
    Protect As Long
    Type As Long
End Type
Declare Function VirtualQueryEx Lib "Kernel32.dll" (ByVal hProcess As Long, ByVal lpAddress As Long, info As MEMORY_BASIC_INFORMATION, ByVal dwLength As Long) As Long
Declare Function CloseHandle Lib "Kernel32.dll" (ByVal handle As Long) As Long


Public Const PROCESS_TERMINATE = &H1&
Public Const PROCESS_CREATE_THREAD = &H2&
Public Const PROCESS_SET_SESSIONID = &H4&
Public Const PROCESS_VM_OPERATION = &H8&
Public Const PROCESS_VM_READ = &H10&
Public Const PROCESS_VM_WRITE = &H20&
Public Const PROCESS_DUP_HANDLE = &H40&
Public Const PROCESS_CREATE_PROCESS = &H80&
Public Const PROCESS_SET_QUOTA = &H100&
Public Const PROCESS_SET_INFORMATION = &H200&
Public Const PROCESS_QUERY_INFORMATION = &H400&
Public Const PROCESS_ALL_ACCESS = &H1F0FFF

Public Const PAGE_NOACCESS = &H1
Public Const PAGE_READONLY = &H2
Public Const PAGE_READWRITE = &H4
Public Const PAGE_WRITECOPY = &H8
Public Const PAGE_EXECUTE = &H10
Public Const PAGE_EXECUTE_READ = &H20
Public Const PAGE_EXECUTE_READWRITE = &H40
Public Const PAGE_EXECUTE_WRITECOPY = &H80
Public Const PAGE_GUARD = &H100
Public Const PAGE_NOCACHE = &H200
Public Const PAGE_WRITECOMBINE = &H400
Public Const MEM_COMMIT = &H1000
Public Const MEM_RESERVE = &H2000
Public Const MEM_DECOMMIT = &H4000
Public Const MEM_RELEASE = &H8000
Public Const MEM_FREE = &H10000
Public Const MEM_PRIVATE = &H20000
Public Const MEM_MAPPED = &H40000
Public Const MEM_RESET = &H80000
Public Const MEM_TOP_DOWN = &H100000
Public Const MEM_4MB_PAGES = &H80000000
Public Const SEC_FILE = &H800000
Public Const SEC_IMAGE = &H1000000
Public Const SEC_VLM = &H2000000
Public Const SEC_RESERVE = &H4000000
Public Const SEC_COMMIT = &H8000000
Public Const SEC_NOCACHE = &H10000000
Public Const MEM_IMAGE = SEC_IMAGE

'Sample
Private FirstRWAddress As Long
Const BLOCKSIZE = 4096&
Sub test()
    Dim hProcess As Long
    Dim ProcessId As Long
    Dim r As Long
    Dim temp As Long
    ProcessId = Shell("NotePad.exe")
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, ProcessId)
    If hProcess = 0 Then
        MsgBox "OpenProcess Fail."
        Exit Sub
    End If
    ListValidMemory hProcess
    Dim b(0 To BLOCKSIZE - 1) As Byte
    r = ReadProcessMemory(hProcess, FirstRWAddress, b(0), BLOCKSIZE, temp)
    If r = 0 Then
        MsgBox "ReadProcessMemory Fail."
        CloseHandle hProcess
        Exit Sub
    End If
    
    r = WriteProcessMemory(hProcess, FirstRWAddress, b(0), BLOCKSIZE, temp)
    If r = 0 Then
        MsgBox "WriteProcessMemory Fail."
    End If
    CloseHandle hProcess
End Sub

'一个进程的独立运行空间是4Gb,在搜索某个数据时,从头到尾读一次就不是好方法。
'进程的运行空间简单可分为只读、可读写和禁用的三种类型,
'要得到这些地址,就要用VirtualQueryEx的方法
'下面的程序可以列出进程的只读和可读写的地址空间
Sub ListValidMemory(ByVal hProcess As Long)
    Dim base As Long
    base = 0
    Dim r As Long
    Dim info As MEMORY_BASIC_INFORMATION
    
    While base >= 0
        If VirtualQueryEx(hProcess, base, info, Len(info)) = 0 Then
            Exit Sub
        End If
        If info.Type <> 0 Then
            If info.Protect = PAGE_READWRITE Then
                Debug.Print Hex(base), info.RegionSize, "Page ReadWrite"
                If FirstRWAddress = 0 Then
                    FirstRWAddress = base
                End If
            ElseIf info.Protect = PAGE_READONLY Then
                Debug.Print Hex(base), info.RegionSize, "Page ReadOnly"
            ElseIf info.Protect = PAGE_EXECUTE_READ Then
                Debug.Print Hex(base), info.RegionSize, "Page Execute Read"
            ElseIf info.Protect = PAGE_EXECUTE_READWRITE Then
                Debug.Print Hex(base), info.RegionSize, "Page Execute ReadWrite"
            End If
            '如果是想搜索游戏数据,一般只需要在PAGE_READWRITE类型的地址空间里搜索就行了。
        End If
        base = base + info.RegionSize
    Wend
End Sub


#13


To:taolei

对不起了,这几天忙着编程,没来得及给你加分,抱歉。


#14


前天,我带着刚编好的游戏修改器来到学校,手上的磁盘就被人抢走了,正高兴的时候,他们又跑回来了。

“QQ啊!你弄的游戏修改器怎么用不了啊!是不是在玩我啊!”
“QQ,你的那个东西害得我的机子死了,是怎么回事啊!”
“QQ,你这家伙居然敢骗我!欠揍啊!”

“我……我没有啊!……我明明在WIN2000上改过啊!!!”小弟我惊恐万分。

“么事?你要我的“无罢漏”中“瘟两千”!!!”
“什么啊!谁象你那么白痴在WIN2000里玩游戏!!”
“天啊!你不会是又叫我重装系统吧,上周你刚把我的机子重装了3次系统。”

半个小时后,我在一片愤怒的叫声之中逃了出来。后面还跟着几句让我心惊肉跳的话:
“死QQ!下次不带来别想进教室!”
“你听好了QQ,作不好我记你十次旷课!还有你以前的记录一起加上!!!”

我带着一对黑眼圈,衣衫褴褛的刚上公车,就被司机一脚踢下:“乞丐还想上我的车!”
“………………虽说我穷,但是一圆八毛七分钱我还是有的!!!…………别急着开车啊……等等我啊!!!”
终于,我拖着一瘸一瘸的腿进了家门,想起刚才被门卫盘问了近一个小时,不禁气血翻腾,连忙自我安慰:“这样的门卫才能确保安全”尽量不想昨天刚被盗的新车。
经过一天一夜的努力……
终于,在RESET了N次,重装WIN98 N/100次,FDISK N/10000次之后,得出一个结论!
亲爱的taolei给的方法只能在WIN2000里用。我倒!
不过的确能改。所以分数照给!
我要重新发个帖子,希望大家来看看啊!就只多加了几个字——“WIN98”
还有,亲爱的taolei,请到来拿分
http://www.csdn.net/expert/TopicView.asp?id=47566