如何快速搜索内存数据

解决方案 »

  1.   

    哎2秒内,估计能搜索几百兆内存吧我用类似以下的方法在VB 2005下写的一个通用修改器速度就不错。
    数据复制到缓冲区就是让你用readprocessmemory复制对方内存内容到你程序的byte数组
    dim byte(size) as byte '这就是缓冲区
    用readprocessmemory读一个内存段到缓冲区
    dim scannum(3) as byte '这里存储你要搜索的数据,在数据输入时就初始化它,不同的数据类型需要不同大小的数组,不同的初始化方法,怎么做自己想,这里以搜索Long,Single类型为例(4字节)
    dim i as long  '循环变量,用于遍历缓冲区
    dim j as long  '循环变量,用于遍历要搜索的数据
    dim addressbase as Long '这是用来记录数据符合度的变量
    for i  =0 to size-3
    addressbase=0
    for j  =0 to 3
    if byte(i+j)=scannum(j) then
       addressbase=addressbase+1
    else
       exit for
    end if
    next j
    if addressbase=3 then debug.print i-3 '这里向调试窗口输出搜索到的一个数据基地址
    next i以上就是最基本的方法。希望楼主有问题自己解决。不能保证上面的代码没有问题,不用说徒手了,就是在编辑器里我也写错。
      

  2.   

    自己声明2个数组(byte类型)dim byte(size-1) as byte  '缓冲
    dim scan(3) as byte       ‘要搜索的数据
    readprocessmemory 读内存数据到byte()
    dim i as long,j as long ,c as long
    for i =0 to size-1
       c=0
       for j =0 to 3
          if byte(i+j)=scan(j) then 
             c=c+1
          else
             exit for
          end if
       next
       if c=4 then 
          debug.print "找到一个地址: " & i
          i=i+3
       end if
    next i
    就是以上这个意思。自己慢慢理解。1秒到底能搜索几十兆自己测试。你要搜索一个G用2秒微软的工程师也办不了。
      

  3.   

    啥破玩意。又没发出来自己声明2个数组(byte类型)dim byte(size-1) as byte  '缓冲
    dim scan(3) as byte       ‘要搜索的数据
    readprocessmemory 读内存数据到byte()
    dim i as long,j as long ,c as long
    for i =0 to size-1
       c=0
       for j =0 to 3
          if byte(i+j)=scan(j) then 
             c=c+1
          else
             exit for
          end if
       next
       if c=4 then 
          debug.print "找到一个地址: " & i
          i=i+3
       end if
    next i
    就是以上这个意思。自己慢慢理解。1秒到底能搜索几十兆自己测试。你要搜索一个G用2秒微软的工程师也办不了。
      

  4.   

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    服务器在做嘛?!
    啥破玩意。又没发出来自己声明2个数组(byte类型)dim byte(size-1) as byte  '缓冲
    dim scan(3) as byte       ‘要搜索的数据
    readprocessmemory 读内存数据到byte()
    dim i as long,j as long ,c as long
    for i =0 to size-1
       c=0
       for j =0 to 3
          if byte(i+j)=scan(j) then 
             c=c+1
          else
             exit for
          end if
       next
       if c=4 then 
          debug.print "找到一个地址: " & i
          i=i+3
       end if
    next i
    就是以上这个意思。自己慢慢理解。1秒到底能搜索几十兆自己测试。你要搜索一个G用2秒微软的工程师也办不了。
      

  5.   

    .....整个逻辑内存多大?你见过什么软件能在2秒内能完成整个搜索的...??至少我用过的,金山游侠,FPE等知名内存搜索软件(游戏修改也是内存搜索),貌似都达不到你这要求.扫扫楼..睡觉去.....
      

  6.   

      MemEdit0.2.rar    (需要RX6控件)
       
      侯思松先生写的 一个快速的游戏修改工具的Delphi6源代码
      和金山游侠之类的很接近,速度较快。
    这个就能够2秒内完成!还有勇芳内存数据分析编辑也能够2秒内完成!并且是vb6编写!
    http://www.chnxp.net/soft/sort02/sort044/down-1959.html
      

  7.   

    不过那个Delphi6源代码我看不懂,汗
      

  8.   

    他们的代码应该只是搜索了进程的可写部分的内存,用virtualprotectex判断下就快N百倍了。。
      

  9.   

    不仅仅只是搜索了进程的可写部分的内存,那个Delphi6源代码还有过滤某些文件类型的代码,不知道如何搞的。
    如果只是搜索了进程的可写部分的内存,还是比较慢,我试过
      

  10.   

    如果只是搜索了进程的可写部分的内存,还是比较慢,我试过//真的吗?请试试gcyun高人写的模块.....Private Type MEMORY_BASIC_INFORMATION
        BaseAddress As Long
        AllocationBase As Long
        AllocationProtect As Long
        RegionSize As Long
        State As Long
        Protect As Long
        lType As Long
    End TypePrivate Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Declare Sub api_CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten 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 GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
    Private Declare Function VirtualProtectEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
    Private Declare Function VirtualQueryEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, lpBuffer As MEMORY_BASIC_INFORMATION, ByVal dwLength As Long) As Long
    Private Declare Function CreateRemoteThread Lib "kernel32" (ByVal hProcess As Long, ByVal lpThreadAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, ByVal lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
    Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As LongPrivate Const PROCESS_ALL_ACCESS = &H1F0FFF
    Private Const PAGE_READWRITE = &H4Private Const MEM_COMMIT = &H1000Private Const ERR_MEMRW = 40010Private c_MemStop As Boolean
    Private c_PID As LongPrivate Function Mem_SearchBytArray(bytData() As Byte, ListAddress() As Long, _
                                        Optional lpStart As Long = &H400000, _
                                        Optional lpEnd As Long = &H7FFFFFFF) As Long
                                        '16bit  from &H80000000 to &HBFFFFFFF   2byte
                                        '32bit  from &H00400000 to &H7FFFFFFF   4byte
                                        'all    from &H00000000 to &HFFFFFFFF
        Dim nCount As Long    Dim bfSize As Long
        Dim mbSize As Long
        
        Dim mbloop As Long
        Dim bfloop As Long    Dim ret As Long
        Dim lpAddress As Long
        Dim hProcess As Long
        Dim MBI As MEMORY_BASIC_INFORMATION
        Dim lpBuffer() As Byte
        
        c_MemStop = False
        mbSize = Len(MBI)
        bfSize = UBound(bytData)
        lpAddress = lpStart
        
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, c_PID)    ret = VirtualQueryEx(hProcess, lpAddress, MBI, mbSize)
        Do While (ret And (lpAddress < lpEnd) And Not c_MemStop)
            If (MBI.Protect And PAGE_READWRITE) And (MBI.State = MEM_COMMIT) Then
                ReDim lpBuffer(MBI.RegionSize - 1)
                ReadProcessMemory hProcess, ByVal MBI.BaseAddress, lpBuffer(0), MBI.RegionSize, 0&
                For mbloop = 0 To MBI.RegionSize - 1 - bfSize
                    For bfloop = 0 To bfSize
                        If bytData(bfloop) <> lpBuffer(mbloop + bfloop) Then GoTo runSearchNext
                    Next
                    ReDim Preserve ListAddress(nCount) As Long
                    ListAddress(nCount) = mbloop + MBI.BaseAddress
                    nCount = nCount + 1
    runSearchNext:
                Next
            End If
            lpAddress = lpAddress + MBI.RegionSize
            ret = VirtualQueryEx(hProcess, lpAddress, MBI, mbSize)
        Loop    Mem_SearchBytArray = nCount
        Call CloseHandle(hProcess)
    End Function我的老爷机(赛扬1G+256SDRAM)上搜索Explorer.exe进程,单字节,数值12,结果共25253项数据只用了1.15秒!!!
      

  11.   

    我就是用的这个模块,但是我是查找连续的字节数组,像这样的:C0 DC 0C 00 C0 DC 0C 00 48 ,很慢
      

  12.   

    Public Function SearchMem(hProcess As Long, strSearch As String, Optional spos As Long = &H400000) As Long
        Dim i As Long, j As Long, count As Long, nLength As Long
        Dim r As Long, mbi As MEMORY_BASIC_INFORMATION
        Dim lpAddress As Long, ubs As Long, RSize As Long, lMax As Long
        Dim bSearch() As Byte
        Dim sp() As String
        Dim lpBuffer() As Byte
        Dim si As SYSTEM_INFO
        
        GetSystemInfo si
        lMax = si.lpMaximumApplicationAddress
        '将我们的搜索的内容转换成为一个Byte数组
        '搜索支持数据串,每个数据用空格分开
        sp = Split(strSearch, " ")
        nLength = UBound(sp)
        ReDim bSearch(nLength)
        For i = 0 To nLength
            bSearch(i) = Val("&H" & sp(i)) And &HFF '防止溢出错误
        Next
        
        SearchMem = 0
        lpAddress = spos     '以 10000 作为起点
        ubs = UBound(bSearch)
        bSearching = True
        r = VirtualQueryEx(hProcess, lpAddress, mbi, Len(mbi))    '将7F000000作为搜索结束地址
        Do While (r And (lpAddress < lMax) And bSearching)
            DoEvents
            '只搜索可读取的已提交的内存区域
            If (mbi.Protect And PAGE_READWRITE) And (mbi.State = MEM_COMMIT) Then
                RSize = mbi.RegionSize
                ReDim lpBuffer(RSize - 1)            ReadProcessMemory hProcess, mbi.BaseAddress, lpBuffer(0), RSize, 0
                
                count = RSize - 1 - ubs
                For i = 0 To count '防止越界
                    DoEvents
                    '逐个字节比较,如果有任何一个不相等,则不再比较其它
                    For j = 0 To ubs
                        DoEvents
                        If bSearch(j) <> lpBuffer(i + j) Then GoTo 10
                    Next
                    '全部相等,返回地址
                    bSearching = False
    '                Debug.Print Hex(i + lpAddress)
                    SearchMem = i + lpAddress
                    Exit Function
    10:
                Next
            End If
            lpAddress = lpAddress + RSize
            r = VirtualQueryEx(hProcess, lpAddress, mbi, Len(mbi))
        Loop    bSearching = False
        SearchMem = 0
    End Function
      

  13.   

    我这段时间正好涉及到内存搜索问题,有几点感受说明一下:
    一、要考虑语言的因素(如VB指针功能太弱,执行效率较低),建议采取C++或MASM32写比较代码。
    二、要考虑内存对齐情况,将被查找子串转换为4的倍数的数据(32位机),速度会大幅提升。
    三、如果不考虑移植性,可采用MMX、SSE或SSE2指令进行优化,但AMD的CPU不支持。
    四、尽量避免使用二次循环语句,速度将呈几级数增加。
    在循环体内外判断子串长度,若为1则无需优化,为2-3使用short,4-7使用long,8以上使用double。比如要查找的子串为"Hello",那么可以首先将"Hello"截为一个4位的子串"Hell",然后转换为一个LONG。再以LONG的类型循环访问目标内存数据,比较二者是否相等,若相等,则为"Hell",然后后再进一步比较是否为"Hello"。
      

  14.   

    楼主可以参考winhex 的内存搜索,速度很理想。vb做这个的确不太适合,但也不是不能做要解决几个问题
    1.提升权限到se_debug使程序能够读写其他程序的内存空间
    2.修改物理内存对象的权限,使其可以写入
    3.在搜索目标进程的时候最好将其挂起,可以提高效率
    4.字节对齐和比较的问题,可以通过调用系统的或者crt的api来实现
      

  15.   


    一、我目前只会VB。 
    二、如何内存对齐? 
    三、需要考虑移植性。 
    四、尽量避免使用二次循环语句,速度将呈几级数增加。 如果要查找的子串为"Hell",但是内存中为"asHellok",这时候4位4位的比较,怎么比?不是会遗漏吗?
      

  16.   

    再说明一点,不知楼主是要搜索本地内存呢?还是要搜索所有进程的内存?
    如果是后者,需要考虑VB字符与C++字符串的区别.
    如果没有特别的事,我下午给你完整的VB示例代码.
      

  17.   

    是搜索别的进程的内存。
    用NtSuspendProcess挂起进程再查找不可以,这个方法没有用。
      

  18.   

    呵呵。。
    看来这个东西人们还是这么有兴趣。当然了,“这个东西”是指别人程序的内存,不是20分。
    有兴趣的去我的下载区里面下载一下最后发布的那个版本的游戏修改器,VB.NET写的,反编译一下就可以了,之所以.NET写的那些程序都没有公布代码,就是因为都没有加密处理,直接反编译看代码就可以了。英雄无敌的修改器就不用反编译了,代码在我的博上放着呢。其实很简单的东西。个人觉得没有讨论的价值了,那个.NET修改器的搜索速度你们可以自己试试,用个大点的游戏,别弄一些什么explorer,那才占几毛钱地方。
      

  19.   

    'VB字符串查找示例程序
    '作者:lyserverOption Base 1
    Option ExplicitPrivate Declare Function GetCurrentProcessId Lib "kernel32" () As Long
    Private Const PAGE_READWRITE = &H4
    Private Const MEM_COMMIT = &H1000
    Private Type MEMORY_BASIC_INFORMATION
        BaseAddress As Long
        AllocationBase As Long
        AllocationProtect As Long
        RegionSize As Long
        State As Long
        Protect As Long
        lType As Long
    End Type
    Private Declare Function VirtualQueryEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, lpBuffer As MEMORY_BASIC_INFORMATION, ByVal dwLength As Long) As Long
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    Private Declare Function DebugActiveProcess Lib "kernel32" (ByVal dwProcessId As Long) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
    Private Const TH32CS_SNAPPROCESS As Long = &H2
    Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal lFlags As Long, ByVal lProcessID As Long) As Long
    Private Const MAX_PATH As Integer = 260
    Private Type PROCESSENTRY32
        dwSize As Long
        cntusage As Long
        th32ProcessID As Long           ' this process
        th32DefaultHeapID As Long
        th32ModuleID As Long            ' associated exe
        cntThreads As Long
        th32ParentProcessID As Long     ' this process's parent process
        pcPriClassBase As Long          ' Base priority of process's threads
        dwFlags As Long
        szExeFile As String * MAX_PATH  ' Path
    End Type
    Private Declare Function Process32First Lib "kernel32" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
    Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject 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 Const PROCESS_VM_READ As Long = &H10                    '允许读目标进程
    Private Const PROCESS_QUERY_INFORMATION As Long = &H400         '允许查询内存状态
    Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFFF            '允许完全控制目标进程
    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 EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, lphModule As Any, ByVal cb As Long, lpcbNeeded As Long) As Boolean
    Private Declare Function GetModuleFileNameEx Lib "psapi" Alias "GetModuleFileNameExA" (ByVal hProcess As Long, ByVal hModule As Long, ByVal lpFilename As String, ByVal nSize As Long) As LongSub Main()
        Dim s As String
        Dim b() As Byte
        Dim nLen As Long
        
        s = "1234567890"
        nLen = Len(s) * 2
        ReDim b(nLen) As Byte
        CopyMemory b(1), ByVal StrPtr(s), nLen
        
        Call Search(b, GetCurrentProcessId())
    End Sub
    Public Sub Search(byteData() As Byte, Optional p_ID As Long = 0, Optional szWindowText As String = "", Optional ByVal lpStart As Long = &H100000, Optional lpEnd As Long = &H7FFFFFFF)
        Dim hWnd As Long                                                '窗口句柄
        Dim hProcessID As Long                                          '进程ID
        Dim hProcessSnapShot As Long                                    '进程快照句柄
        Dim szModuleName As String                                      '进程模块名称
        Dim bSuccessHup As Boolean                                      '进程挂起标志
        Dim bFoundProcess As Boolean                                    '进程查找标志
        Dim stProcess As PROCESSENTRY32                                 '进程信息结构    '判断进程句柄是否存在,如果不存在,则查找进程
        If p_ID > 0 Then                                            '如果直接指定了要查找的目标进程的ID
            hProcessID = p_ID
        Else
            If Len(szWindowText) > 0 Then                           '如果指定了窗口名称
                hWnd = FindWindow(vbNullString, szWindowText)
                If hWnd = 0 Then Exit Sub
                GetWindowThreadProcessId hWnd, hProcessID
            End If
        End If
        If hProcessID > 0 Then                                      '查找特定的进程
            Call fnSearch(byteData, hProcessID, lpStart, lpEnd)
        Else                                                        '查找所有进程
            stProcess.dwSize = Len(stProcess)
            hProcessSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)
            bFoundProcess = Process32First(hProcessSnapShot, stProcess)
            Do While bFoundProcess
                hProcessID = stProcess.th32ProcessID
                szModuleName = Left(stProcess.szExeFile, InStr(stProcess.szExeFile, vbNullChar) - 1)
                Call fnSearch(byteData, hProcessID, lpStart, lpEnd)
                bFoundProcess = Process32Next(hProcessSnapShot, stProcess)
            Loop
            CloseHandle hProcessSnapShot
        End If
    End SubPrivate Function fnSearch(byteData() As Byte, ByVal p_ID As Long, ByVal lpStart As Long, ByVal lpEnd As Long)
        Dim hProcess As Long                                            '进程句柄
        Dim lpBaseAddress As Long
        Dim bSuccess As Boolean
        Dim MBI As MEMORY_BASIC_INFORMATION
        Dim lRet As Long                                                '用于接收API返回值
        Dim mbiSize As Long, bSize As Long, dwNeeded As Long
        Dim lpMBI As Long, lpByte As Long
        Dim lpBuffer() As Byte                                          '内存缓冲区指针
        Dim lpszFileName As String                                      '进程模块名称数组
        
        lpBaseAddress = lpStart
        mbiSize = Len(MBI)
        bSize = UBound(byteData)
        
        hProcess = OpenProcess(PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION, False, p_ID)
        If hProcess = 0 Then Exit Function
        
        lpszFileName = String(MAX_PATH, vbNullChar)                     '取完整的进程模块名称
        If GetModuleFileNameEx(hProcess, ByVal 0&, lpszFileName, MAX_PATH) Then
            lpszFileName = Left(lpszFileName, InStr(lpszFileName, vbNullChar) - 1)
        End If
        lRet = VirtualQueryEx(hProcess, lpBaseAddress, MBI, mbiSize)
        
        Do While ((lRet > 0) And (lpBaseAddress < lpEnd))
            If (MBI.Protect And PAGE_READWRITE) And (MBI.State = MEM_COMMIT) Then
                ReDim lpBuffer(MBI.RegionSize)
                ReadProcessMemory hProcess, ByVal MBI.BaseAddress, lpBuffer(1), MBI.RegionSize, 0&
                For lpMBI = 1 To MBI.RegionSize - bSize
                    For lpByte = 1 To bSize
                        bSuccess = (lpBuffer(lpMBI + lpByte) = byteData(lpByte))
                        If Not bSuccess Then Exit For
                    Next
                    If bSuccess Then    '找到目标内容
                        Debug.Print "找到目标内容,进程文件:", lpszFileName, "地址:", MBI.BaseAddress + lpMBI
                    End If
                Next
            End If
            lpBaseAddress = lpBaseAddress + MBI.RegionSize
            lRet = VirtualQueryEx(hProcess, lpBaseAddress, MBI, mbiSize)
            DoEvents
        Loop
        CloseHandle hProcess
    End Function由于时间因素,加上VB指针功能弱,并未做前面说的优化,只再补充一点:
    如果查找的进程不是用VB写的,字符串的存储方式是不一样的,楼主可以进一步添加模块枚举,判断是否包含MSVBVM60.DLL,如果包含,可如示例进行转换.
      

  20.   

    此外还可使用进程调试API,但我没试过.
      

  21.   

    请楼主用以下函数替换前面同名的函数,由于下面函数考虑了内存对齐,速度提高大约4倍.
    Private Function fnSearch(byteData() As Byte, ByVal p_ID As Long, ByVal lpStart As Long, ByVal lpEnd As Long)
        Dim hProcess As Long                                            '进程句柄
        Dim lpBaseAddress As Long
        Dim bSuccess As Boolean
        Dim MBI As MEMORY_BASIC_INFORMATION
        Dim lRet As Long                                                '用于接收API返回值
        Dim mbiSize As Long, bSize As Long, dwNeeded As Long
        Dim lpMBI As Long, lpByte As Long
        Dim lpMemBuffer() As Long                                       '内存缓冲区指针
        Dim lpDataBuffer() As Long                                      '要查找的字符串缓冲区指针
        Dim lpszFileName As String                                      '进程模块名称数组
        
        lpBaseAddress = lpStart
        mbiSize = Len(MBI)
        bSize = UBound(byteData)
        bSize = (bSize \ 4) + IIf((bSize Mod 4) <> 0, 1, 0)
        ReDim lpDataBuffer(bSize)
        CopyMemory lpDataBuffer(1), byteData(1), UBound(byteData)
        
        hProcess = OpenProcess(PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION, False, p_ID)
        If hProcess = 0 Then Exit Function
        
        lpszFileName = String(MAX_PATH, vbNullChar)                     '取完整的进程模块名称
        If GetModuleFileNameEx(hProcess, ByVal 0&, lpszFileName, MAX_PATH) Then
            lpszFileName = Left(lpszFileName, InStr(lpszFileName, vbNullChar) - 1)
        End If
        lRet = VirtualQueryEx(hProcess, lpBaseAddress, MBI, mbiSize)
        
        Do While ((lRet > 0) And (lpBaseAddress < lpEnd))
            If (MBI.Protect And PAGE_READWRITE) And (MBI.State = MEM_COMMIT) Then
                ReDim lpMemBuffer(MBI.RegionSize)
                ReadProcessMemory hProcess, ByVal MBI.BaseAddress, lpMemBuffer(1), MBI.RegionSize, 0&
                For lpMBI = 1 To (MBI.RegionSize \ 4 - bSize)
                    For lpByte = 1 To bSize
                        bSuccess = (lpMemBuffer(lpMBI + lpByte) = lpDataBuffer(lpByte))
                        If Not bSuccess Then Exit For
                    Next
                    If bSuccess Then    '找到目标内容
                        Debug.Print "找到目标内容,进程文件:", lpszFileName, "地址:", MBI.BaseAddress + lpMBI * 4
                    End If
                Next
            End If
            lpBaseAddress = lpBaseAddress + MBI.RegionSize
            lRet = VirtualQueryEx(hProcess, lpBaseAddress, MBI, mbiSize)
            DoEvents
        Loop
        CloseHandle hProcess
    End Function
      

  22.   

    优化总结:
    一、考虑内存对齐。其实仅此因素,速度就会提高大约16倍(而不是我前面说的4倍),即使是查找单个字符也如此,除了你的查找子串没有定义好而可能导致失败,比如某个进程有字符串“如何快速搜索内存数据”,而查找子串被定义为以“何”、“速”、“索”等未对齐的字开头会导致失败,此时可偏移2节字后做二次扫描,整个速度仍然而逐个字节比较快8倍。
    二、缓存输出结果。在显示结果时使用你代码中的缓存,然后一次性显示,速度又将提高数十倍(因为debug.print为图形操作,非常费时)。
    三、排除系统核心进程。在进行全机进程范围内搜索时,应排除系统核心进程,如将
                    Call fnSearch(byteData, hProcessID, lpStart, lpEnd)
    加上一个判断            '排除系统进程
                If InStr(szModuleName, "[System Idle Process] wscntfy.exe svchost.exe winlogon.exe CSRSS.EXE SMSS.exe alg.exe ctfmon.exe rundll32.exe dllhost.exe Explorer.EXE spoolsv.exe services.exe msdtc.exe taskmgr.exe") = 0 Then
                    Call fnSearch(byteData, hProcessID, lpStart, lpEnd)
                End If
    速度又将提高N倍。
    四、编译程序。也许楼主觉得这点是废话,其实不然,由于在IDE环境中程序被加入了调试信息,速度自然慢,编译后运和,提高的不此一个数量级。优化后的实验结果:
    我的机器配置为(赛扬1.7、256M内存、2002年组装),运行了VB6、MsDEV、FireFox、PPStream等8个应用程序,进行指定进程扫描时,耗时40毫秒(20次测试的最大值,最快达16毫秒),进行全机进程搜索时,耗时4000毫秒(20次测试的最大值)。楼主的机器应该比我的好,耗时应该只少不多。
    你的分数太少,我不再啰嗦了,昨天下了点小雨,我得到菜地里看一看。
      

  23.   

    非常感谢各位朋友的帮助,参考lyserver 的代码修改内存对齐部分,速度果然大幅度提高.
    我查找12个字节的数据,用时:5.0625秒,已经能够满足我的需要了,再次谢谢大家!大家如有空帮我看看另外1个问题:http://topic.csdn.net/u/20071126/11/fed822c2-8851-4e23-99eb-b31e796dba85.html
      

  24.   

     For lpMBI = 1 To (MBI.RegionSize \ 4 - bSize) 
                    For lpByte = 1 To bSize 
                        bSuccess = (lpMemBuffer(lpMBI + lpByte) = lpDataBuffer(lpByte)) 
                        If Not bSuccess Then Exit For 
                    Next 
                    If bSuccess Then    '找到目标内容 
                        Debug.Print "找到目标内容,进程文件:", lpszFileName, "地址:", MBI.BaseAddress + lpMBI * 4 
                    End If 
                Next 
            End If 
    ============================
    显然4个字节对齐,只是片面的,如果要查找0xFFFFFFFF之类的四个字节都相等的呢?那可不是4个字节一跳,而是1个字节一跳了.
      

  25.   

    例如内存为 FF FF FF FF FF FF 00 0A,如果查找0XFFFFFFFF,应该找到三个地址,如果只是找到第一个以后再跳4个字节,那结果只是找到一个.
      

  26.   

    lyserver
    你这段代码很不错,很快,感谢!