Ver Mensaje Individual
  #19  
Antiguo 30-08-2015
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Reputación: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Cita:
Empezado por deliriun Ver Mensaje
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.

Última edición por Casimiro Notevi fecha: 30-08-2015 a las 20:01:21.
Responder Con Cita