Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Go Back   Foros Club Delphi > Principal > Varios
Register FAQ Members List Calendar Guía de estilo Search Today's Posts Mark Forums Read

Coloboración Paypal con ClubDelphi

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 27/08/2015
deliriun deliriun is offline
Miembro
 
Join Date: Aug 2014
Posts: 51
Poder: 12
deliriun Va por buen camino
Question Buscando texto en la memoria de un programa.

Hola qué tal?

Pues me supongo que ha muchos les sonara conocido el programa "Cheat Engine" y las multiples funciones que tiene y no
solamente que se usan para crear Trainers ( aunque siendo sinceros es lo más típico ) de hecho tiene varias funciones que me
han llamado la atención como por ejemplo la opción que sirve para acelerar un programa seleccionado a cierta velocidad...
Pero realmente vengo a hacer la consulta por la busqueda de "String" ... En Cheat Engine se selecciona un programa y se puede buscar
distintos tipos de variables, Floats, Double, Strings entre otros...

Quisiera saber como hacer un programa similar que busque un String y que halle su address para posteriormente modificar su valor..
Espero no sea mucho pedir...

Gracias
Reply With Quote
  #2  
Old 27/08/2015
Casimiro Noteví's Avatar
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Join Date: Sep 2004
Location: En algún lugar.
Posts: 32,682
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
Ábrelo en modo binario, hay varios ejemplos por los foros.
Reply With Quote
  #3  
Old 27/08/2015
ecfisa's Avatar
ecfisa ecfisa is offline
Moderador
 
Join Date: Dec 2005
Location: Tres Arroyos, Argentina
Posts: 10,508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Si como dice Casimiro, se ha tratado varias veces. Ahora mismo recuerdo este ejemplo.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Reply With Quote
  #4  
Old 27/08/2015
Casimiro Noteví's Avatar
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Join Date: Sep 2004
Location: En algún lugar.
Posts: 32,682
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
Buena memoria
Reply With Quote
  #5  
Old 27/08/2015
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Creo que a lo que se refiere deliriun es a buscar y reemplazar texto el la memoria de otro proceso.

Para ello deberás abrir el proceso y usar las AIPs ReadProcessMemory y WriteProcessMemory. Con la primera lees un bloque de memoria del proceso "atacado" en él debes buscar tu cadena, reemplazarla (en este caso el número de caracteres reemplazados no puede superar NUNCA a la cadena original) y luego escribir el bloque de nuevo en el proceso en cuestión con WriteProcessMemory. Para buscar y reemplazar el texto puedes usar el código que propone ecfisa o este.


Saludos.

Last edited by escafandra : 27/08/2015 at 01:26.
Reply With Quote
  #6  
Old 27/08/2015
deliriun deliriun is offline
Miembro
 
Join Date: Aug 2014
Posts: 51
Poder: 12
deliriun Va por buen camino
Aclaración

Cuando puse de ejemplo el programa Cheat Engine me refería cuando el programa este corriendo
abrirlo desde el proceso ( como lo hace el Cheat Engine ) y una vez ahí hacer una búsqueda en memoria pero solo de String..
Obtener el address y cambiar su valor...
Reply With Quote
  #7  
Old 27/08/2015
ecfisa's Avatar
ecfisa ecfisa is offline
Moderador
 
Join Date: Dec 2005
Location: Tres Arroyos, Argentina
Posts: 10,508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola deliriun.
Quote:
Originally Posted by deliriun View Post
Cuando puse de ejemplo el programa Cheat Engine me refería cuando el programa este corriendo
abrirlo desde el proceso ( como lo hace el Cheat Engine ) y una vez ahí hacer una búsqueda en memoria pero solo de String..
Obtener el address y cambiar su valor...
A... había interpretado otra cosa, ahora entiendo. Entonces escafandra ya te dió las pautas correctas de como encararlo en el mensaje #5.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Reply With Quote
  #8  
Old 27/08/2015
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Lee el mensaje 5

Saludos.
Reply With Quote
  #9  
Old 27/08/2015
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Caramba, ecfisa, ya nos hemos pisado

Saludos.
Reply With Quote
  #10  
Old 27/08/2015
deliriun deliriun is offline
Miembro
 
Join Date: Aug 2014
Posts: 51
Poder: 12
deliriun Va por buen camino
Red face Un ejemplo.

Alguien me podría dar un ejemplo de como emplear... No entiendo mucho las paginas de Microsoft
Reply With Quote
  #11  
Old 27/08/2015
Casimiro Noteví's Avatar
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Join Date: Sep 2004
Location: En algún lugar.
Posts: 32,682
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
No te lo tomes a mal, pero si dices eso es que quizás no estés preparado todavía para hacer algo así.
Reply With Quote
  #12  
