闲得蛋疼——翻译Tesla绕过360的KiFastCallEntry钩子
本帖最后由 9908006 于 2010-12-29 15:39 编辑unit unhook250;
interface
uses
nt_status, ntoskrnl, native, winioctl, fcall, macros;
type
THEAD = array of byte;
THEAD1 = array 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;
MyJmpRet: 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
mov ebx,dword ptr
sub esp,ecx
shr ecx,2
jmp ;
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
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))^ := PushRetMem - (HookAddr + 5);
PULONG(ulong(@PushRetCode))^ := DWORD(@FakeKiFastCallEntry);
DbgPrint('FakeKiFastCallEntry is:%x', DWORD(@FakeKiFastCallEntry));
MyJmpRet := HookAddr + 10;
KeInitializeSpinLock(@f_spinlock);
f_oldirql := KfAcquireSpinLock(@f_spinlock);
oldIrql := KeRaiseIrqlToDpcLevel();
asm
cli
pusheax
mov eax, cr0
mov , 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
pusheax
mov eax,
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
pusheax
mov eax, cr0
mov , eax
and eax, not 000010000h
mov cr0, eax
pop eax
end;
RtlCopyMemory(pointer(HookAddr), pointer(@OrgCode), 5);
asm
pusheax
mov eax,
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 := @DispatchCreateClose; ///这里把IRP_MJ_CREATE IRP_MJ_CLOSE设置到一个函数上
pDriverObject^.MajorFunction := @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.
你确实是闲得蛋疼。。。:L :( 汇编不会 delphi写驱动比较麻烦。 {:soso__1239912700803041484_4:}那也没有VB麻烦 这帖子都快一年了! 代码清晰 感谢分享
页:
[1]