如何更快地制作内存扫描仪?

时间:2014-06-13 09:13:24

标签: vb.net

我使用VB.net 2008制作内存扫描程序和黑客程序。我尝试了一些他们的答案,但内存扫描仪仍然很慢。也许我有一个改进,因为在我扫描一个简单的扫雷之前,需要10到20分钟。但现在我可以扫描它2到10秒。

但是我还是不满意,因为当我在其他游戏中尝试它时需要5到10分钟,或者有时因为太长时间和过多的CPU使用而冻结。

这是我的代码

假设我声明了所有API和一些用于进行第一次扫描的参数 此代码是扫描4字节地址的示例:

'' Command Button Event

btn_firstScan(....) Handle....
'' The Code
      Me.Enabled = False
        FirstScanThread = New Thread(AddressOf scanF)
        FirstScanThread.IsBackground = True
        FirstScanThread.Priority = ThreadPriority.Highest
        FirstScanThread.Start() '' Thread Started for the First Scan.
End sub


  Private Sub scanF() '' This is the Function is being Executed by the FirstScanThread at the btn_firstScan.
        FirstScan(Of Int32)(pHandle, &H400000, &H7FFF0000, CType(txt_value.Text, Int32))
    End Sub

由SubS扫描执行的Sub FirstScan,由CommandS按钮中的FirstScanThread执行btn_firstScan sub

Friend Sub FirstScan(Of T)(ByVal pHandle As IntPtr, ByVal minAddress As Int64, ByVal maxAddress As Int64, _
                                  ByVal VALUE As T, Optional ByVal tempFileName As String = "temp.txt")

        Dim thr As New Thread(AddressOf getProcessMemoryInfo) '' Get the Process Memory Info First
        Dim memRange As New scanRange
        memRange.minimum_address = minAddress
        memRange.maximum_address = maxAddress
        thr.IsBackground = True
        thr.Priority = ThreadPriority.Highest
        thr.Start(memRange)
        thr.Join()


        thr = New Thread(AddressOf dumpReadProcessMemory) '' Read All Bytes and Dump to the Temporary File
        thr.IsBackground = True
        thr.Priority = ThreadPriority.Highest
        thr.Start()
        thr.Join()

        thr = New Thread(AddressOf readTempFile) '' Scan the Dump File in a Specific Set of Bytes [4 Bytes Aligned]
        thr.IsBackground = True
        thr.Priority = ThreadPriority.Highest
        thr.Start(VALUE)
        thr.Join() 

        setControlState(Me, True) '' If the Scan is Complete , The form is Ready Again to Receive Input
    End Sub


Friend Sub dumpReadProcessMemory() '' This Sub is Use to Dump the All Bytes  Read by ReadProcessMemory 
        Dim INFO As FileStream = New FileStream("FIRST.INFO.txt", FileMode.Open, FileAccess.Read, FileShare.Read)
        Dim SR As StreamReader = New StreamReader(INFO) '' This is use to Obtain the Info that is needed to switch Page by Page Faster , No need to obtain in VirtualQueryEx
        Dim BFILE As FileStream = New FileStream("FIRST.SCAN.txt", FileMode.Create, FileAccess.Write, FileShare.Write)
        Dim BW As BinaryWriter = New BinaryWriter(BFILE) '' This is the Binary Writer for writing the READ Bytes
        Dim BUFFER(0 To (1048576 * 128)) As Byte
        Dim mem As New memoryInfo

        While Not SR.EndOfStream '' While there is Page Found
            mem.regionBaseAddress = CLng(SR.ReadLine.ToString)
            mem.regionSize = CLng(SR.ReadLine.ToString)
            ReadProcessMemory(pHandle, mem.regionBaseAddress, BUFFER, mem.regionSize, 0)
            BW.Write(BUFFER, 0, mem.regionSize)
            Thread.Sleep(1)
        End While

        SR.Close()
        SR.Dispose()
        INFO.Close()
        INFO.Dispose()
        BW.Close()
        BFILE.Close()
        BFILE.Dispose()
        GC.Collect() '' Collect Garbage of BUFFER prevent CPU Stressing and RAM Leak, and i think i helps :P

End Sub

 Friend Sub getProcessMemoryInfo(ByVal Obj As Object) '' Use to Get What PAGE is Readable/Writable and its Size

        Dim FILE As System.IO.FileStream = New System.IO.FileStream("FIRST.INFO.txt", IO.FileMode.Create, FileAccess.Write, IO.FileShare.Write)
        Dim SW As System.IO.StreamWriter = New System.IO.StreamWriter(FILE)
        Dim BASE_ADDRESS As Int64 = CLng(Obj.minimum_address.ToString)
        Dim MAX As Int64 = CLng(Obj.maximum_address.ToString)
        Dim PAGE_COUNT As Integer = 0

        While VirtualQueryEx(pHandle, BASE_ADDRESS, MBI, MBIsize)
            If MBI.State = MemoryAllocationState.Commit Then
                If MBI.zType = MemoryAllocationType.MEM_PRIVATE Or MBI.zType = MemoryAllocationType.MEM_IMAGE Then
                    Select Case MBI.AllocationProtect
                        '' Check if The Region is Readable/Writable and Executable
                        Case MemoryAllocationProtectionType.PAGE_CANWRITE
                            GoTo WRITE_INFO
                        Case MemoryAllocationProtectionType.PAGE_EXECUTE_READWRITE
                            GoTo WRITE_INFO
                        Case MemoryAllocationProtectionType.PAGE_WRITECOMBINE
                            GoTo WRITE_INFO
                        Case MemoryAllocationProtectionType.PAGE_EXECUTE_WRITECOPY
                            GoTo WRITE_INFO
                        Case MemoryAllocationProtectionType.PAGE_READWRITE
                            GoTo WRITE_INFO
                        Case Else
                            GoTo BYPASS_WRITE
                    End Select

