A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #3480  by STRELiTZIA
 Sun Nov 14, 2010 7:54 am
Hello,

[Delphi] LoadDriver SSDT Hook.
Compile it with Meerlat 1.1 (See http://www.kernelmode.info/forum/viewto ... 65&start=0)
Use DbgView to catch informations.
Only for Windows XP.

Delphi project link: hxxp://www.mediafire.com/?klfd7ozqliawq6f

Code: Select all
unit ZwLoadDriverHook;

interface

uses
  nt_status,
  ntoskrnl,
  fcall,
  KernelUtils,
  NtoskrnlCustom;

function _DriverEntry(
  DriverObject: PDriverObject;
  RegistryPath: PUnicodeString
  ): NTSTATUS; stdcall;

implementation
type
  TZwLoadDriver = function(DriverServiceName: PUnicodeString): NTSTATUS; stdcall;
var
  HookActive: Boolean;
  ZwLoadDriverNextHook: TZwLoadDriver;

function ZwLoadDriverHookProc(DriverServiceName: PUnicodeString): NTSTATUS; stdcall;
begin
  DbgPrint('Driver service name :%wZ', DriverServiceName);
  Result := ZwLoadDriverNextHook(DriverServiceName);
end;

procedure DriverUnload(DriverObject: PDriverObject); stdcall;
begin
  if HookActive then
  begin
    ZwLoadDriverNextHook := TZwLoadDriver(InterlockedExchange(SystemServiceName(GetImportFunAddr(@ZwLoadDriver)), LONG(@ZwLoadDriverNextHook)));
    DbgPrint('ZwLoadDriver New Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwLoadDriver))^);
    DbgPrint('ZwLoadDriver Old Address: 0x%.8X', DWORD(@ZwLoadDriverNextHook));

    HookActive := False;
  end;
  DbgPrint('DriverUnload(-)');
end;

function _DriverEntry(DriverObject: PDriverObject; RegistryPath: PUnicodeString): NTSTATUS; stdcall;
begin
  DriverObject^.DriverUnload := @DriverUnload;
  Result := STATUS_SUCCESS;
  DbgPrint('DriverEntry(-):0x%.8X', Result);
  HookActive := False;

  DbgPrint('ZwLoadDriver Import Address: 0x%.8X', GetImportFunAddr(@ZwLoadDriver));
  DbgPrint('KeServiceDescriptorTable() Address 1: 0x%.8X', @KeServiceDescriptorTable);
  DbgPrint('KeServiceDescriptorTable() Address 2: 0x%.8X', PPointer(@KeServiceDescriptorTable)^);

  DbgPrint('ZwLoadDriver Ord Address: 0x%.8X', SystemServiceOrd($7A)^); //  XP Ord!
  DbgPrint('ZwLoadDriver Name Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwLoadDriver))^);

  DbgPrint('ZwLoadDriver HookProc Address: 0x%.8X', @ZwLoadDriverHookProc);

  if not HookActive then
  begin
    ZwLoadDriverNextHook := TZwLoadDriver(InterlockedExchange(SystemServiceName(GetImportFunAddr(@ZwLoadDriver)), LONG(@ZwLoadDriverHookProc)));

    DbgPrint('ZwLoadDriver New Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwLoadDriver))^);
    DbgPrint('ZwLoadDriver Old Address: 0x%.8X', DWORD(@ZwLoadDriverNextHook));

    HookActive := True;
  end else
  begin
    DbgPrint('ZwLoadDriver Hooked');
  end;
end;
end.
Code: Select all
unit KernelUtils;

interface

uses
  nt_status,
  ntoskrnl;

function SystemServiceName(AFunc: Pointer): PLONG; stdcall;
function GetImportFunAddr(lpImportAddr: Pointer): Pointer; stdcall;
function SystemServiceOrd(iOrd: ULONG): PLONG; stdcall;

implementation

function GetImportFunAddr(lpImportAddr: Pointer): Pointer; stdcall;
begin
  Result := PPointer(PPointer(Cardinal(lpImportAddr) + 2)^)^;
end;

function SystemServiceName(AFunc: Pointer): PLONG; stdcall;
var lpKeServiceDescriptorTable: PServiceDescriptorEntry;
begin
  lpKeServiceDescriptorTable := GetImportFunAddr(@KeServiceDescriptorTable);
  Result := PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * PULONG(ULONG(AFunc) + 1)^));
end;

function SystemServiceOrd(iOrd: ULONG): PLONG; stdcall;
var lpKeServiceDescriptorTable: PServiceDescriptorEntry;
begin
  lpKeServiceDescriptorTable := GetImportFunAddr(@KeServiceDescriptorTable);
  Result := PLONG(PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * iOrd)));
end;
end. 
Regards.
 #3562  by STRELiTZIA
 Thu Nov 18, 2010 6:37 pm
