要操作内存还是看看API中关于MEMORY的函数吧

解决方案 »

  1.   

    下面是如何修改进程内存的例子,在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命令执行程序返回的值
    `返回              进程HandleDeclare 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 = &H1F0FFFPublic 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
    www.applevb.com