Old 27/08/2015
ecfisa's Avatar
ecfisa ecfisa is offline
Moderador
 
Join Date: Dec 2005
Location: Tres Arroyos, Argentina
Posts: 10,508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Seguramente... y por otro lado:
Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Reply With Quote
  #13  
Old 27/08/2015
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Independientemente de que sea o no capaz de llegar a entender el uso de esas API y que les de un uno eficaz para su problema, yo quisiera saber cual es el interés particular de deliriun en alterar las cadenas de un proceso y cual es el proceso que quiere alterar.


Saludos.
Reply With Quote
  #14  
Old 28/08/2015
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Vamos a dar un empujoncito al tema. He escrito una función un poco a lo bruto para cambiar una cadena en un proceso. He de aclarar que está escrito en delphi7, que se compila para 32bits, esto quiere decir que no se pueden atacar de esta forma procesos de 64bits. Lo he probado en winXP y en Win10:

Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, TLHelp32;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    Edit2: TEdit;
    Label2: TLabel;
    Label3: TLabel;
    Edit3: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

function  _wcsnicmp(wstr1, wstr2: PWCHAR; Size: integer): Integer; cdecl external 'crtdll';
function  wcslen(wstr: PWCHAR): Integer; cdecl external 'crtdll';


var
  Form1: TForm1;

implementation

{$R *.dfm}

//---------------------------------------------------------------------------
function EnablePrivilege(name: String; Enable: boolean = true): boolean;
var
  hToken: Cardinal;
  priv: TOKEN_PRIVILEGES;
begin
  priv.PrivilegeCount:= 1;
  priv.Privileges[0].Attributes:= 0;
  if Enable then priv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
  LookupPrivilegeValue(nil, PCHAR(name), priv.Privileges[0].Luid);
  OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
  AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^);
  Result:= (GetLastError = ERROR_SUCCESS);
  CloseHandle (hToken);
end;

//---------------------------------------------------------------------------
function RemoteReplaceString(PID: DWORD; Str, NewStr: PWCHAR): BOOL;
const
  nBytes = $16000;
var
  hProc: THANDLE;
  n, i, T, Len, nBytesRead: DWORD;
  Buffer, RemoteAddr: PBYTE;
  bi: MEMORY_BASIC_INFORMATION;
begin
  Result:= false;
  hProc:= OpenProcess(PROCESS_ALL_ACCESS, false, PID);
  Len:= wcslen(Str) * sizeof(WCHAR);
  GetMem(Buffer, nBytes);

  EnablePrivilege('SeDebugPrivilege');

  // Escaneamos la memoria del proceso en busca de la cadena
  for n:= 0 to $1000 do
  begin
     RemoteAddr:= PBYTE(n*nBytes-Len);
     ReadProcessMemory(hProc, RemoteAddr, Buffer, nBytes, nBytesRead);
     if nBytesRead > 0 then
     begin
       //Le resto el modulo de la división para no perderme cadenas partidas
       T:= nBytesRead - (nBytesRead mod wcslen(Str));
       i:= 0;
       while i <= T do
       begin
         // Busco la cadena en el buffer "no case sensitive"
         if _wcsnicmp(PWCHAR(DWORD(Buffer)+i), Str, wcslen(Str)) = 0 then
         begin
            // Si la encuentro la escribo en el proceso remoto
            if WriteProcessMemory(hProc, pointer(DWORD(RemoteAddr) + i), NewStr, Len, nBytesRead) then
              // si pude escribir incremento el índice para seguir buscando
              i:= i + wcslen(Str);
         end;
         inc(i);
       end;
     end;
   end;
   FreeMem(Buffer);
   CloseHandle(hProc);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  proc: TProcessEntry32;
  hSysSnapshot: THandle;
begin
  proc.dwSize := SizeOf(TProcessEntry32);
  hSysSnapshot:= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if (hSysSnapshot <> INVALID_HANDLE_VALUE) and Process32First(hSysSnapshot, proc) then
  begin
    repeat
      if SameText(String(proc.szExeFile), Edit1.Text) then
        RemoteReplaceString(proc.th32ProcessID, PWCHAR(WideString(Edit2.Text)), PWCHAR(WideString(Edit3.Text)));
    until not (Process32Next(hSysSnapshot, proc));
  end;
  CloseHandle(hSysSnapshot);
end;

end.


He de comentar lo siguiente:

