{
NtOpenProcess[SSDT Hook] By Anskya
Email: Anskya[at]Gmail.com
Web: www[dot]eviloctal[dot]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;
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;
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);
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;
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));
function _DriverEntry(DriverObject:PDriverObject;RegistryPath:PUnicodeString): NTSTATUS; stdcall;
begin
DriverObject^.DriverUnload := @DriverUnload;
Result := STATUS_SUCCESS;
DbgPrint('DriverEntry(-):0x%.8X', Result);
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;
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;
BusQueryDeviceID = 0; // <Enumerator>\<Enumerator-specific device id>
BusQueryHardwareIDs = 1; // Hardware ids
BusQueryCompatibleIDs = 2; // compatible device ids
BusQueryInstanceID = 3; // persistent id for this instance of the device
BusQueryDeviceSerialNumber = 4; // serial number for this device
//
// types are very important,
// because we want to code drivers in Delphi we use we use Delphi style
// of types, but also we want to have some code compatibility so we implement
// also WinAPI (C) style of types
//
type
LONG=Integer;
PLONG=^LONG;
ULONG=Cardinal;
DWORD=Cardinal;
PULONG=^ULONG;
NTSTATUS=ULONG;
LCID=ULONG;
TDeviceType=ULONG;
DEVICE_TYPE=TDeviceType;
TKProcessorMode=Byte;
KPROCESSOR_MODE=TKProcessorMode;
TKIrql=Byte;
KIRQL=TKIRQL;
PEThread=Pointer;
PEProcess=Pointer;
PKThread=Pointer; //PKTHREAD
PHandle=^THandle;
TAccessMask=ULONG;
PUnicodeString=^TUnicodeString;
TUnicodeString=packed record
Length:Word;
MaximumLength:Word;
Buffer:PWideChar;
end;
UNICODE_STRING=TUnicodeString;
PUNICODE_STRING=^UNICODE_STRING;
PLargeInteger=^TLargeInteger;
TLargeInteger=packed record
LowPart:Cardinal;
HighPart:Integer;
end;
TIrpUnionAssociatedIrp=packed record
case Byte of
0:(MasterIrp:PIrp);
1:(IrpCount:Cardinal);
2:(SystemBuffer:Pointer);
end;
PIoStatusBlock=^TIoStatusBlock;
TIoStatusBlock=packed record
Status:NTSTATUS;
Information:Cardinal; //ULONG_PTR
end;
IO_STATUS_BLOCK=TIoStatusBlock;
PIO_STATUS_BLOCK=^IO_STATUS_BLOCK;
TIrpUnionOverlayStructAsynchronousParameters=packed record
UserApcRoutine:Pointer; //PIO_APC_ROUTINE
UserApcContext:Pointer;
end;
TIrpUnionOverlay=packed record
case Byte of
0:(AsynchronousParameters:TIrpUnionOverlayStructAsynchronousParameters);
1:(AllocationSize:TLargeInteger);
end;
TIrpUnionTailStructOverlayUnion1=packed record
case Byte of
0:(DeviceQueueEntry:TKDeviceQueueEntry);
1:(DriverContext:array[0..3] of Pointer);
end;
TIrpUnionTailStructOverlayStruct1Union1=packed record
case Byte of
0:(CurrentStackLocation:Pointer); //PIO_STACK_LOCATION
1:(PacketType:Cardinal);
end;
TIrpUnionTailStructOverlayStruct1=packed record
ListEntry:TListEntry;
u1:TIrpUnionTailStructOverlayStruct1Union1;
end;
TIrpUnionTailStructOverlay=packed record
u1:TIrpUnionTailStructOverlayUnion1;
Thread:PEThread;
AuxiliaryBuffer:PChar;
s1:TIrpUnionTailStructOverlayStruct1;
OriginalFileObject:Pointer; //PFILE_OBJECT
end;
TIrpUnionTail=packed record
case Byte of
0:(Overlay:TIrpUnionTailStructOverlay);
1:(Apc:TKApc);
2:(CompletionKey:Pointer);
end;
PPowerState=^TPowerState;
TPowerState=packed record
case Byte of
0:(SystemState:TSystemPowerState);
1:(DeviceState:TDevicePowerState);
end;
POWER_STATE=TPowerState;
PPOWER_STATE=^POWER_STATE;
TIoStackLocationUnionParametersStructCreate=packed record
SecurityContext:Pointer; //PIO_SECURITY_CONTEXT
Options:Cardinal;
FileAttributes:Word;
ShareAccess:Word;
EaLength:Cardinal;
end;
TIoStackLocationUnionParametersStructRead=packed record
Length:Cardinal;
Key:Cardinal;
ByteOffset:TLargeInteger;
end;
TIoStackLocationUnionParametersStructWrite=packed record
Length:Cardinal;
Key:Cardinal;
ByteOffset:TLargeInteger;
end;
TIoStackLocationUnionParametersStructQueryFile=packed record
Length:Cardinal;
FileInformationClass:TFileInformationClass;
end;
TIoStackLocationUnionParametersStructSetFile=packed record
Length:Cardinal;
FileInformationClass:TFileInformationClass;
FileObject:PFileObject;
case Byte of
0:(ReplaceIfExists:Boolean;
AdvanceOnly:Boolean);
1:(CluserCount:Cardinal);
2:(DeleteHandle:THandle);
end;
TIoStackLocationUnionParametersStructQueryVolume=packed record
Length:Cardinal;
FsInformationClass:TFsInformationClass;
end;
TIoStackLocationUnionParametersStructDeviceIoControl=packed record
OutputBufferLength:Cardinal;
InputBufferLength:Cardinal;
IoControlCode:Cardinal;
Type3InputBuffer:Pointer;
end;
TIoStackLocationUnionParametersStructMountVolume=packed record
DoNotUse1:Pointer;
DeviceObject:PDeviceObject;
end;
TIoStackLocationUnionParametersStructVerifyVolume=packed record
DoNotUse1:Pointer;
DeviceObject:PDeviceObject;
end;
TIoStackLocationUnionParametersStructScsi=packed record
Srn:Pointer; //_SCSI_REQUEST_BLOCK *
end;
TIoStackLocationUnionParametersStructQueryDeviceRelations=packed record
drType:TDeviceRelationType;
end;
TIoStackLocationUnionParametersStructDeviceCapabilities=packed record
Capabilities:Pointer; //PDEVICE_CAPABILITIES
end;
TIoStackLocationUnionParametersStructFilterResourceRequirements=packed record
IoResourceRequirementList:Pointer; //PIO_RESOURCE_REQUIREMENTS_LIST
end;
TIoStackLocationUnionParametersStructReadWriteConfig=packed record
WhichSpace:Cardinal;
Buffer:Pointer;
Offset:Cardinal;
Length:Cardinal;
end;
TIoStackLocationUnionParametersStructSetLock=packed record
Lock:LongBool;
end;
TIoStackLocationUnionParametersStructQueryId=packed record
IdType:TBusQueryIdType;
end;
TIoStackLocationUnionParametersStructQueryDeviceText=packed record
DeviceTextType:TDeviceTextType;
LocaleId:LCID;
end;
TIoStackLocationUnionParametersStructUsageNotification=packed record
InPath:Boolean;
Reserved:array[0..2] of Boolean;
dunType:TDeviceUsageNotificationType;
end;
TIoStackLocationUnionParametersStructWaitWake=packed record
PowerState:TSystemPowerState;
end;
TIoStackLocationUnionParametersStructPowerSequence=packed record
PowerSequence:Pointer; //PPOWER_SEQUENCE
end;
TIoStackLocationUnionParametersStructPower=packed record
SystemContext:Cardinal;
psType:TPowerStateType;
State:TPowerState;
ShutdownType:TPowerAction;
end;
TIoStackLocationUnionParametersStructStartDevice=packed record
AllocatedResources:Pointer; //PCM_RESOURCE_LIST
AllocatedResourcesTranslated:Pointer; //PCM_RESOURCE_LIST
end;
TIoStackLocationUnionParametersStructWMI=packed record
ProviderId:Pointer; //ULONG_PTR
DataPath:Pointer;
BufferSize:Cardinal;
Buffer:Cardinal;
end;
TIoStackLocationUnionParametersStructOthers=packed record
Argument1:Pointer;
Argument2:Pointer;
Argument3:Pointer;
Argument4:Pointer;
end;
function DbgPrint(Format:PChar): NTSTATUS; cdecl; varargs; external NtKernel name 'DbgPrint';
function KeServiceDescriptorTable(): PServiceDescriptorEntry; external NtKernel name '_KeServiceDescriptorTable';
function xInterlockedExchange(Target: PLONG; Value: LONG): LONG; stdcall;
function IoCreateDevice(DriverObject:PDriverObject;DeviceExtensionSize:Cardinal;DeviceName:PUnicodeString;DeviceType:TDeviceType;DeviceCharacteristics:Cardinal;Reserved:Boolean;var DeviceObject:PDeviceObject):NTSTATUS; stdcall; external NtKernel name 'IoCreateDevice';
procedure IoCompleteRequest(Irp:PIrp;PriorityBoost:Integer); stdcall; external NtKernel name 'IoCompleteRequest';
procedure IoDeleteDevice(DeviceObject:PDeviceObject); stdcall; external NtKernel name 'IoDeleteDevice';
function IoCreateSymbolicLink(SymbolicLinkName,DeviceName:PUnicodeString):NTSTATUS; stdcall; external NtKernel name 'IoCreateSymbolicLink';
function IoDeleteSymbolicLink(SymbolicLinkName:PUnicodeString):NTSTATUS; stdcall; external NtKernel name 'IoDeleteSymbolicLink';
procedure RtlInitUnicodeString(DestinationString:PUnicodeString;SourceString:PWideChar); stdcall; external NtKernel name 'RtlInitUnicodeString';
function ZwOpenProcess(ProcessHandle:PHandle;DesiredAccess:TAccessMask;ObjectAttributes:PObjectAttributes;ClientId:PClientId):NTSTATUS; stdcall; external NtKernel name 'ZwOpenProcess';
procedure ProbeForRead(Address:Pointer;Length:Cardinal;Alignment:Cardinal); stdcall; external NtKernel name 'ProbeForRead';
procedure ExFreePool(P:Pointer); stdcall; external NtKernel name 'ExFreePool';
function KeWaitForSingleObject(SObject:Pointer;WaitReason:TKWaitReason;WaitMode:TKProcessorMode;Alertable:LongBool;Timeout:PLargeInteger):NTSTATUS; stdcall; external NtKernel name 'KeWaitForSingleObject';
function ExAllocatePool(PoolType:TPoolType;NumberOfBytes:Cardinal):Pointer; stdcall; external NtKernel name 'ExAllocatePool';
function ExAllocatePoolWithQuota(PoolType:TPoolType;NumberOfBytes:Cardinal):Pointer; stdcall; external NtKernel name 'ExAllocatePoolWithQuota';
function ExAllocatePoolWithTag(PoolType:TPoolType;NumberOfBytes:Cardinal;Tag:ULONG):Pointer; stdcall; external NtKernel name 'ExAllocatePoolWithTag';
procedure KeInitializeMutex(Mutex:PKMutex;Level:Cardinal); stdcall; external NtKernel name 'KeInitializeMutex';
function KeReleaseMutex(Mutex:PKMutex;Wait:LongBool):LONG; stdcall; external NtKernel name 'KeReleaseMutex';
implementation
function InterlockedExchange(Target:PLONG; Value:LONG):LONG; register; external NtKernel name 'InterlockedExchange';
function xInterlockedExchange(Target: PLONG; Value: LONG): LONG; stdcall;
asm
mov ecx, Target
mov edx, Value
call InterlockedExchange
end;