Friday, August 26, 2011

Hook Specials 19 : SSDT Hook For Delphi

Author:Anskya
I simple talk notice for delphi kmd developing.

Watch the code :
1. KeServiceDescriptorTable is specific function......If direct use implib to create library, You will the function uncared-for ......Because offset of the function is 0, It only is flag effect..... on some code

code:
function SystemService(AFunc:Pointer):PLONG;
begin
Result:=PLONG(Cardinal(KeServiceDescriptorTable^.ServiceTableBase)+SizeOf(ULONG)*PULONG(ULONG(AFunc)+1)^);
end;

Because the function border on useless, After the function's code can's be executed.

You can direct use

code:
PPointer(@KeServiceDescriptorTable)^;
Only get the address .

Code:
NtOpenProcess[SSDT Hook] By Anskya
Email: Anskya[at]Gmail.com
}
unit Driver;

interface

uses
ntddk; // ---->DDDK.pas

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;

// 从导入表中获取一个函数的地址
function GetImportFunAddr(lpImportAddr: Pointer): Pointer; stdcall;
begin
Result := PPointer(PPointer(Cardinal(lpImportAddr) + 2)^)^;
end;

// KeServiceDescriptorTable+函数名计算SSDT函数偏移
function SystemServiceName(AFunc: Pointer): PLONG; stdcall;
var
lpKeServiceDescriptorTable: PServiceDescriptorEntry;
begin
lpKeServiceDescriptorTable := PPointer(@KeServiceDescriptorTable)^;
Result := PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * PULONG(ULONG(AFunc) + 1)^));
end;

// KeServiceDescriptorTable+序号名计算SSDT函数偏移
function SystemServiceOrd(iOrd: ULONG): PLONG; stdcall;
var
lpKeServiceDescriptorTable: PServiceDescriptorEntry;
begin
lpKeServiceDescriptorTable := PPointer(@KeServiceDescriptorTable)^;
Result := PLONG(PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * iOrd)));
end;

// 钩子过程
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
asm
cli //disable WP bit
push eax
mov eax, cr0 //move CR0 register into EAX
and eax, not 000010000h //disable WP bit
mov cr0, eax //write register back
pop eax
end;

ZwOpenProcessNextHook := TZwOpenProcess(xInterlockedExchange(SystemServiceName(GetImportFunAddr(@ZwOpenProcess)), LONG(@ZwOpenProcessNextHook)));

asm
push eax //enable WP bit
mov eax, cr0 //move CR0 register into EAX
or eax, 000010000h //enable WP bit
mov cr0, eax //write register back
pop eax
sti
end;

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
DriverObject^.DriverUnload := @DriverUnload;
Result := STATUS_SUCCESS;
DbgPrint('DriverEntry(-):0x%.8X', Result);

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 Ord Address: 0x%.8X', SystemServiceOrd($7A)^); // XP Ord!
DbgPrint('ZwOpenProcess Name Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwOpenProcess))^);
DbgPrint('ZwOpenProcess HookProc Address: 0x%.8X', @ZwOpenProcessHookProc);

if (Not HookActive) then
begin
// SSDT Hook
asm //disable WP bit
cli
push eax
mov eax, cr0 //move CR0 register into EAX
and eax, not 000010000h //disable WP bit
mov cr0, eax //write register back
pop eax
end;

//lpNew^ := LONG(lpOld);
ZwOpenProcessNextHook := TZwOpenProcess(xInterlockedExchange(SystemServiceName(GetImportFunAddr(@ZwOpenProcess)), LONG(@ZwOpenProcessHookProc)));

asm
push eax //enable WP bit
mov eax, cr0 //move CR0 register into EAX
or eax, 000010000h //enable WP bit
mov cr0, eax //write register back
pop eax
sti
end;

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!!! By Anskya');
end;

end;

end.

1 comment: