Cita:
Empezado por deliriun
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;
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;
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
T:= nBytesRead - Size - nBytesRead mod Size;
i:= 0;
while i <= T do
begin
if _StrCmpNIW(PWCHAR(Buffer+i), Str, Len) = 0 then
begin
if WriteProcessMemory(hProc, pointer(mbi.BaseAddress + i), NewStr, Size, PDWORD(0)^) then
begin
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.