WRITE_INFO:
                    SW.WriteLine(BASE_ADDRESS)
                    SW.WriteLine(MBI.RegionSize.ToInt32)
                    Thread.Sleep(1)
                    'PAGE_COUNT += 1
                End If
            End If


BYPASS_WRITE:
            BASE_ADDRESS = BASE_ADDRESS + MBI.RegionSize.ToInt32
            updateProgressTo(Me.pb_scanProgress, CInt(BASE_ADDRESS / MAX * 100))

        End While

        SW.Close()
        SW.Dispose()
        FILE.Close()
        FILE.Close()

        'Console.WriteLine(PAGE_COUNT)
    End Sub

Public Sub readTempFile(ByVal Value As Object)

        Dim TEMP As System.IO.FileStream = New System.IO.FileStream("TEMP.txt", IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.Write)
        Dim TFILE As System.IO.FileStream = New System.IO.FileStream("FIRST.INFO.txt", IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
        Dim BFILE As System.IO.FileStream = New System.IO.FileStream("FIRST.SCAN.txt", IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
        Dim SW As System.IO.StreamWriter = New System.IO.StreamWriter(TEMP) '' Will Contain a list of Addressed found with the Value input.
        Dim SR As System.IO.StreamReader = New System.IO.StreamReader(TFILE) '' Contains the Region baseAddesses and Size
        Dim BR As System.IO.BinaryReader = New System.IO.BinaryReader(BFILE) '' Contains the Bytes being Dump Before and will now Read for Scanning.
        Dim ADDRESS_POINTER As Int64 = 0
        Dim mem As New memoryInfo
        Dim TEMP_BYTE(0 To 4 - 1) As Byte
        Dim BUFFER(0 To (1024 * 1024)) As Byte = 1024KB 
        Dim BUFFER_INDEX = 0

        mem.regionBaseAddress = CLng(SR.ReadLine.ToString) ''Obtain the Staring Base Address
        mem.regionSize = CLng(SR.ReadLine.ToString) '' Obtain the Region Size
        ADDRESS_POINTER = mem.regionBaseAddress

        While BR.Read(BUFFER, 0, BUFFER.Length) '' Fill the BUFFER with Data
            BUFFER_INDEX = 0
            While BUFFER_INDEX < BUFFER.Length - (4 - 1)
                For a As Integer = 0 To (4 - 1) '' Compile the Read Bytes
                    TEMP_BYTE(a) = BUFFER(BUFFER_INDEX + a)
                Next
                If BitConverter.ToInt32(TEMP_BYTE, 0) = Value Then '' If the Compiled 4 Bytes = Value then
                    SW.WriteLine(formatHex(Hex(ADDRESS_POINTER).ToString))
                    'addItemTo(Me.lb_addressList, formatHex(Hex(ADDRESS_POINTER).ToString))
                End If
                ADDRESS_POINTER += 4
                BUFFER_INDEX += 1
                mem.regionSize -= 4
                If mem.regionSize <= 0 Then
                    If SR.EndOfStream Then
                        Exit While
                    Else
                        ''Switch to the Next Region
                        mem.regionBaseAddress = CLng(SR.ReadLine.ToString) ''Obtain the Staring Base Address
                        mem.regionSize = CLng(SR.ReadLine.ToString) '' Obtain the Region Size
                        ADDRESS_POINTER = mem.regionBaseAddress
                    End If
                End If
            End While
            Thread.Sleep(1) '' Prevent 100% CPU Usage therefore the Form and other App avoid Crashing and Not Responding,
        End While




        BR.Close()
        BFILE.Close()
        SW.Close()
        TEMP.Close()
        SW.Dispose()
        TEMP.Dispose()
        SR.Close()
        SR.Dispose()
        TFILE.Dispose()
        GC.Collect()
        setControlState(Me, True) '' Make the Form Enabled

    End Sub

注意:如果Hex的长度不是8,则formatHex只是一个将尾随零置于十六进制字符串前面的函数。

此代码适用于Windows XP 32位中的扫雷,仅适用于MINESWEEPER。我在Grand Chase和Farm Frenzy尝试过;扫描不会结束,因为它仍然很慢,甚至扫描完成,没有找到地址(可能因为刚刚测试了4个字节)。

我喜欢使用VirtualProtectEx和VirtualAllocEx来扫描那些PAGE_GUARD并在其上书写。因此,我能够获得我想要的具体地址,但我无法做到,因为它仍然很慢。我将PAGE_GUARD&PAGE页面设置为EXECUTE_READWRITE,它将扫描更多的字节。它会使应用程序变慢。

0 个答案:

没有答案