cs_Jean_Jean
Messages postés614Date d'inscriptiondimanche 13 août 2006StatutMembreDernière intervention13 décembre 20183 5 juil. 2012 à 14:40
Bonjour Mokost,
J'ai été intéressé par ton code que j'ai inclu dans un projet test sous XE2.
Mais le compilateur me génère 29 erreurs du genre:
E2033 : les types des parametres VAR originaux et formels doivent être identiques.
Lorsque je regarde les fonctions en question, par exemple :
function TProcessDataModifier.ReadBytes(size:integer):TByteDynArray;
var readed :cardinal;
begin
setlength(result,size);
ReadProcessMemory(FAccessHandle,pointer(FAdresse),@result[0],size,readed);
inc(FAdresse,size);
end;
le compilateur s'arrête sur la 2ème ligne: ReadProcessMemory(...) que je n'ai pas modifié!
Je fais appel à la fonction dans la fiche principale:
procedure TForm1.FormActivate(Sender: TObject);
begin
// test1.exe qui est un code de D7
ProcessReader := TProcessDataModifier.Create('test1',0);
// Lire une chaîne de 256 octets
With ProcessDataModifier DO
Begin
Showmessage(ReadString(256)); //nombre d'octet à lire
End;
end;
Que se passe-t-il?
fredelem
Messages postés136Date d'inscriptiondimanche 29 octobre 2006StatutMembreDernière intervention 1 décembre 20222 26 juil. 2011 à 09:12
J'ai introduit cette modification dans la procedure ReadString en remplaçant le "Raise Exception" par "result:=", ce qui donne:
if (not ReadProcessMemory (FAccessHandle, pointer (FAdresse), @result[1], size, readed)) then
result:=('Impossible de lire les données')
Else
begin (* reprise du programme original *)
ReadProcessMemory (FAccessHandle, Pointer (FAdresse) , @result[1] , Size,Readed);
setlength(str,readed);
result := String(str);
end;
Effectivement, au lieu d'obtenir "Lire_mem.exe", j'obtiens maintenant "Impossible de lire les données".
J'ai essayé de changer l'adresse de lecture. Après l'exemple que tu donnes (ProcessReader.Adresse := $047Fc87), j'ai essayé d'autres adresses.
Si je passe au dessous de 0460000, j'obtiens "Impossible de lire les données". Si je prends une valeur supérieure, j'obtiens un Showmessage vide. Je suppose que ça représente une longue suite de Chr(0) avec aucun autre caractère. C'est quand même un peu surprenant.
J'avoue que je ne sais pas grand-chose sur la gestion de la mémoire. Est-ce que tu vois une adresse où je pourrais lire quelque chose d'intéressant ?
Mokost
Messages postés48Date d'inscriptionjeudi 18 décembre 2003StatutMembreDernière intervention29 mars 2010 25 juil. 2011 à 22:53
L'argument qui suit ReadString réprésente bien le nombre d'octet à lire. Il impossible de lire à l'adresse 0, c'est pour cela que tu obtient "Lire_mem.exe", on se sait pas ou il lit vraiment les données. En fait il aurait été plus judicieux si j'avais mit un test ex:
if(not ReadProcessMemory(FAccessHandle,pointer(FAdresse),@result[1],size,readed))
then raise Exception.Create('Impossible de lire les données');
fredelem
Messages postés136Date d'inscriptiondimanche 29 octobre 2006StatutMembreDernière intervention 1 décembre 20222 22 juil. 2011 à 18:23
Je pense que c'est la mémoire de la calculatrice que j'ai lue puisque j'ai écrit au début du programme:
begin
// Faire de la calculatrice le processus étudié
ProcessReader := TProcessDataModifier.Create('Calc',0);
Mais j'ai essayé de modifier un peu ce Readstring(256). A la place, j'ai mis ReadString(500) et cette fois j'obtiens "Lire_mem.exe", le nom sous lequel j'ai sauvegardé ton programme. Bizarre, ça ne peut pas être contenu dans la mémoire de la calculatrice.
L'argument qui suit Readstring représente-t-il un nombre maximum d'octets à lire ou une adresse de départ ?
Mokost
Messages postés48Date d'inscriptionjeudi 18 décembre 2003StatutMembreDernière intervention29 mars 2010 8 juil. 2011 à 12:19
Je pense que tu as tenté de lire la mémoire d'un processus système et à mon avis Windows ne te permettra ni de lire ni de modifier la mémoire de ce processus.
fredelem
Messages postés136Date d'inscriptiondimanche 29 octobre 2006StatutMembreDernière intervention 1 décembre 20222 6 juil. 2011 à 13:12
En effet, il y avait une erreur de ma part. Au lieu de
WITH ProcessDataModifier DO
j'aurais dÙ écrire:
WITH ProcessReader DO
et supprimer ce FAdresse:=10000
car FAdresse est une variable de type "private".
Après correction, ça marche et le Showmessage me dit :
[System Process]
Eh bien bravo mais j'aimerais bien comprendre à quoi correspond ce que j'ai lu.
cs_cantador
Messages postés4720Date d'inscriptiondimanche 26 février 2006StatutModérateurDernière intervention31 juillet 202113 6 juil. 2011 à 11:52
mais je n'obtiens rien, même pas le showmessage!
????
ça doit planter nécessairement sur une de ces lignes :
With ProcessDataModifier DO
Begin
FAdresse:=10000:
---
End;
end;
fredelem
Messages postés136Date d'inscriptiondimanche 29 octobre 2006StatutMembreDernière intervention 1 décembre 20222 6 juil. 2011 à 10:56
Merci pour ces infos. Effectivement AnsiContainsText est accepté par mon vieux Delphi7 et la compilation ne pose plus de problème.
Dans mon Unit 1, je crée la procédure FormActivate suivante:
procedure TForm1.FormActivate(Sender: TObject);
begin
// Faire de la calculatrice le processus étudié
ProcessReader := TProcessDataModifier.Create('Calc',0);
// Lire une chaîne de 256 octets à l'adresse 10000
With ProcessDataModifier DO
Begin
FAdresse:=10000:
Showmessage(ReadString(256));
End;
end;
Je lance la calculatrice puis je lance mon application mais je n'obtiens rien, même pas le showmessage! Je demande encore un peu d'aide.
(J'ai vu sur Intenet que CheatEngine, c'est une application et non pas comme je le pensais un mot de Delphi. Moi qui aime bien Démineur, je vais m'intéresser à ce CheatEngine mais pour l'instant, je cherche plutôt à progresser dans l'utilisation de ton logiciel).
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 6 juil. 2011 à 01:10
@Freedelem:
si tu as D7 ou +
tu remplaces ContainsText par AnsiContainsText et ça devrait fonctionner
Mokost
Messages postés48Date d'inscriptionjeudi 18 décembre 2003StatutMembreDernière intervention29 mars 2010 5 juil. 2011 à 20:32
Pour ContainsText utilise strpos : l'idée c'est de savoir si le nom de fichier contient la chaine rechercher exemple on cherche 'calc' dans 'calc.exe'.
fredelem
Messages postés136Date d'inscriptiondimanche 29 octobre 2006StatutMembreDernière intervention 1 décembre 20222 5 juil. 2011 à 18:17
OK, j'ai remplacé RawByteString par String mais que puis-je faire pour la fonction ContainsText ? La remplacer par le mot "True" ou essayer de la réécrire à partir de l'idée suivante: si on trouve 10 caractères alphanumériques de suite dans le morceau à analyser, renvoyer true, sinon renvoyer false ?
Je voudrais bien utiliser CheatEngine mais Delphi7 ne connaît pas ce mot-là non plus.
Mokost
Messages postés48Date d'inscriptionjeudi 18 décembre 2003StatutMembreDernière intervention29 mars 2010 5 juil. 2011 à 16:48
Salut Fredelem, Comme je l'ai dit le type RawByteString et la fonction ContainsText existe bien dans Delphi Xe. Je m'en suis servit pour coder cette classe. Ensuite pour chercher l'adresse du résultat de la calculette je te conseille CheatEngine.
fredelem
Messages postés136Date d'inscriptiondimanche 29 octobre 2006StatutMembreDernière intervention 1 décembre 20222 5 juil. 2011 à 13:50
Je voudrais utiliser ton unité pour faire la chose suivante: lancer la calculatrice dans un processus et lire le résultat qu'elle affiche dans un autre et peut-être aussi voir quel est le contenu de la mémoire à l'adresse CS:IP. Peux-tu m'aider un peu à le faire ?
A la compilation, j'ai eu deux problèmes: le type RawByteString n'est pas défini et la fonction ContainsText non plus. Il faudrait que tu corriges ces deux oublis.
5 juil. 2012 à 14:40
J'ai été intéressé par ton code que j'ai inclu dans un projet test sous XE2.
Mais le compilateur me génère 29 erreurs du genre:
E2033 : les types des parametres VAR originaux et formels doivent être identiques.
Lorsque je regarde les fonctions en question, par exemple :
function TProcessDataModifier.ReadBytes(size:integer):TByteDynArray;
var readed :cardinal;
begin
setlength(result,size);
ReadProcessMemory(FAccessHandle,pointer(FAdresse),@result[0],size,readed);
inc(FAdresse,size);
end;
le compilateur s'arrête sur la 2ème ligne: ReadProcessMemory(...) que je n'ai pas modifié!
Je fais appel à la fonction dans la fiche principale:
procedure TForm1.FormActivate(Sender: TObject);
begin
// test1.exe qui est un code de D7
ProcessReader := TProcessDataModifier.Create('test1',0);
// Lire une chaîne de 256 octets
With ProcessDataModifier DO
Begin
Showmessage(ReadString(256)); //nombre d'octet à lire
End;
end;
Que se passe-t-il?
26 juil. 2011 à 09:12
if (not ReadProcessMemory (FAccessHandle, pointer (FAdresse), @result[1], size, readed)) then
result:=('Impossible de lire les données')
Else
begin (* reprise du programme original *)
ReadProcessMemory (FAccessHandle, Pointer (FAdresse) , @result[1] , Size,Readed);
setlength(str,readed);
result := String(str);
end;
Effectivement, au lieu d'obtenir "Lire_mem.exe", j'obtiens maintenant "Impossible de lire les données".
J'ai essayé de changer l'adresse de lecture. Après l'exemple que tu donnes (ProcessReader.Adresse := $047Fc87), j'ai essayé d'autres adresses.
Si je passe au dessous de 0460000, j'obtiens "Impossible de lire les données". Si je prends une valeur supérieure, j'obtiens un Showmessage vide. Je suppose que ça représente une longue suite de Chr(0) avec aucun autre caractère. C'est quand même un peu surprenant.
J'avoue que je ne sais pas grand-chose sur la gestion de la mémoire. Est-ce que tu vois une adresse où je pourrais lire quelque chose d'intéressant ?
25 juil. 2011 à 22:53
if(not ReadProcessMemory(FAccessHandle,pointer(FAdresse),@result[1],size,readed))
then raise Exception.Create('Impossible de lire les données');
22 juil. 2011 à 18:23
begin
// Faire de la calculatrice le processus étudié
ProcessReader := TProcessDataModifier.Create('Calc',0);
Mais j'ai essayé de modifier un peu ce Readstring(256). A la place, j'ai mis ReadString(500) et cette fois j'obtiens "Lire_mem.exe", le nom sous lequel j'ai sauvegardé ton programme. Bizarre, ça ne peut pas être contenu dans la mémoire de la calculatrice.
L'argument qui suit Readstring représente-t-il un nombre maximum d'octets à lire ou une adresse de départ ?
8 juil. 2011 à 12:19
6 juil. 2011 à 13:12
WITH ProcessDataModifier DO
j'aurais dÙ écrire:
WITH ProcessReader DO
et supprimer ce FAdresse:=10000
car FAdresse est une variable de type "private".
Après correction, ça marche et le Showmessage me dit :
[System Process]
Eh bien bravo mais j'aimerais bien comprendre à quoi correspond ce que j'ai lu.
6 juil. 2011 à 11:52
????
ça doit planter nécessairement sur une de ces lignes :
ProcessReader := TProcessDataModifier.Create('Calc',0);
With ProcessDataModifier DO
Begin
FAdresse:=10000:
---
End;
end;
6 juil. 2011 à 10:56
Dans mon Unit 1, je crée la procédure FormActivate suivante:
procedure TForm1.FormActivate(Sender: TObject);
begin
// Faire de la calculatrice le processus étudié
ProcessReader := TProcessDataModifier.Create('Calc',0);
// Lire une chaîne de 256 octets à l'adresse 10000
With ProcessDataModifier DO
Begin
FAdresse:=10000:
Showmessage(ReadString(256));
End;
end;
Je lance la calculatrice puis je lance mon application mais je n'obtiens rien, même pas le showmessage! Je demande encore un peu d'aide.
(J'ai vu sur Intenet que CheatEngine, c'est une application et non pas comme je le pensais un mot de Delphi. Moi qui aime bien Démineur, je vais m'intéresser à ce CheatEngine mais pour l'instant, je cherche plutôt à progresser dans l'utilisation de ton logiciel).
6 juil. 2011 à 01:10
si tu as D7 ou +
tu remplaces ContainsText par AnsiContainsText et ça devrait fonctionner
5 juil. 2011 à 20:32
5 juil. 2011 à 18:17
Je voudrais bien utiliser CheatEngine mais Delphi7 ne connaît pas ce mot-là non plus.
5 juil. 2011 à 16:48
5 juil. 2011 à 13:50
A la compilation, j'ai eu deux problèmes: le type RawByteString n'est pas défini et la fonction ContainsText non plus. Il faudrait que tu corriges ces deux oublis.