HOOK SSDT AND HOOK Shadow SSDT FOR DELPHI

来源:互联网 发布:微软软件下载中心 编辑:程序博客网 时间:2024/05/20 09:11
 by bujin999

unit Driver;

interface

uses
  nt_status,ntoskrnl,ntutils;

const
  DeviceName = '/Device/360safeBoxA';
  DosDeviceName = '/DosDevices/360safeBoxA';
  IOCTL_HOOK_START      = $0022E000;
  IOCTL_HOOK_STOP        = $0022E004;
  IOCTL_PROTECT_PROCESS  = $0022E200;
  IOCTL_PROTECT_HWND    = $0022E201;
  IOCTL_PROTECT_OTHER    = $0022E204;

var
DosDevName: TUnicodeString;
TempSafeId:Handle=0;
TempSafehandle:Handle=0;

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

implementation

uses hooking;

function hookCreate(ADeviceObject: PDeviceObject; AIrp: PIrp): NTSTATUS; stdcall;
begin
  Result := STATUS_SUCCESS;
  AIrp^.IoStatus.Status := Result;
  IoCompleteRequest(AIrp, IO_NO_INCREMENT);
end;

function hookClose(ADeviceObject: PDeviceObject; AIrp: PIrp): NTSTATUS; stdcall;
begin
  Result := STATUS_SUCCESS;
  AIrp^.IoStatus.Status := Result;
  IoCompleteRequest(AIrp, IO_NO_INCREMENT);
end;


function hookDeviceControl(ADeviceObject: PDeviceObject; AIrp:PIrp): NTSTATUS; stdcall;
var
  LStack: PIO_STACK_LOCATION;
  pIOBuffer: Pointer;
  LBufInLen, LBufOutLen,
  LCode, LRet,OutByteCount: ULONG;
begin
  LStack := IoGetCurrentIrpStackLocation(AIrp);
  Result := STATUS_SUCCESS;
  AIrp^.IoStatus.Information := 0;
  LCode := LStack^.Parameters.DeviceIoControl.IoControlCode;
  pIOBuffer := AIrp^.AssociatedIrp.SystemBuffer;

  LBufInLen := LStack^.Parameters.DeviceIoControl.InputBufferLength;
  LBufOutLen := LStack^.Parameters.DeviceIoControl.OutputBufferLength;
  OutByteCount:=0;

case LCode of
    IOCTL_HOOK_START: begin
      LRet := HookingHook;
      OutByteCount:=4;
      LONG(pIOBuffer^):=LRet;
    end;

    IOCTL_HOOK_STOP: begin
      LRet := HookingUnhook;
      OutByteCount:=4;
      LONG(pIOBuffer^):=LRet;
    end;

    IOCTL_PROTECT_PROCESS: begin
      TempSafeId:=Handle(pIOBuffer^);
      SetSafeId(TempSafeId);
      OutByteCount:=4;
      LONG(pIOBuffer^):=Integer(True);
    end;

    IOCTL_PROTECT_HWND:begin
      TempSafehandle:=Handle(pIOBuffer^);
      SetSafehandle(TempSafehandle);
      OutByteCount:=4;
      LONG(pIOBuffer^):=Integer(True);
    end;

    IOCTL_PROTECT_OTHER: begin
      DoPub;
      OutByteCount:=4;
      LONG(pIOBuffer^):=Integer(True);
    end;
  else
    Result := STATUS_INVALID_DEVICE_REQUEST;
    AIrp^.IoStatus.Information := 0;
  end;

  AIrp^.IoStatus.Status := Result;
  AIrp^.IoStatus.Information := OutByteCount;
  IoCompleteRequest(AIrp, IO_NO_INCREMENT);
end;

procedure DriverUnload(pDriverObject: PDriverObject); stdcall;
begin
  HookingUnhook;
  IoDeleteSymbolicLink(@DosDevName);
  IoDeleteDevice(pDriverObject^.DeviceObject);
end;

function _DriverEntry(pDriverObject: PDriverObject; RegistryPath: PUnicodeString) : NTSTATUS; stdcall;
var
  LDevName: TUnicodeString;
  LDevObj: PDeviceObject;
begin
  RtlInitUnicodeString(LDevName, DeviceName);
  RtlInitUnicodeString(DosDevName, DosDeviceName);

  Result := IoCreateDevice(pDriverObject,0, @LDevName,
                            FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, LDevObj);

  if NT_SUCCESS(Result) then
  begin
    pDriverObject^.MajorFunction[IRP_MJ_CREATE]          := @hookCreate;
    pDriverObject^.MajorFunction[IRP_MJ_CLOSE]          := @hookClose;
    pDriverObject^.MajorFunction[IRP_MJ_DEVICE_CONTROL]  := @hookDeviceControl;
    pDriverObject^.DriverUnload                          := @DriverUnload;

    Result := IoCreateSymbolicLink(@DosDevName, @LDevName);
    if not NT_SUCCESS(Result) then
    begin
        IoDeleteDevice(pDriverObject^.DeviceObject);
    end;
  end;
end;

end.


Copy code
unit hooking;

interface

uses
  nt_status,ntoskrnl,ntutils,ssdthook;

type
  TZwOpenProcess = function(ProcessHandle:PHandle; DesiredAccess:TAccessMask;
                            ObjectAttributes:PObjectAttributes;
                            ClientId:PClientId):NTSTATUS; stdcall;
  TNtUserFindWindowEx= Function (hwndParent,hwndChild:Handle;
                                  pstrClassName,pstrWindowName:PUnicodeString;
                                  dwType:LONG):NTSTATUS;stdcall;