1- Las cadenas de un proceso en memoria deben tratarse como UNICODE
2- He usado funciones "C" de la librería crtdll.dll que trae Windows como parte del S.O. para faciñitar la búsquede de cadenas a bajo nivel
- wcslen devuelve el número de caracteres de una cadena tipo WCHAR
- _wcsnicmp compara una cadena WCHAR con otra en una longitud máxima dada y sin ser sensible a mayúsculas/minúsculas
3- Un código para 32bits no puede leer la memoria de un proceso 64 bits sin más, se precisa un driver o trucos especiales, esto es debido a la incompatibilidad de los punteros que definen el rango de direcciones que son capaces de direccionar.
4- No se puede sustituir una cadena por otra de mayor longitud.

Espero aclarar alguna duda a deliriun.


Saludos.

Last edited by escafandra : 09/03/2020 at 08:00.
Reply With Quote
  #15  
Old 28/08/2015
deliriun deliriun is offline
Miembro
 
Join Date: Aug 2014
Posts: 51
Poder: 12
deliriun Va por buen camino
Unicode y 64 Bits

El código me funciona muy bien en 32 Bits... sin embargo estoy seguro que todo programador quiere que sus programas corran en cualquier PC por eso pregunto si es posible convertirlo a 64 Bits.

Por otro lado me funciona con Unicode... pero si ese no es el caso... Cómo se debería emplear...

Muchas Gracias de antemano por su ayuda...
Reply With Quote
  #16  
Old 29/08/2015
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
deliriun, ReadProcessMemory y WriteProcessMemory funcionan para un código de 64biits atacando otro también de 64 bits o de 32 bits, las que no te van a funcionar si compilas mi código en 64 bits (lazarus, por ejemplo) son wcslen y _wcsnicmp puesto que la librería crtdll.dll es se Win32. Te he dado las pautas, aunque pueden complicarse un poco más incorporando VirtualQueryEx. Puedes empezar a trabajar y nos cuetas.

Saludos.
Reply With Quote
  #17  
Old 30/08/2015
deliriun deliriun is offline
Miembro
 
Join Date: Aug 2014
Posts: 51
Poder: 12
deliriun Va por buen camino
Problema con String Unicode

Pues la verdad el código que me ha dado funciona bien... pero siendo sinceros no tengo experiencia programando con Delphi... Yo uso más vb.net por su sencillez pero admito que Delphi es mucho más potente y también hay mucho asesoramiento y ayuda como esta pagina por ejemplo así que hice la pregunta en este Foro y solo me gustaría ver como es posible hacer la búsqueda del String sin que sea UNICODE... ya que esa es mi dificultad... Y sé que este no es el sitio adecuado para preguntar pero si alguien conociera un Foro como este pero destinado a vb.net se lo agradecería mucho.

Gracias
Reply With Quote
  #18  
Old 30/08/2015
ecfisa's Avatar
ecfisa ecfisa is offline
Moderador
 
Join Date: Dec 2005
Location: Tres Arroyos, Argentina
Posts: 10,508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola deliriun.
Quote:
Originally Posted by deliriun View Post
... Y sé que este no es el sitio adecuado para preguntar pero si alguien conociera un Foro como este pero destinado a vb.net se lo agradecería mucho.
Supongo que Msdn foros - Lenguaje VB.NET - Microsoft debería ser suficientemente serio.

En la búsqueda, aparecen varios mas:Pero como no conozco nada acerca de vb.net, no puedo evaluar el nivel de esos foros como para recomendarte alguno en especial.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Reply With Quote
  #19  
Old 30/08/2015
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Quote:
Originally Posted by deliriun View Post
Pues la verdad el código que me ha dado funciona bien... pero siendo sinceros no tengo experiencia programando con Delphi... Yo uso más vb.net por su sencillez pero admito que Delphi es mucho más potente y también hay mucho asesoramiento y ayuda como esta pagina por ejemplo así que hice la pregunta en este Foro y solo me gustaría ver como es posible hacer la búsqueda del String sin que sea UNICODE... ya que esa es mi dificultad... Y sé que este no es el sitio adecuado para preguntar pero si alguien conociera un Foro como este pero destinado a vb.net se lo agradecería mucho.

Gracias
Bueno, vista la dificultad y siendo éste un foro para responder preguntas, te muestro este nuevo código, mucho más elaborado, que funciona en delphi y Lazarus. En Lazarus compilado para 64bits encuentra y cambia cadenas en procesos de 32 y 64 bits:
Código Delphi [-]
function _StrCmpNIW(Str1, Str2: PWCHAR; N: integer): DWORD;
var
  T: integer;