Hi,

ZwOpenProcess Hook
Compile it with Meerlat 1.1 (http://www.kernelmode.info/forum/viewto ... f=14&t=465)
Use DbgView to catch informations.
Delphi project link: hxxp://www.mediafire.com/?9cm3eemyry34qzt
Code: Select all
{*******************************************************}
{       Open source sample.                             }
{       Free to use.                                    }
{       Compile it with Meerkat GUI for KmdKit4D.       }
{*******************************************************}

{*******************************************************}
{       Meerkat KmdKit4D Advanced GUI. c)2010.          }
{       Slug Analysis Lab (STRELiTZIA's Blog)           }
{       http://www.sluganalysislab.blogspot.com         }
{*******************************************************}

unit ZwOpenProcessHook;

interface

uses
  nt_status,
  ntoskrnl,
  fcall,
  KernelUtils;

function _DriverEntry(
  DriverObject: PDriverObject;
  RegistryPath: PUnicodeString
  ): NTSTATUS; stdcall;

implementation

type
  TZwOpenProcess = function(
    ProcessHandle: PHandle;
    DesiredAccess: TAccessMask;
    ObjectAttributes: PObjectAttributes;
    ClientId: PClientId
    ): NTSTATUS; stdcall;
var
  HookActive: Boolean;
  ZwOpenProcessNextHook: TZwOpenProcess;
  lpKeServiceDescriptorTable: PServiceDescriptorEntry;

function ZwOpenProcessHookProc(ProcessHandle: PHandle; DesiredAccess: TAccessMask; ObjectAttributes: PObjectAttributes; ClientId: PClientId): NTSTATUS; stdcall;
begin
  DbgPrint('ZwOpenProcess HookProc: NewZwOpenProcess(ProcessHandle:0x%.8X,DesiredAccess:0x%.8X,ObjectAttributes:0x%.8X,ClientId:0x%.8X)',
    ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);

  Result := ZwOpenProcessNextHook(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
  DbgPrint('ZwOpenProcess HookProc: NewZwOpenProcess(-):0x%.8X', Result);
end;

procedure DriverUnload(DriverObject: PDriverObject); stdcall;
begin
  if (HookActive) then
  begin
    DisableWriteProtection();
    ZwOpenProcessNextHook := TZwOpenProcess(InterlockedExchange(SystemServiceName(GetImportFunAddr(@ZwOpenProcess)), LONG(@ZwOpenProcessNextHook)));
    EnableWriteProtection();

    DbgPrint('ZwOpenProcess New Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwOpenProcess))^);
    DbgPrint('ZwOpenProcess Old Address: 0x%.8X', DWORD(@ZwOpenProcessNextHook));

    HookActive := False;
  end;
  DbgPrint('DriverUnload(-)');
end;

function _DriverEntry(DriverObject: PDriverObject; RegistryPath: PUnicodeString): NTSTATUS; stdcall;
begin
  Result := STATUS_SUCCESS;
  DriverObject^.DriverUnload := @DriverUnload;
  DbgPrint('DriverEntry(-):0x%.8X', Result);
  lpKeServiceDescriptorTable := GetImportFunAddr(@KeServiceDescriptorTable);
  HookActive := False;

  DbgPrint('ZwOpenProcess Import Address: 0x%.8X', GetImportFunAddr(@ZwOpenProcess));
  DbgPrint('KeServiceDescriptorTable() Address 1: 0x%.8X', @KeServiceDescriptorTable);
  DbgPrint('KeServiceDescriptorTable() Address 2: 0x%.8X', PPointer(@KeServiceDescriptorTable)^);

  DbgPrint('ZwOpenProcess Name Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwOpenProcess))^);

  DbgPrint('ZwOpenProcess HookProc Address: 0x%.8X', @ZwOpenProcessHookProc);

  if not HookActive then
  begin
    DisableWriteProtection();
    ZwOpenProcessNextHook := TZwOpenProcess(InterlockedExchange(SystemServiceName(GetImportFunAddr(@ZwOpenProcess)), LONG(@ZwOpenProcessHookProc)));
    EnableWriteProtection();

    DbgPrint('ZwOpenProcess New Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwOpenProcess))^);
    DbgPrint('ZwOpenProcess Old Address: 0x%.8X', DWORD(@ZwOpenProcessNextHook));

    HookActive := True;
  end else
  begin
    DbgPrint('ZwOpenProcess Hooked');
  end;
end;
end.

 
Code: Select all
unit KernelUtils;

interface

uses
  nt_status,
  ntoskrnl;

function SystemServiceName(AFunc: Pointer): PLONG; stdcall;
function GetImportFunAddr(lpImportAddr: Pointer): Pointer; stdcall;
function SystemServiceOrd(iOrd: ULONG): PLONG; stdcall;
procedure EnableWriteProtection(); stdcall;
procedure DisableWriteProtection(); stdcall;

var uCr0: ULONG;
implementation

procedure DisableWriteProtection(); stdcall;
begin
  asm
   cli
   push eax
   mov  eax, cr0
   mov  [uCr0], eax
   and  eax, not 00010000h
   mov  cr0, eax
   pop  eax
  end;
end;

procedure EnableWriteProtection(); stdcall;
begin
  asm
    push eax
    mov  eax, [uCr0]
    mov  cr0, eax
    pop  eax
    sti
  end;
end;

function GetImportFunAddr(lpImportAddr: Pointer): Pointer; stdcall;
begin
  Result := PPointer(PPointer(Cardinal(lpImportAddr) + 2)^)^;
end;

function SystemServiceName(AFunc: Pointer): PLONG; stdcall;
var lpKeServiceDescriptorTable: PServiceDescriptorEntry;
begin
  lpKeServiceDescriptorTable := GetImportFunAddr(@KeServiceDescriptorTable);
  Result := PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * PULONG(ULONG(AFunc) + 1)^));
end;

function SystemServiceOrd(iOrd: ULONG): PLONG; stdcall;
var lpKeServiceDescriptorTable: PServiceDescriptorEntry;
begin
  lpKeServiceDescriptorTable := GetImportFunAddr(@KeServiceDescriptorTable);
  Result := PLONG(PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * iOrd)));
end;
end.
Regards.
Last edited by STRELiTZIA on Thu Nov 18, 2010 6:41 pm, edited 1 time in total.
 #3563  by STRELiTZIA
 Thu Nov 18, 2010 6:41 pm
Hi,
BSODer:To provoke a BSoD (PAGE_FAULT_IN_NONPAGED_AREA) voluntarily.
Compile it with Meerlat 1.1 (http://www.kernelmode.info/forum/viewto ... f=14&t=465)
Use DbgView to catch informations.
Delphi project link: hxxp://www.mediafire.com/?83li9nbbgb9st8q
Code: Select all
{*******************************************************}
{       Open source sample.                             }
{       Free to use.                                    }
{       Compile it with Meerkat GUI for KmdKit4D.       }
{*******************************************************}

{*******************************************************}
{       Meerkat KmdKit4D Advanced GUI. c)2010.          }
{       Slug Analysis Lab (STRELiTZIA's Blog)           }
{       http://www.sluganalysislab.blogspot.com         }
{*******************************************************}
 
unit bsoder;

interface

uses
  ntoskrnl,
  nt_status;
 
function _DriverEntry(
  DriverObject: PDriverObject;
  RegistryPath: PUnicodeString
  ): NTSTATUS; stdcall;

implementation

 // To provoke a BSoD (PAGE_FAULT_IN_NONPAGED_AREA) voluntarily.

function _DriverEntry(DriverObject: PDriverObject; RegistryPath: PUnicodeString): NTSTATUS; stdcall;
begin
 DbgPrint('Yep, I''m Loaded');
 DriverObject^.DriverUnload := Pointer($FFFFFFFF);
 DbgPrint('Invalid pointer affected to "DriverObject^.DriverUnload", now! try to unload me ;)');
 Result := STATUS_SUCCESS;
end;
end.
IDA
.text:000102A0 ; NTSTATUS __stdcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
.text:000102A0 public DriverEntry
.text:000102A0 DriverEntry proc near
.text:000102A0
.text:000102A0 DriverObject = dword ptr 8
.text:000102A0 RegistryPath = dword ptr 0Ch
.text:000102A0
.text:000102A0 push ebp
.text:000102A1 mov ebp, esp
.text:000102A3 push offset Format ; "Yep, I'm Loaded"
.text:000102A8 call DbgPrint
.text:000102AD pop ecx
.text:000102AE mov eax, [ebp+DriverObject]
.text:000102B1 mov dword ptr [eax+34h], 0FFFFFFFFh -//->> Invalid pointer.
.text:000102B8 push offset aInvalidPointer ; "Invalid pointer affected to \"DriverObje"...
.text:000102BD call DbgPrint
.text:000102C2 pop ecx
.text:000102C3 xor eax, eax
.text:000102C5 pop ebp
.text:000102C6 retn 8
.text:000102C6 DriverEntry endp
Regards.
 #3564  by STRELiTZIA
 Thu Nov 18, 2010 6:48 pm
Hi,

ZwTerminateProcess

Compile it with Meerlat 1.1 (http://www.kernelmode.info/forum/viewto ... f=14&t=465)
Use DbgView to catch informations.

Before beginning your tests, please update "NtoskrnlCustom.dcu":
1- UnRAR "include.rar"
2- Copy and replace "NtoskrnlCustom.dcu" into "\Meerkat_Beta1\include\" folder

Delphi project link: hxxp://www.mediafire.com/?l53jedwypmoxsp1
Code: Select all

{*******************************************************}
{       Open source sample.                             }
{       Free to use.                                    }
{       Compile it with Meerkat GUI for KmdKit4D.       }
{*******************************************************}

{*******************************************************}
{       Meerkat KmdKit4D Advanced GUI. c)2010.          }
{       Slug Analysis Lab (STRELiTZIA's Blog)           }
{       http://www.sluganalysislab.blogspot.com         }
{*******************************************************}

unit ZwTerminateProcessTest;

interface

uses
  nt_status,
  ntoskrnl,
  NtoskrnlCustom;

function _DriverEntry(
  DriverObject: PDriverObject;
  RegistryPath: PUnicodeString
  ): NTSTATUS; stdcall;

implementation

function OpenProcess(PID: DWORD): Thandle; stdcall;
var
  ProcessHandle: Thandle;
  ClientId: CLIENT_ID;
  ObjectAttributes: OBJECT_ATTRIBUTES;
begin
  ProcessHandle := 0;

  ObjectAttributes.Length := SizeOf(OBJECT_ATTRIBUTES);
  ObjectAttributes.RootDirectory := 0;
  ObjectAttributes.ObjectName := nil;
  ObjectAttributes.Attributes := 0;
  ObjectAttributes.SecurityDescriptor := nil;
  ObjectAttributes.SecurityQualityOfService := nil;

  ClientId.UniqueProcess := PID;
  ClientId.UniqueThread := 0;

  ZwOpenProcess(
    @ProcessHandle,
    $001F0FFF,
    @ObjectAttributes,
    @ClientId
    );

  Result := ProcessHandle;
end;

procedure DoIt;
var hProcess: Thandle;
begin

  // IMPORTANT: "1064" is Process's ID, Change it with your target Process ID.
  hProcess := OpenProcess(1064);
  if hProcess <> 0 then
  begin
    DbgPrint('OpenProcess: Success -->> Process handle is:0x%X', hProcess);
    if ZwTerminateProcess(hProcess, 0) = 0 then
      DbgPrint('ZwTerminateProcess - Killed')
    else
      DbgPrint('ZwTerminateProcess - Failed');
  end
  else
    DbgPrint('OpenProcess: Failed to get Process handle');

  ZwClose(hProcess);
end;

function _DriverEntry(DriverObject: PDriverObject; RegistryPath: PUnicodeString): NTSTATUS; stdcall;
begin
  DbgPrint('Driver -->> Loaded');
  DoIt;
  DbgPrint('Driver -->> Leaving');
  Result := STATUS_DEVICE_CONFIGURATION_ERROR;
end;
end. 
Regards.
 #3829  by EP_X0FF
 Fri Dec 03, 2010 3:33 pm
Without x64 compiler Delphi in it's current state cannot be taken seriously. Numerous CodeGear studios with stupid additions (for example I want compiler changes, not current idiocy with Forms, NET and BD) almost killed it. Driver development on Delphi is some sort of keen perversion :)
 #3831  by STRELiTZIA
 Fri Dec 03, 2010 6:02 pm
Hi,
Unfortunately it is true,
That it is no real work for x64 and ring0 from Embarcadero, just advertising itself for x64 platform.

The kit is based on Delphi compiler generated objects files format, these files are converted and linked by MS linker.
--- Test.pas file -->> IN
1st step: Delphi compiler (Embarcadero) to generate Object file format.
2ed step: Converted to COFF by rmcoff.exe (mickeylan)
3th step: Linked by MS Linker (Microsoft).
--- Test.sys file -->> OUT

Regards.
 #4284  by juan81
 Wed Jan 05, 2011 3:36 pm
hi,

Sorry noobs question, is there an example delphi source to call a driver which hook open process to openprocess windows application running as services >,<.. ?
i'm still confuse..



Regard.
 #4285  by EP_X0FF
 Wed Jan 05, 2011 3:42 pm
Hello,

if you asked about above posted example of NtOpenProcess hook then you could pay attention - this driver does not have any irp handlers only Unload procedure.

Regards.
 #4287  by STRELiTZIA
 Wed Jan 05, 2011 5:09 pm
juan81 wrote:hi,

Sorry noobs question, is there an example delphi source to call a driver which hook open process to openprocess windows application running as services >,<.. ?
i'm still confuse..
Regard.
Hi,
You must learn better Delphi to understand functions used in these examples.

Attached source of Process Monitor and IO, (Driver and Gui) Delphi sources (by By mickeylan)
also please visite : kmdkit4d - Chinese web site contains all samples (hxxp://www.kmdkit4d.net)

Regards.
Attachments
(660.51 KiB) Downloaded 44 times
(753.59 KiB) Downloaded 47 times