var
  HookActive: Boolean=False;
  OldZwOpenProcess:LONG=0;
  OldNtUserFindWindowEx:LONG=0;
  SafeId:Handle=0;
  SafeHandle:Handle=0;

procedure SetSafeId(value:Handle);
procedure SetSafeHandle(value:Handle);
function HookingHook: Integer; stdcall;
function HookingUnhook: Integer; stdcall;
procedure DoPub;
implementation

procedure SetSafeId(value:Handle);
begin
SafeId:=value;
end;

procedure SetSafeHandle(value:Handle);
begin
SafeHandle:=value;
end;


function  ZwOpenProcessAddr:Pointer;
begin
Result:=GetImportFunAddr(@ZwOpenProcess);
end;


functionNewNtUserFindWindowEx(hwndParent,hwndChild:Handle;pstrClassName,pstrWindowName:PUnicodeString;dwType:LONG):NTSTATUS;stdcall;
begin
  Result:=TNtUserFindWindowEx(pointer(OldNtUserFindWindowEx))(hwndParent,hwndChild,pstrClassName,pstrWindowName,dwType);
  if Result=SafeHandle then Result:=0;
end;

functionNewZwOpenProcess(ProcessHandle:PHandle; DesiredAccess:TAccessMask;ObjectAttributes:PObjectAttributes; ClientId:PClientId):NTSTATUS;stdcall;
var
Temp:Handle;
begin
Temp:=ProcessHandle^;
if Temp=SafeId then
Result:=0
else
Result:=TZwOpenProcess(pointer(OldZwOpenProcess))(ProcessHandle,DesiredAccess,ObjectAttributes, ClientId);
end;


function HookingHook: Integer; stdcall;
var
uCr0cpu:dword;
begin
  if HookActive then
  begin
    Result:=Integer(False);
    Exit;
  end;

  //关闭写保护
  asm
      cli
      push  eax
      mov  eax, cr0
      mov  [uCr0cpu], eax
      and  eax, not 000010000h
      mov  cr0, eax
      pop  eax
  end;
    OldZwOpenProcess:=InterlockedExchange(SystemServiceName(ZwOpenProcessAddr),LONG(@NewZwOpenProcess));
    OldNtUserFindWindowEx:=InterlockedExchange(ShadowSystemServiceOrd($17a),LONG(@NewNtUserFindWindowEx));
  //  打开写保护
  asm
    push  eax
    mov  eax, [uCr0cpu]
    mov  cr0, eax
    pop  eax
    sti
  end;


  HookActive := True;

  Result := Integer(True);
end;


function HookingUnhook: Integer; stdcall;
var
uCr0cpu:dword;
begin
  if not HookActive then
  begin
    Result:=Integer(False);
    Exit;
  end;

  //关闭写保护
  asm
      cli
      push  eax
      mov  eax, cr0
      mov  [uCr0cpu], eax
      and  eax, not 000010000h
      mov  cr0, eax
      pop  eax
  end;

  InterlockedExchange(SystemServiceName(ZwOpenProcessAddr),OldZwOpenProcess);
  InterlockedExchange(ShadowSystemServiceOrd($17a),OldNtUserFindWindowEx);
  //  打开写保护
  asm
    push  eax
    mov  eax, [uCr0cpu]
    mov  cr0, eax
    pop  eax
    sti
  end;

  HookActive := False;

  Result := Integer(True);
end;

procedure DoPub;
begin
  DbgPrint('%08x',ShadowSystemServiceOrd(0));
  DbgPrint('%08x',ShadowSystemServiceOrd(0)^);
end;

end.

为了防止有些人做坏事  只贴一些主要函数出来
Copy code
//  从导入表中获取一个函数的地址
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 := GetImportFunAddr(@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 := GetImportFunAddr(@KeServiceDescriptorTable);
  Result := PLONG(PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * iOrd)));
end;

function FindShadowTable:Pointer;  //XP版本
var
lpKeServiceDescriptorTable:ULONG;
begin
lpKeServiceDescriptorTable := ULONG(GetImportFunAddr(@KeServiceDescriptorTable));
Result:=Pointer(lpKeServiceDescriptorTable-$40);
end;

function FindShadowTable2:Pointer;
var
cPtr, pOpcode:ULONG;
I:ULONG;
begin
  Result:=nil;
  cPtr:=ULONG(GetImportFunAddr(@KeAddSystemServiceTable));
  I:=cPtr;
  While (I<(cPtr+$1000)) Do
  begin
    if MmIsAddressValid(Pointer(I)) then
    begin
      if word(pointer(I)^)=$888d then
      begin
      Result:=PPointer(I+2)^;
      break
      end;
    end;
    I:=I+1;
  end;
end;

//序号名计算Shadow SSDT函数偏移
function ShadowSystemServiceOrd(iOrd: ULONG): PLONG; stdcall;
var
  lpKeServiceDescriptorTable:PShadowSrvDescriptorEntry;
begin
  lpKeServiceDescriptorTable :=FindShadowTable2;
  Result := PLONG(Cardinal(lpKeServiceDescriptorTable^.win32kTable.ServiceTableBase) + (SizeOf(ULONG) * iOrd));
end;
原创粉丝点击