Click here to Skip to main content
15,896,527 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Hi, im new here and i hope someone help me about my problem.
I use VB.net 2008 to make Memory Scanner.

I try some of their answers but still the memory scanner is slow. maybe i have an improvement because before i scan a simple minesweeper and it takes 10 to 20 minutes.
But now i can scan it for 2 to 10 seconds.

But im still now satisfied because when i try it in other games it takes 5 to 10 minutes or sometimes freeze due of too much long and too much usage of CPU. Please Help me :(

Here is my Code

Assume i declare all the API and Some Arguments for making a first scan
this code is a sample of scanning a 4 Bytes Address

VB
'' 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

'' Thread 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

'' The Sub FirstScan Executed by Sub scanF() that is being Executed by FirstScanThread in Command button 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


NOTE: formatHex is only a Function that will put trailing Zeros in the front of Hex String if the Hex is not have Length of 8.

This code works in minesweeper in Windows XP 32 Bit and works fast in MINESWEEPER ONLY.
I tried it in Grand Chase and Farm Frenzy.. the scan won't ends because its still slow and even the scan is done, there is no address being found..(Maybe because in just tested it for 4 Bytes :P)

I like to use VirtualProtectEx and VirtualAllocEx to Enable to Scan those PAGE_GUARD and write on it. therefore i am able to obtain the Specific address that i want but i can't do it because , it still slow. i i make the PAGE_GUARD'ed PAGE into EXECUTE_READWRITE it will make more Bytes to Scan. it will make the App more slower.. thats why i am begging for help :(

I need your help.. please :( Make this application Works Fine.


if you have some question, feel free to ask.. Thanks in advance and God bless all of you. :)
Posted
Updated 13-Jun-14 0:26am
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900