Jag håller på med ett minnes-sökar program som ska kunna söka efter värden i minnet på en annan process. Detta kanske kan vara till hjälp: Tack så mycket Andreas!Omvandla ett 2-byte tal till två 1-byte tal
Jag kan söka efter 1-byte värden och hitta rätt adress, såhär fungerar det:
I formen har jag en textbox och en knapp (kraftigt förenklat).
I textboxen skriver jag ett värde som jag ska söka efter och trycker på knappen så listas alla värden den hittar i en listbox.
I knappen:
Först öppnar jag processen med hjälp av OpenProcess (jag har ProcessID), flaggan är PROCESS_READ_WRITE_QUERY så att jag kan läsa och skriva till minnet på processen.
Sedan använder jag VirtualQueryEx funktionen för att få BaseAddress och RegionSize av en address.
Regionen läser jag sedan in i en sträng (sBuffer) genom ReadProcessMemory funktionen.
Sedan letar jag i sBuffer efter värdet jag specificerade i textboxen.
För att leta i sBuffer omvandlar jag värdet i textboxen till ASCII tecknet för värdet, sedan använder jag Instr såhär:
tecken = Chr$(Val(Textbox1.Text))
a = 0
Do
a = Instr(a+1, sBuffer, tecken)
If a <> 0 then
' Här listar jag addressen och värdet i en listbox
End If
Loop Until a = 0
Om den inte hittar fler addresser så hoppar den till nästa region och gör samma sak där tills den har sökt igenom alla regioner.
Detta fungerar perfekt och det går SNABBT!
Problemet är när man vill söka efter värden som är större än 1-byte, t.ex 4000 hur omvandlar man det till en 2-byte sträng som jag kan söka efter?
Denna funktion kommer i mitt WinlOOk 2.0 program.
(du kan kolla in WinlOOk 1.0 på min hemsida http://www.geocities.com/cyperium/index.html klicka på BASIC länken).Sv: Omvandla ett 2-byte tal till två 1-byte tal
<code>
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Function IntegerToString(ByVal Value As Integer) As String
Dim ValueAsString As String * 2
CopyMemory ByVal ValueAsString, Value, 2
IntegerToString = ValueAsString
End Function
Function LongToString(ByVal Value As Long) As String
Dim ValueAsString As String * 4
CopyMemory ByVal ValueAsString, Value, 4
LongToString = ValueAsString
End Function
</code>
Jag skulle skrivit loop lite anorlunda:
<code>
Private Sub Command1_Click()
Dim Pos As Long
Dim Value As Long
Dim Find As String
Dim FindLen As Long
Dim sBuffer As String
'Test Data
sBuffer = Chr$(0) & Chr$(1) & Chr$(2) & Chr$(3) & Chr$(4) & Chr$(5) & Chr$(6) & Chr$(7) & Chr$(8) & Chr$(9)
If IsNumeric(Text1.Text) Then
Value = Val(Text1.Text)
Select Case Value
Case 0 To 255
Find = Chr$(Value)
FindLen = 1
Case -32768 To 32767
Find = IntegerToString(Value)
FindLen = 2
Case -2147483647 To 2147483647
Find = LongToString(Value)
FindLen = 4
Case Else
MsgBox "Number out of scope"
End Select
Pos = InStr(1, sBuffer, Find)
Do While Pos
' Här listar jag addressen och värdet i en listbox
Debug.Print Pos
Pos = InStr(Pos + FindLen, sBuffer, Find)
Loop
Else
MsgBox "Enter a number in Textbox1!"
End If
End Sub
</code>
Exempel på sökningar:<br>
<br>
Text1.Text = "1"<br>
Text1.Text = "3"<br>
Text1.Text = "5"<br>
<br>
Text1.Text = "&H403"<br>
Text1.Text = "&H504"<br>
Text1.Text = "&H605"<br>
<br>
Text1.Text = "&H40302"<br>
Text1.Text = "&H60504"<br>
Text1.Text = "&H90807"<br>
<br>
Text1.Text = "&H5040302"<br>
Text1.Text = "&H7060504"<br>
Text1.Text = "&H9080706"<br>
<br>
<br>
Som du ser är värdena spegelvända. Detta är för att text sökning är ifrån vänster till höger. Du kan använda StrReverse() på antingen sBuffer eller resultatet från IntegerToString() och LongToString().Sv: Omvandla ett 2-byte tal till två 1-byte tal
Loopen som du föreslog är ungefär som jag också skulle göra, loopen i exemplet var bara en kraftig förenkling för att man skulle se och förstå vad jag menade.
Tack igen. (att använda CopyMemory var förresten både genialt och kreativt eftersom man direkt får minnets formatering m.m.)