begin
  T:= 0;
  // Pasando a minusculas y comparando caracteres
  while ((Ord(Str1^) or 32) = (Ord(Str2^) or 32)) and (Str1^ <> #0) and (Str2^ <> #0) and (T < N) do
  begin
    inc(Str1);
    inc(Str2);
    inc(T);
  end;
  Result:= N-T;
end;

function EnablePrivilege(name: String; Enable: boolean = true): boolean;
var
  hToken: THANDLE;
  priv: TOKEN_PRIVILEGES;
begin
  priv.PrivilegeCount:= 1;
  priv.Privileges[0].Attributes:= 0;
  if Enable then priv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
  LookupPrivilegeValue(nil, PCHAR(name), priv.Privileges[0].Luid);
  OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
  AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), PTOKEN_PRIVILEGES(0)^, PDWORD(nil)^);
  Result:= (GetLastError = ERROR_SUCCESS);
  CloseHandle (hToken);
end;

//---------------------------------------------------------------------------
function RemoteReplaceString(PID: DWORD; Str, NewStr: PWCHAR): BOOL;
var
  hProc: THANDLE;
  i, T, Size, Len, nBytesRead: DWORD;
  Buffer: PCHAR;
  mbi: MEMORY_BASIC_INFORMATION;
  Start: PCHAR;
begin
  Result:= false;
  hProc:= OpenProcess(PROCESS_ALL_ACCESS, false, PID);
  Len:= lstrlenW(Str);
  Size:= Len * sizeof(WCHAR);
  EnablePrivilege('SeDebugPrivilege');
  Start:= nil;

  // Escaneamos la memoria del proceso en busca de la cadena
  while VirtualQueryEx(hProc, Start, mbi, sizeof(mbi))<>0 do
  begin
    if mbi.Protect <> 0 and not(mbi.Protect and (PAGE_NOACCESS or PAGE_GUARD)) then
    begin
      Buffer:= VirtualAlloc(nil, mbi.RegionSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
      if Buffer <> nil then
      begin
        ReadProcessMemory(hProc, mbi.BaseAddress, Buffer, mbi.RegionSize, nBytesRead);
        if nBytesRead > 0 then
        begin
          //Le resto el modulo de la división para no perderme cadenas partidas
          T:= nBytesRead - Size - nBytesRead mod Size;
          i:= 0;
          while i <= T do
          begin
            // Busco la cadena en el buffer "no case sensitive"
            if _StrCmpNIW(PWCHAR(Buffer+i), Str, Len) = 0 then
            begin
              // Si la encuentro la escribo en el proceso remoto
              if WriteProcessMemory(hProc, pointer(mbi.BaseAddress + i), NewStr, Size, PDWORD(0)^) then
              begin
                // Incremento el índice para seguir buscando
                //i:= i + Size - 1;
                Result:= Result or true;
              end;
            end;
            inc(i);
          end;
        end;
        VirtualFree(Buffer, 0, MEM_RELEASE);
      end;
    end;
    inc(Start, mbi.RegionSize);
  end;
  CloseHandle(hProc);
end;

Al escribir código a bajo nivel para 64bits hay que tener mucho cuidado con la aritmética de punteros y conversiones, ya que su tamaño es de 64bits y no de 32, como estamos acostumbrados.
Aprovecho para mostrar una función, _StrCmpNIW, simple y más rápida que la API del mismo nombre. Es importante dotar de velocidad al barrido de memoria.

Saludos.

Last edited by Casimiro Noteví : 30/08/2015 at 20:01.
Reply With Quote
  #20  
Old 30/08/2015
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Nota de última hora:

Al ver el código, subí una versión en la que comenté una línea para hacer pruebas, se debe "descomentar" para ganar algo de velocidad. Esta es la parte del código:
Código Delphi [-]
               if WriteProcessMemory(hProc, pointer(mbi.BaseAddress + i), NewStr, Size, PDWORD(0)^) then
               begin
                 // Incremento el índice para seguir buscando
       //==>     //i:= i + Size - 1;                 
                 Result:= Result or true;
               end;

Debe quedar así:
Código Delphi [-]
               if WriteProcessMemory(hProc, pointer(mbi.BaseAddress + i), NewStr, Size, PDWORD(0)^) then
               begin
                 // Incremento el índice para seguir buscando
                 i:= i + Size - 1;
                 Result:= Result or true;
               end;


Saludos.
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
programa residente en memoria elcigarra OOP 5 28/04/2008 18:39
Buscando programa de cadetil Novás Varios 1 01/11/2006 12:23
programa residente en memoria Jorge Ramirez Varios 1 25/04/2004 06:10
Programa residente en memoria naker Varios 2 10/11/2003 00:35
Programa de Consola en memoria.... jcgarcia Varios 2 04/06/2003 02:05


All times are GMT +2. The time now is 14:03.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi