Memory reading issue mit baseaddress
-
Hallo,
ich bin am verzweifeln.
seit mehreren tagen versuche ich informationen aus einem programm herauszulesen. ich wollte anfangs einen string aus dem Internet explorer herauslesen, dies war anfangs etwas zu kompliziert für mich und ich entschied mich für solitär da ich dachte dieses programm bzw spiel wird wohl nicht geschützt sein und ich könnte einfacher die memory auslesen.
Dieses problem habe ich bereits auf stackoverflow geschildert.
http://stackoverflow.com/questions/8263135/finding-the-correct-baseaddress
wer nicht weiterverlinkt werden möchte
hier ist das bild von meinem desktop. das problem kann man sofort erkennen.
http://i.stack.imgur.com/50lva.jpg
außerdem noch mein code in c#
[DllImport("kernel32.dll")] static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, UIntPtr nSize, ref uint lpNumberOfBytesWritten); [DllImport("kernel32.dll")] static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Boolean bInheritHandle, UInt32 dwProcessId); public Form1() ------------------------ private void button1_Click(object sender, EventArgs e) { Process[] iexp = Process.GetProcessesByName("Solitaire"); if (iexp.Length == 0) { listBox1.Items.Add("NOT FOUND"); } Process internet = iexp[0]; uint baseAddress = (uint)internet.MainModule.BaseAddress.ToInt64(); System.IntPtr readHandle = OpenProcess(0x0010, false, (uint)internet.Id); byte[] bytes = new byte[4]; uint rw = 0; ReadProcessMemory(readHandle, (System.IntPtr)((baseAddress) + 0x50) + 0x14, bytes, (UIntPtr)4, ref rw); int someNumber = BitConverter.ToInt32(bytes, 0); ReadProcessMemory(readHandle, ((System.IntPtr)0x0016A534), bytes, (UIntPtr)4, ref rw); int someNumber2 = BitConverter.ToInt32(bytes, 0); ReadProcessMemory(readHandle, (System.IntPtr)((0xFFB7AFA8) + 0x50) + 0x14, bytes, (UIntPtr)4, ref rw); int someNumber3 = BitConverter.ToInt32(bytes, 0); listBox1.Items.Add("Read base + offsets: "+someNumber); listBox1.Items.Add("With the dynamic Address: " + someNumber2); listBox1.Items.Add("Read with baseAddress from ce + offset " + someNumber3); listBox1.Items.Add("My Base Address from c#: " + baseAddress); listBox1.Items.Add("BaseAddress from CE " + 0xFFB7AFA8);
-
WAS willst du machen? Jedes Modul hat seine base address. Schau in den memory view in welchem modul du dich befindest, davon die base address und schon kannst du per offset die static address erreichen?!
-
Hi schrieb:
WAS willst du machen? Jedes Modul hat seine base address. Schau in den memory view in welchem modul du dich befindest, davon die base address und schon kannst du per offset die static address erreichen?!
okay danke aber gibt es irgentwo eine lektüre die mir erklärt wie genau das alles funktioniert ?
also mein weg war halt von der dynamischen variable zum pointer mit offsets, der pointer ändert sich ja nach jedem start, die offsets bleiben immer die selben soweit ich weiß.
Jetzt meinst du es gibt eine feste "modul-addresse" ?ich hab eigentlich total viele fragen, am liebsten wäre mit irgentein guide bzw buch.
ich kann ja trotzdem mal meine fragen auflisten:
Wie komme ich vom pointer zur statischen (modul)baseadresse?
Was mache ich mit dieser moduladresse ? addiere ich die baseaddress+moduladdress+offsets?
Hi schrieb:
WAS willst du machen?
ich möchte nur die memory auslesen können, anfangs mal einen integer.
aber ohne wirklich zu verstehen wie die memory aufgebaut ist bringt mir das nicht wirklich viel oder ?
-
Ja, frag am besten einfach.
Ein Modul ist eine .exe oder .dll. Jedes Modul hat eine base address also module base.
Bei Solitär gibts wohl nur die .exe, also kannst du .MainModule.BaseAddress nehmen.Nehmen wir an, der gewünschte Wert befindet sich immer an derselben Adresse (Relativ zum Modul, nur das geht). Dann guckst du, in welchem Modul sich die befindet (wiegesagt, hier wahrscheinlich die .exe selbst) (Rechtsklick - memory view glaub ich). Adresse - module base = offset. Bei Neustart neue module base holen + (alter) offset = Adresse zum Wert.
Ansonsten nach fixen Zeigern zu der Adresse suchen, das hast du ja scheinbar schon gemacht. Sonst bliebe AFAIK nur noch n code cave, um an die dynamische Adresse ranzukommen.
Mit den Zeigern verfährst du genau gleich. Da beschreibt der Wert an der Adresse einfach eine weitere Adresse. In deinem Fall, nehmen wir an die .exe base ist 0x10000000:
0xFFB7AFA8 (fixer Zeiger) - 0x10000000 = 0xEFB7AFA8 (fixer offset)
Bei Neustart 0x10000000 (oder neue base) + 0xEFB7AFA8 = fixe Adresse (hier Zeiger)Den Wert des Zeigers (also wohin er zeigt, war 0x2C5750) dann + 0x50 (scheinbar) ergibt eine neue Adresse, die wiederum ein Zeiger ist, dessen Wert dann noch + 0x14 (scheinbar) und du hast die Adresse des gewünschten Werts.
-
okay
also nochmal zum verständis was ich habe:
Meine aktuelle dynamische Adresse : 0x0041A534
Meinen Pointer : 0xFFA8AFA8 mit offset 0x14 und 0x50
Meine Baseadresse(ermittelt mit c#) : 0xFF9D0000
0xFFB7AFA8 (fixer Zeiger) - 0x10000000 = 0xEFB7AFA8 (fixer offset)
Bei Neustart 0x10000000 (oder neue base) + 0xEFB7AFA8 = fixe Adresse (hier Zeiger)dh ich rechne nun
0xFFA8AFA8 - 0xFF9D0000 = 0xBAFA8
also ergibt sich daraus folgender code
ReadProcessMemory(readHandle, (System.IntPtr)(((baseAddress + 0xBAFA8)+0x14)+0x50), bytes, (UIntPtr)4, ref rw); int someNumber = BitConverter.ToInt32(bytes, 0);
leider bekomme ich kein sinnvolles ergebnis
hier das bild zum pointer
http://s1.directupload.net/file/d/2720/mfvo35af_jpg.htmmöchte mich nochmals bedanken, du hast mir sehr geholfen auch wenn es bisher noch nicht so funktiert wie ich es gerne möchte.
-
Guck doch mal im memory view, die Adresse 0x41A534, kommen mir paar Ziffern bekannt vor... Darüber siehst du, dass diese Adresse die Base=0041A000 hat. Scheint also doch eine .dll zu sein?! (Wenn du von einer Base 0xFF9D0000 sprichst, muss es wohl mehrere Spielmodule geben). Es könnte also doch ganz einfach sein, mit fixem offset.
0x41A534 - 0x41A000 = 0x534
Jetzt musst noch gucken, wie der Modulname mit der Base 0x41A000 ist (Ich empfehle http://technet.microsoft.com/de-de/sysinternals/bb896653 , kA jetzt ob und wie das mit CE geht), von dem dann bei jedem Start die Base holen + 0x534 ist schon die Adresse zum Wert.
Dein Code ist übrigens komplett falsch. Du kannst doch nicht einfach alles zusammenrechnen. 1x ReadProcessMemory ermittelt dir den Wert an der angegebenen Adresse. Das musst du pro Zeiger aufrufen, dann den ermittelten Zeigerwert + offset, diesen Wert als neue Adresse für ReadProcessMemory usw...
-
Hi schrieb:
Guck doch mal im memory view, die Adresse 0x41A534, kommen mir paar Ziffern bekannt vor... Darüber siehst du, dass diese Adresse die Base=0041A000 hat. Scheint also doch eine .dll zu sein?! (Wenn du von einer Base 0xFF9D0000 sprichst, muss es wohl mehrere Spielmodule geben). Es könnte also doch ganz einfach sein, mit fixem offset.
0x41A534 - 0x41A000 = 0x534
Jetzt musst noch gucken, wie der Modulname mit der Base 0x41A000 ist (Ich empfehle http://technet.microsoft.com/de-de/sysinternals/bb896653 , kA jetzt ob und wie das mit CE geht), von dem dann bei jedem Start die Base holen + 0x534 ist schon die Adresse zum Wert.
Dein Code ist übrigens komplett falsch. Du kannst doch nicht einfach alles zusammenrechnen. 1x ReadProcessMemory ermittelt dir den Wert an der angegebenen Adresse. Das musst du pro Zeiger aufrufen, dann den ermittelten Zeigerwert + offset, diesen Wert als neue Adresse für ReadProcessMemory usw...
okay danke ich hab es hinbekommen
man das hat echt lange gedauert :p