C# C# aiuto con ReadProcessMemory

Stato
Discussione chiusa ad ulteriori risposte.

AlexAlexAlex

Utente Silver
16 Agosto 2010
101
11
45
94
Ciao a tutti.
Sto creando un hack per prato fiorito in C# per fare pratica, è da 2 anni che programmo, ma è da poco che ho iniziato a creare hack. So usare la ReadProcessMemory e anche la WriteProcessMemory. Sono riuscito a modificare il tempo, il numero dei fiori, l'altezza e la largezza del gioco, il numero delle caselle trovate, il suono, il segno(?), i tempi migliori in secondi e il nome di chi ha fatto i tempi migliori.
Il problema arriva quando voglio leggere il nome di chi ha fatto i tempi migliori, perchè è una stringa e con ReadProcessMemory non so come leggerla, riesco solo a leggere i valori 4bytes.
Ho provato con questo:

UInt32 ProcID;
IntPtr WindowHandle = FindWindow(null, "Prato fiorito");
GetWindowThreadProcessId(WindowHandle,
out ProcID);
IntPtr ProcessHandle = OpenProcess(0x1F0FFF, 1, ProcID);
byte[] buffer = new byte[4];
int bytesread = 4;

//legge il miglior tempo e lo converte in testo(funziona)
ReadProcessMemory(ProcessHandle, (
IntPtr)0x10056D4, buffer, 4, out bytesread);
textBox5.Text =
BitConverter.ToInt32(buffer, 0).ToString();

//legge il nome di chi ha fatto il miglior tempo esperto ma legge solo una lettera e non tutto il nome
ReadProcessMemory(ProcessHandle, (IntPtr)0x1005758, buffer, 4, out bytesread);
string s = Encoding.UTF8.GetString(buffer);
textBox8.Text = s;

ma legge solo una lettera e non tutto il nome, per esempio se il nome intero è Anonimo mi legge solo A. Come posso fare per leggere tutto il nome?

Ciao e grazie a tutti
 
Ho trovato la soluzione dovevo cambiare il numero di byte.
Ho fatto un paio di tentativi e con Encoding.Unicode ho fatto questo:

UInt32 ProcID;
IntPtr WindowHandle = FindWindow(null, "Prato fiorito");
GetWindowThreadProcessId(WindowHandle,
out ProcID);
IntPtr ProcessHandle = OpenProcess(0x1F0FFF, 1, ProcID);
byte[] buffer = new byte[4];
int bytesread = 4;
byte[] buffer2 = new byte[256];
int bytesread2 = 256;
ReadProcessMemory(ProcessHandle, (
IntPtr)0x10056D4, buffer, 4, out bytesread);
textBox5.Text =
BitConverter.ToInt32(buffer, 0).ToString() + " Secondi";
//non funzia
ReadProcessMemory(ProcessHandle, (IntPtr)0x1005758, buffer2, 256, out bytesread2);
string str = Encoding.Unicode.GetString(buffer2, 0, 256);
textBox8.Text = str;

grazie Whivel per avermi detto che sbagliavo facendo Encoding.UTF8
 
String non è un tipo di base ma una classe (per lo meno in C++)
In realtà le stringhe vengono trattare come array di char e devi leggerle come tali. Posso dirti che i char occupino 1 byte di memoria ma non so aiutarti ulteriormente

EDIT: Preceduto
 
Sono riuscito a leggere la stringa, ora però dovrei, avendo una string in una textBox, fare WriteProcessMemory(), che però deve scrivere una stringa e non un valore 4bytes. Come posso fare?
 
Ultima modifica:
Ho cercato su internet ma non sono riuscito a trovare come usarla :nono:, potresti farmi un esempio per piacere, ti posto un pò di codice.

prima di tutto importo le librerie e le relative funzioni

// C# Signature for the FindWindow() API
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(
string lpClassName,
string lpWindowName
);
// C# Signature for the WriteProcessMemory() API
[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
byte[] lpBuffer,
UIntPtr nSize,
out IntPtr lpNumberOfBytesWritten
);
// C# Signature for the OpenProcess() API
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(
UInt32 dwDesiredAccess,
Int32 bInheritHandle,
UInt32 dwProcessId
);
// C# Signature for the GetWindowThreadProcessId() API
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(
IntPtr hWnd,
out uint lpdwProcessId
);

[
DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[
Out] byte[] lpBuffer,
int dwSize,
out int lpNumberOfBytesRead
);

public
static bool Hack(int Address, uint Value)

{
UInt32 ProcID;
IntPtr bytesout;
IntPtr WindowHandle = FindWindow(null, "Prato fiorito");
if (WindowHandle == null) { return false; }
GetWindowThreadProcessId(WindowHandle,
out ProcID);
IntPtr ProcessHandle = OpenProcess(0x1F0FFF, 1, ProcID);
WriteProcessMemory(ProcessHandle, (
IntPtr)Address, BitConverter.GetBytes(Value), (UIntPtr)sizeof(uint), out bytesout);
return true;
}



quindi io normalmente per scrivere un valore 4bytes faccio così


