-1
私はプロセスから文字列をスキャンするように設計されたプログラムを持っています。これは、少なくとも4バイト長の、プロセス内のすべての読み取り可能な文字列を出力するように設計されています。 (私は実際にMinecraftのJavaプロセスをスキャンしています)。何らかの理由で、デフォルトゲームは、しばらく座ってから、何度かスキャンを完了します。最小のモジュレーションを追加すると、スキャンがハングします。私がこれを解決できる方法はありますか?文字列を検索するReadProcessMemory
私がスキャンに使用している方法は次のとおりです。
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
「何か提案/アドバイスがありますか?」[お問合せ]を読んで[ツアー]を受けてください – Plutonix
編集ありがとうございます。 – Bryce