Вот такой, с вас пиво :
| Код | function GetActualAddr(Proc: Pointer): Pointer; type PAbsoluteIndirectJmp = ^TAbsoluteIndirectJmp; TAbsoluteIndirectJmp = packed record OpCode: Word; //$FF25(Jmp, FF /4) Addr: Cardinal; end; var J: PAbsoluteIndirectJmp; P: PPointer; begin J := PAbsoluteIndirectJmp(Proc); if (J.OpCode = $25FF) then begin {$ifdef Win32} P := PPointer(J.Addr); {$endif} {$ifdef Win64} P := PPointer(TNativeUInt(Proc) + J.Addr + 6{Instruction Size}); {$endif} if IsBadReadPtr(P, SizeOf(NativeUInt)) then Exit(nil); Result := P^; end else Result := Proc; end;
function HookCode(PEModule: HModule; Recursive: Boolean; TargetAddress, NewAddress: Pointer; var OldAddress: Pointer): Integer; var HookedModules: string;
function HookModule(ImageDosHeader: PImageDosHeader; TargetAddress, NewAddress: Pointer; var OldAddress: Pointer): Integer; var Address: Pointer; ImportCode: ^Pointer; BytesWritten: NativeUInt; ImageNTHeaders: PImageNTHeaders; ImageImportEntry: ^TImageImportEntry; Module: string; OldProtect: Cardinal; ModuleHandle: HModule; begin Result := 0;
if OldAddress = nil then OldAddress := GetActualAddr(TargetAddress);
//check the header and see if there is one, if there isn't then exit hook routine If ImageDosHeader.e_magic <> IMAGE_DOS_SIGNATURE then Exit; //Loads the API headers into ImageNTHeaders ImageNTHeaders := Pointer(NativeInt(ImageDosHeader) + ImageDosHeader._lfanew);
//checks if there are API header? (I think) If ImageNTHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = 0 then Exit; //Gets just the API header addresses? (I think) ImageImportEntry := Pointer(NativeUInt(ImageDosHeader) + ImageNTHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
//Loops through each API header looking for the name you specified ready to patch! while ImageImportEntry^.Name <> 0 do begin //If its found then go into Module := string(AnsiString(PAnsiChar(NativeUInt(ImageDosHeader) + ImageImportEntry^.Name)));
if Recursive then if Pos(LowerCase(Module), HookedModules) = 0 then begin //Writes the redirection of API HookedModules := HookedModules + LowerCase(Module); ModuleHandle := GetModuleHandle(PWideChar(Module)); if (ModuleHandle > 0) and (ImageDosHeader <> Pointer(ModuleHandle)) then HookModule(Pointer(ModuleHandle), TargetAddress, NewAddress, OldAddress); end;
//Sets the Address of the Table? ImportCode := Pointer(NativeUInt(ImageDosHeader) + ImageImportEntry.LookupTable);
//TODO: remove magic constant while (ImportCode^ <> nil) and (NativeUInt(ImportCode^) > 4) do begin Address := ImportCode^;
if Address <> OldAddress then Address := GetActualAddr(Address);
//checks address and writes our one! if Address = OldAddress then begin if VirtualProtect(ImportCode, SizeOf(Pointer), PAGE_EXECUTE_READWRITE, OldProtect) then begin if WriteProcessMemory(GetCurrentProcess, ImportCode, @NewAddress, SizeOf(Pointer), BytesWritten) then begin //x64_test CloseHandle(FileCreate('d:\dbg\' + IntToStr(NativeUInt(ImportCode)))); VirtualProtect(ImportCode, SizeOf(Pointer), OldProtect, @OldProtect); FlushInstructionCache(GetCurrentProcess, ImportCode, SizeOf(Pointer)); Inc(Result); end; end; end;
//increment the importcode until it finds the correct address Inc(ImportCode); end;
//keep stepping thru each API Header Inc(ImageImportEntry); end; end;
begin Result := 0; if PEModule > 0 then Result := HookModule(Pointer(PEModule), TargetAddress, NewAddress, OldAddress); end;
|
|