I have a program designed to scan strings from a process. It is designed to output all of the readable strings within the process, at least 4 bytes long. (I am actually scanning Minecraft's java process). For some reason, the default game will SOMETIMES complete its scan, once I let it sit a while. Once you add even the smallest mod, the scan will hang. Is there any way I can fix this?
Here are the methods I am using for the scan.
Private Function FindStrings(input() As Byte, minLength As Integer) As List(Of String)
Dim arr() As String = System.Text.Encoding.Default.GetString(input).Split({Chr(0) & Chr(0) & Chr(0)}, StringSplitOptions.RemoveEmptyEntries)
Dim output As New List(Of String)
Dim tmp As String = ""
Dim tmp1 As String = ""
For Each item As String In arr
tmp = item.Replace(Chr(0), "")
For Each c As Char In tmp.ToCharArray
If isReadable(Asc(c)) = True Then
tmp1 &= c
Else
If tmp1.Length >= minLength Then output.Add(tmp1)
tmp1 = ""
End If
Next
If tmp1.Length >= minLength Then output.Add(tmp1)
tmp1 = ""
Next
Return output
End Function
Private Function isReadable(input As Integer) As Boolean
Dim whitelist() As String = {"196,214,220,223,228,246,252"}
If Array.IndexOf(whitelist, input) > -1 Then Return True
If input < 32 Then Return False
If input > 126 Then Return False
Return True
End Function
Private Sub BGW_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BGW.DoWork
Dim hProcess As IntPtr
Dim lpMem As UInt32, ret As UInt32, lLenMBI As UInt32
Dim si As SYSTEM_INFO
Dim mbi As MEMORY_BASIC_INFORMATION
Dim Prozess As Process = Process.GetProcessById(D.ID)
'Open process with required access
hProcess = OpenProcess(PROCESS_READ_WRITE_QUERY, False, Prozess.Id)
If hProcess = 0 Then
MsgBox("Can't open process!")
Exit Sub
End If
'Determine applications memory addresses range
'Call GetNativeSystemInfo(si)
Call GetSystemInfo(si)
lpMem = 0 'si.lpMinimumApplicationAddress
lLenMBI = Marshal.SizeOf(mbi)
'Try
'Scan memory
Do While lpMem < si.lpMaximumApplicationAddress
BGW.ReportProgress(1)
If BGW.CancellationPending = True Then Exit Sub
ret = VirtualQueryEx(hProcess, lpMem, mbi, lLenMBI)
If ret = lLenMBI Then
If mbi.lType = &H20000 AndAlso mbi.State = &H1000 AndAlso mbi.RegionSize > 0 Then
Dim sBuffer As Byte() = New Byte(mbi.RegionSize - 1) {}
ReadProcessMemory(hProcess, mbi.BaseAddress, sBuffer, mbi.RegionSize, 0)
strings.AddRange(FindStrings(sBuffer, 4))
End If
Else
Exit Do
End If
'Increase base address for next searching cicle. Last address may overhead max Long value (Windows use 2GB memory, which is near max long value), so add Error checking
lpMem = mbi.BaseAddress + mbi.RegionSize
Loop
'Catch ex As Exception
'System.Console.WriteLine("ERROR: " + ex.Message)
'End Try
CloseHandle(hProcess)
BGW.ReportProgress(2, strings)
'7ffe1000
End Sub
Private Sub BGW_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
lblStatus.Text = "Complete"
Progress.Value = D.Pages
System.Threading.Thread.Sleep(150)
Dim thread As New Thread(
Sub()
strings = strings.Distinct.ToList
lblStatus.Text = "Collecting Results..."
For Each item As String In strings
System.Console.WriteLine(item)
Exit For
Next
System.Console.WriteLine("DONE")
strings = Nothing
System.GC.Collect()
System.GC.WaitForPendingFinalizers()
Application.Exit()
End Sub)
thread.Start()
End Sub
Public Sub EnumeratePages()
Dim hProcess As IntPtr
Dim lpMem As UInt32, ret As UInt32, lLenMBI As UInt32
Dim si As SYSTEM_INFO
Dim mbi As MEMORY_BASIC_INFORMATION
Dim MBIitems() As String
Dim Prozess As Process = Process.GetProcessById(D.ID)
LV.Items.Clear()
LV.BeginUpdate()
'Open process with required access
hProcess = OpenProcess(PROCESS_READ_WRITE_QUERY, False, Prozess.Id)
If hProcess = 0 Then
MsgBox("Can't open process!")
Exit Sub
End If
'Determine applications memory addresses range
'Call GetNativeSystemInfo(si)
Call GetSystemInfo(si)
lpMem = 0 'si.lpMinimumApplicationAddress
lLenMBI = Marshal.SizeOf(mbi)
'Label1.Text = "MinimumApplicationAddress: " & MakeNiceSize(si.lpMinimumApplicationAddress) & vbNewLine & _
' "MaximumApplicationAddress: " & MakeNiceSize(si.lpMaximumApplicationAddress) & " / " & MakeNiceSize(UInteger.MaxValue)
Try
'Scan memory
Do While lpMem < si.lpMaximumApplicationAddress
ret = VirtualQueryEx(hProcess, lpMem, mbi, lLenMBI)
If ret = lLenMBI Then
With mbi
MBIitems = New String() { .AllocationBase.ToString("X").ToLower, Protection2String(.AllocationProtect), MakeNiceSize(.RegionSize), State2String(.State), Protection2String(.Protect), Type2String(.lType)}
LV.Items.Add(.BaseAddress.ToString("X").ToLower).SubItems.AddRange(MBIitems)
End With
Else
Exit Do
End If
'Increase base address for next searching cicle. Last address may overhead max Long value (Windows use 2GB memory, which is near max long value), so add Error checking
lpMem = mbi.BaseAddress + mbi.RegionSize
Loop
Catch ex As Exception
System.Console.WriteLine(ex.Message)
End Try
CloseHandle(hProcess)
LV.EndUpdate()
D.Pages = LV.Items.Count - 1
Progress.Value = 0
Progress.Maximum = D.Pages
BGW.RunWorkerAsync()
System.Console.WriteLine("Done enumerating!")
Me.Text = D.Name & ".exe - " & D.ID
'7ffe1000
End Sub
Solved! I have discovered the issue was caused by my compiler being set to x86 when it needed to be set to x64. No longer hangs!