Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Code that restores a hooked api ( inline hooked ) don't works. Why?



Permlink Replies: 0 Threads: [ Previous | Next ]
Francisco camilo

Posts: 1
Registered: 3/12/17
Code that restores a hooked api ( inline hooked ) don't works. Why?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 12, 2017 9:49 AM
Hello,

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

http://stackoverflow.com/a/41928417/6401656

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.

Someone can help please?

Here is my 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.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02