Hi!
Habe hier eine Read und Write funktion, um in einem Spiel Geld zu cheaten.
private void cheat()
{
Process[] proc = Process.GetProcessesByName("1602");
if (proc.Length == 0)
{
MessageBox.Show("No Processes found.");
return;
}
Process po;
po = proc[0];
IntPtr rhdl = OpenProcess(0x10, false, (uint)po.Id); //ReadAccess
IntPtr whdl = OpenProcess(0x20, false, (uint)po.Id); //WriteAccess
if (rhdl == null)
{
MessageBox.Show("Readhandle nicht erstellt.", "Fehler!");
return;
}
if (whdl == null)
{
MessageBox.Show("Writehandle nicht erstellt.", "Fehler!");
return;
}
byte[] bytes = new byte[4];
uint adress = 0x560264;
uint size = sizeof(int);
uint rw = 0;
bool read;
read = ReadProcessMemory(rhdl, (IntPtr)adress, bytes, (UIntPtr)size, ref rw);
if (!read)
{
MessageBox.Show("Fehlschlag beim Lesen.");
return;
}
else
{
MessageBox.Show(BitConverter.ToInt32(bytes, 0).ToString(), "Anzahl Geld:");
}
int money = BitConverter.ToInt32(bytes, 0);
money = money + 10000;
byte[] bytes2 = new byte[4];
bytes2 = BitConverter.GetBytes(money);
bool write;
write = WriteProcessMemory(whdl, (IntPtr)adress, bytes2, (UIntPtr)size, ref rw);
if (write)
MessageBox.Show("Write erfolgreich!");
else if (!write)
{
int error = Marshal.GetLastWin32Error();
MessageBox.Show(" Write Fehlgeschlagen. Errorcode: " + error.ToString(), "Fehler!");
return;
}
}
Das Auslesen funktioniert. Das konvertieren von byte in Int funktioniert auch. Wenn ich testweise nochmal bytes2 zurückkonvertiere und anzeige steht auch der neue Wert da. Keine Ahnung obs relevant ist, denke nicht, aber money geht über 5 Millionen. Vielleicht ist die Zahl zu groß, kann ich aber kaum glauben.
Ich kann keinen Fehler entdecken. Wenn ich hier im Forum suche, dann entdecke ich zwar einen ähnlichen Thread, aber WriteProcessMemory sieht genau gleich aus. Zumal der Errorcode auch noch 0 ist, was heisst, dass die Operation eigentlich successful war.
Grüße
Edit:
Die Imports:
[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);
[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
byte[] lpBuffer, UIntPtr nSize, ref uint lpNumberOfBytesWritten);
Da es sich um Anno 1602 handelt ists ja kein Ding zu Antworten 😉
Bist du dir sicher das die Adresse des Funktionszeigers (0x560264) stimmt?
Ansonsten, hast du überprüft ob der Stack wirklich nur 4 bytes groß ist? - 1.000.000 (2 Dwords) 8 Bytes in den meisten Games...
Ansonsten, schön und sauber - sehe wenn den Fehler nicht 🙂
Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(
Hi,
es wird der richtige Wert für das Gold angezeigt. Der liegt irgendwo bei 5,5 Millionen. Deswegen muss die Adresse richtig sein.
_
Ansonsten, hast du überprüft ob der Stack wirklich nur 4 bytes groß ist? - 1.000.000 (2 Dwords) 8 Bytes in den meisten Games..._
Sorry, aber das sagt mir nichts 🙂
Grüße
statt
byte[] bytes = new byte[4];
sind es in anderen Games
byte[] bytes = new byte[8];
Auch wenn der "richtige" Wert angezeigt wird.
Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(
Hrm, hab irgenwie 5Mrd statt 5 mio gelesen...
4Bytes passt in dem Fall und mit int usw. haut alles hin.. irgendwie nicht mein Tag Heute.
Tjor, sehe den Fehler dann auch nicht.
Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(
Schade 🙂 Danke!
Grüße
LÖSUNG:
Ich hätte bei den Imports SetError true machen sollen:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
byte[] lpBuffer, UIntPtr nSize, ref uint lpNumberOfBytesWritten);
Und dann hatte mein Handle nicht die genügenden Accessrights (denn der Error war 5):
IntPtr whdl = OpenProcess(0x0020 | 0x0008, false, (uint)po.Id); //WriteAccess
Danke!
Huch, der Fehler steckt manchmal im Detail 🙂
Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(
Die Lösung gibts dann zum Nachlesen hier:
http://www.c-plusplus.de/forum/viewtopic-var-t-is-215574.html
Den Beitrag selbst finde ich aber sehr interessant, genau nach dem wurde in vielen Foren schon oft gefragt 😮) Thx für die Lösung
Ja Term!nX und chris2k6 sind ein und die selbe Person 🙂 Bin selbst draufgekommen, nachdem ich endlich den Errorcode hatte.