Delphi Pages Forums  

Go Back   Delphi Pages Forums > Delphi Forum > General

Lost Password?

Reply
 
Thread Tools Display Modes
  #1  
Old 02-11-2017, 03:27 AM
Luiz Eduardo Luiz Eduardo is offline
Junior Member
 
Join Date: May 2014
Posts: 27
Default Restorer api ( inline hook ) don't unhooks, but executes normally

After several day of work, finally today i have a complete and compilable of a Delphi version of a "Restorer inline hooks" based in this answer of @RbMm, made with Native api.

Well, the code below is compiling very fine and was tested in console mode and all lines are executed with success, but not unhooks api when tested with a rootkit making a inline hook on my executable, nothing happens.

Code:
library pfnUnhook; 

uses 
  Winapi.Windows, 
  System.SysUtils, 
  System.Classes, 
  NtDll, // http://pastebin.com/FYiNjEBh
  ntdll_; // http://pastebin.com/zJuaJzBB 

{$R *.res} 

var 
  ByteOffset: LARGE_INTEGER = (); 
  hmod: HMODULE = 0; 

const 
  _MAX_OBJECT_NAME = 1024 div SizeOf(WCHAR); 

type 

  { .: MEMORY_MAPPED_FILE_NAME_INFORMATION  :. } 

  _MEMORY_MAPPED_FILE_NAME_INFORMATION = record 
    Name: TNtUnicodeString; 
    Buffer: array [0 .. _MAX_OBJECT_NAME - 1] of WCHAR; 
  end; 

  MEMORY_MAPPED_FILE_NAME_INFORMATION = _MEMORY_MAPPED_FILE_NAME_INFORMATION; 
  TMemoryMappedFileNameInfo = MEMORY_MAPPED_FILE_NAME_INFORMATION; 
  PMemoryMappedFileNameInfo = ^TMemoryMappedFileNameInfo; 

  { .: MEMORY_INFORMATION_CLASS  :. } 

  _MEMORY_INFORMATION_CLASS = (MemoryBasicInformation, MemoryWorkingSetList, 
    MemoryMappedFilenameInformation, MemorySectionName, 
    MemoryBasicVlmInformation); 
  MEMORY_INFORMATION_CLASS = _MEMORY_INFORMATION_CLASS; 
  TMemoryInformationClass = MEMORY_INFORMATION_CLASS; 
  PMemoryInformationClass = ^TMemoryInformationClass; 

  /// //////////////////////////////////////////////////////////////////////////// 

function RtlAddressInSectionTable(NtHeaders: PImageNtHeaders32; Base: Pointer; 
  Rva: ULONG): Pointer; stdcall; 
  external 'ntdll.dll' name 'RtlAddressInSectionTable'; 

function RtlPointerToOffset(B, P: Pointer): ULONG; 
begin 
  Result := ULONG(NativeUInt(P) - NativeUInt(B)); 
end; 

procedure UnhookPfn(pfn: Pointer); 
const 
  OBJ_CASE_INSENSITIVE = $00000040; 
  NtCurrentProcess = THandle(-1); 
  FILE_SHARE_VALID_FLAGS = $00000007; 
var 
  pinth: PImageNtHeaders32; 
  fni: TMemoryMappedFileNameInfo; 
  rcb: SIZE_T; 
  hFile: THandle; 
  iosb: TIoStatusBlock; 
  oa: TNtObjectAttributes; 
  buf: array [0 .. 15] of Byte; 
  OldProtect: ULONG; 

begin 

  if ((RtlPcToFileHeader(pfn, @hmod)) <> (NtNotImplementedPointer)) then 
  begin 

    FillChar(buf[0], length(buf), 0);

    pinth := nil;
    pinth := RtlImageNtHeader(hmod);

    if Assigned(pinth) then

    FillChar(fni, SizeOf(fni), #0); 
    fni.Name.Buffer := fni.Buffer; 
    fni.Name.Length := 0; 
    fni.Name.MaximumLength := SizeOf(fni.Buffer); 

    if (0 <= NtQueryVirtualMemory(NtCurrentProcess, Pointer(hmod), 
      Integer(MemoryMappedFilenameInformation), @fni, 
       SizeOf(fni), @rcb)) then 

      InitializeObjectAttributes(@oa, @fni.Name, OBJ_CASE_INSENSITIVE, 0, nil); 

    if (0 <= NtOpenFile(hFile, FILE_GENERIC_READ, oa, iosb, 
      FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT)) then 

      ByteOffset.QuadPart := ULONG_PTR(RtlAddressInSectionTable(pinth, nil, 
        RtlPointerToOffset(Pointer(hmod), pfn))); 

    if ((ByteOffset.LowPart > 0) and (ByteOffset.HighPart = 0)) then 

      if (0 <= NtReadFile(hFile, 0, nil, nil, iosb, @buf, SizeOf(buf), 
        @ByteOffset, nil)) then 

        if (CompareMem(pfn, @buf, iosb.Information)) then 

          if (VirtualProtect(pfn, SizeOf(buf), PAGE_EXECUTE_READWRITE, 
            @OldProtect)) then 

            Move(pfn, buf, iosb.Information); 

    if (OldProtect <> PAGE_EXECUTE_READWRITE) then 

      VirtualProtect(pfn, SizeOf(buf), OldProtect, @OldProtect); 

  if (hFile > 0) then
   NtClose(hFile);
  end; 
end; 

{ ::: Usage ::: } 

Procedure ThreadFunction; 
var 
  BitBltAddr: Pointer; 
begin 
  hmod := GetModuleHandle('Gdi32.dll'); 
  BitBltAddr := GetProcAddress(hmod, 'BitBlt'); 
    UnhookPfn(BitBltAddr); 
end; 

procedure Execution; 
var 
  ThreadId: Cardinal; 
begin 
  CreateThread(nil, 0, @ThreadFunction, nil, 0, ThreadId); 
end; 

procedure mydllproc(Reason: Integer); 
begin 
  case Reason of 
    DLL_PROCESS_ATTACH: 
      begin 
        Execution; 
      end; 
  end; 
end; 

begin 
  DllProc := mydllproc; 
  mydllproc(DLL_PROCESS_ATTACH); 

end.
Someone can help please?

PS: compiled with Delphi XE5

Last edited by Luiz Eduardo; 02-11-2017 at 05:52 PM.
Reply With Quote
Reply

Thread Tools
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

BB code is On
Smilies are On
[IMG] code is On
HTML code is On

Forum Jump


All times are GMT. The time now is 07:15 AM.


Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2017, vBulletin Solutions, Inc.