Hack(0xaddress, value(per esempio uint.Parse(testo))

ma se volessi scrivere una stringa, che ho in una textBox nell'address, che ha il formato di stringa con una lunghezza massima di 15, 20 lettere, come potrei fare?
vorrei fare una cosa del genere
Hack(0xaddress, string value, int lunghezza stringa(se possibile);

cioè

Hack(0x010056D8(formato stringa 7 caratteri), testo per la stringa, int per la lunghezza stringa(15, 20));

ciao a tutti e grazie ancora
 
Ultima modifica:
cambia hack in
Codice:
[SIZE=2][FONT=Consolas][COLOR=#0000ff]
[/COLOR][/FONT][/SIZE][FONT=Consolas][FONT=Consolas][SIZE=2] publicstaticbool Hack(int Address, byte Value[]) 
{
  UInt32 ProcID;
  IntPtr bytesout;
  IntPtr WindowHandle = FindWindow(null, "Prato fiorito");
  if (WindowHandle == null) { returnfalse; }
 GetWindowThreadProcessId(WindowHandle, out ProcID);
  IntPtr ProcessHandle = OpenProcess(0x1F0FFF, 1, ProcID);
 WriteProcessMemory(ProcessHandle, (IntPtr)Address, Value, (UIntPtr)sizeof(uint), out bytesout);
  returntrue;
 }
 
[/SIZE][/FONT][/FONT]
dovresti provare a fare
Codice:
system.io.memorystream tmp = system.io.memorystream(stringa)
hack(ADDRESS,tmp.toArray()/*o qualcosa del genere*/ )
tmp.close()
(controlla se la classe string non permetta direttamente di convertire in array)

invece per gli uint basta che fai
Codice:
hack(ADDRESS,[FONT=Consolas][SIZE=2][COLOR=#2b91af][FONT=Consolas][SIZE=2][COLOR=#2b91af][FONT=Consolas][SIZE=2][COLOR=#2b91af]BitConverter[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2].GetBytes(Value))
[/SIZE][/FONT][/SIZE][/FONT]
 
Allora, con gli address che trovo su cheat engine, in formato 4bytes riesco a leggerli e modificarli con c#, riesco a leggere le stringhe, ma non riesco a modificarle, ora provo a farecome ha detto Whivel
 
ma tu per caso hai idea della differenza che c'è tra una stringa e di un indirizzo che fa da puntatore ad essa? perchè mi viene qualche dubbio in proposito...
 
Ultima modifica:
Finalmente ci sono riuscito! Ho fatto così:

UInt32 ProcID;
IntPtr WindowHandle = FindWindow(null, "Prato fiorito");
GetWindowThreadProcessId(WindowHandle,
out ProcID);
IntPtr ProcessHandle = OpenProcess(0x1F0FFF, 1, ProcID);
int bytesread = 256;
byte[] b = new byte[256];
b =
Encoding.Unicode.GetBytes(textBox20.Text);
WriteProcessMemory(ProcessHandle, (
IntPtr)0x10056D8, b, (UIntPtr)b.Length, out bytesread);

Adesso scrive la stringa perfettamente, però c'è un piccolo problema.
Ho scritto come nome per esempio pincopallino, ma voglio cambiarlo e scriverci ciao,
il risultato è questo: mi scrive ciaoopallino, si ricorda delle lettere che ho scritto prima, infatti toglie le prime 4 lettere pinc e ci scrive ciao. Come posso fare? Dopo non vi rompo più:nono:
Ciao e grazie a tutti.
 
ironia della sorte, il motivo è lo stesso per cui prima ti leggeva solo la prima lettere ^^
dopo che hai scritto il nome in memoria, scrivici di seguiti due byte 0
 
  • Mi piace
Reazioni: AlexAlexAlex
Scusa se disturbo ancora, in che senso scrivici due bye 0 ?
dopo che ho fatto così
WriteProcessMemory(ProcessHandle, (IntPtr)0x10056D8, b, (UIntPtr)b.Length, out bytesread);
che cosa devo fare?
 
int16 zero = 0;
WriteProcessMemeory(ProcessHandle,(IntPtr)0x10056D8 + b.length*2,zero,2,out bytesread)
qualcosa del genere
 
Se faccio come dici tu, viene fuori questo:
Int16 zero = 0;
WriteProcessMemory(ProcessHandle, (
IntPtr)0x10056D8 + b.Length * 2, zero, 2, out bytesread);


con i seguenti errori:

Errore 2 Argomento 3: impossibile convertire da 'short' a 'byte[]' D:\da internet\4Story\Prato Fiorito Hack\Prato Fiorito Hack\Form1.cs 338 85 Prato Fiorito Hack

Errore 3 Argomento 4: impossibile convertire da 'int' a 'System.UIntPtr' D:\da internet\4Story\Prato Fiorito Hack\Prato Fiorito Hack\Form1.cs 338 91 Prato Fiorito Hack

Errore 1 La corrispondenza migliore del metodo di overload per 'Prato_Fiorito_Hack.Form1.WriteProcessMemory(System.IntPtr, System.IntPtr, byte[], System.UIntPtr, out int)' presenta alcuni argomenti non validi D:\da internet\4Story\Prato Fiorito Hack\Prato Fiorito Hack\Form1.cs 338 17 Prato Fiorito Hack
 
ho detto "qualcosa del genere".... il cervello dovrebbe riuscire ad associare cose simili....

byte zero[]={0,0};
WriteProcessMemory(ProcessHandle, (IntPtr)0x10056D8 + b.Length * 2, zero, (UintPtr)2, out bytesread);
 
Ho fatto vari tentativi, ma niente lo stesso risultato.
e comunque (IntPtr)0x10056D8 + b.Length * 2 non ha senso, perchè così cambia solo il valore del pointer, che invece deve essere 0x10056D8 e
byte[] zero = {0, 0} non fa scrivere niente.
 
Ultima modifica:
ah si è perchè IntPtr il read, read. mentre se fa x0400000 allora era, mentre no.





LOL mode ON
 
  • Mi piace
Reazioni: SpeedJack
Stato
Discussione chiusa ad ulteriori risposte.