function PatchAddress(OldFunc, NewFunc: Pointer): integer;
var
BeenDone: TList;
function PatchAddressInModule(hModule: THandle; OldFunc, NewFunc: Pointer): integer;
var
Dos: PImageDosHeader;
NT: PImageNTHeaders;
ImportDesc: PImage_Import_Entry;
rva: DWORD;
Func: PPointer;
DLL:
string;
f: Pointer;
written: DWORD;
begin
Result := 0;
Dos := Pointer(hModule);
if BeenDone.IndexOf(Dos) >= 0
then Exit;
BeenDone.Add(Dos);
OldFunc := FinalFunctionAddress(OldFunc);
if IsBadReadPtr(Dos, SizeOf(TImageDosHeader))
then Exit;
if Dos.e_magic <> IMAGE_DOS_SIGNATURE
then Exit;
NT := Pointer(integer(Dos) + dos._lfanew);
// if IsBadReadPtr(NT,SizeOf(TImageNtHeaders)) then exit;
RVA := NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
if RVA = 0
then Exit;
ImportDesc := Pointer(integer(Dos) + RVA);
while (ImportDesc^.
Name <> 0)
do
begin
DLL := PChar(integer(Dos) + ImportDesc^.
Name);
PatchAddressInModule(GetModuleHandle(PChar(
DLL)), OldFunc, NewFunc);
Func := Pointer(integer(DOS) + ImportDesc.LookupTable);
while Func^ <>
nil do
begin
f := FinalFunctionAddress(Func^);
if f = OldFunc
then
begin
WriteProcessMemory(GetCurrentProcess, Func, @NewFunc, 4, written);
if Written > 0
then Inc(Result);
end;
Inc(Func);
end;
Inc(ImportDesc);
end;
end;
begin
BeenDone := TList.Create;
try
Result := PatchAddressInModule(GetModuleHandle(
nil), OldFunc, NewFunc);
finally
BeenDone.Free;
end;
end;