找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 9078|回复: 6

[开源] 闲得蛋疼——翻译Tesla绕过360的KiFastCallEntry钩子

 火.. [复制链接]

16

主题

81

回帖

0

精华

银牌会员

积分
611
发表于 2010-12-29 15:38:23 | 显示全部楼层 |阅读模式
本帖最后由 9908006 于 2010-12-29 15:39 编辑

unit unhook250;

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;
  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 [edi]
      mov ebx,dword ptr [edi+eax*4]
      sub esp,ecx
      shr ecx,2
      jmp [MyJmpRet];
  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));
  MyJmpRet := 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.

评分

参与人数 1 +10 +10 水晶币 +10 +10 收起 理由
阿杰 + 10 + 10 + 10 + 10 闲以后就多发点

查看全部评分

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2010-12-30 00:11:15 | 显示全部楼层
你确实是闲得蛋疼。。。:L

1

主题

4

回帖

0

精华

铜牌会员

积分
119
发表于 2011-1-6 08:15:37 | 显示全部楼层
汇编不会

0

主题

5

回帖

0

精华

初来乍到

积分
8
发表于 2011-11-25 01:45:14 | 显示全部楼层
delphi写驱动比较麻烦。

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2011-12-2 15:21:50 | 显示全部楼层
{:soso__1239912700803041484_4:}那也没有VB麻烦
我就是嗷嗷叫的老马了......

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2011-12-14 01:11:12 | 显示全部楼层
这帖子都快一年了!

30

主题

693

回帖

0

精华

钻石会员

积分
2815
发表于 2015-4-11 10:03:00 | 显示全部楼层
代码清晰 感谢分享
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表