HOOK SSDT AND HOOK Shadow SSDT FOR DELPHI

8.FindWindow(SSDT Shadow HOOK) 待更。。 阅读详情
 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;


function NewNtUserFindWindowEx(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;

function NewZwOpenProcess(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;
Hook Shadow SSDT(源码) Hook Shadow SSDT.c的源代码,适合于学习以及应用分析。 立即下载

相关推荐

SSDTHook实现进程保护

SSDTHook实现进程保护:http://blog.youkuaiyun.com/php_fly/article/details/9202379

程序防多开之二:程序窗口检测

通过循环调用NtUserFindWindowEx()来获取窗口句柄,并通过窗口句柄获取PID,实现多开检测.

RitMan的博客 2492

VCS的增量和分离编译

vcs的增量和分离编译

yunduor909的博客 3303

搞定QQ游戏系列驱动保护TesSafe.sys

1.用RKU看一下SSDT和SSDTShadow,发现SSDT并没有被HOOK,SSDTShadow HOOK了5个调用: NtUserBuildHwndList NtUserFindWindowEx NtUserGetDC NtUserGetDCEx NtUserGetForegroundWindow 想也不用想,肯定是为了防止其他软件找到他的窗口。 解决方法:在TesSa

ccx_john的专栏 2679

从string一词感受从字母象形到语义生成的底层逻辑

从词源上看,个人认为,soft一词的含义主要来自于“柔软水滑或柔软光滑”这样的含义,是从这样的含义中逐渐窄化,最终主要用来指“柔软”之意,而光滑、水滑这样的含义或语义形象最终被淡化,所以,soft如果符合首字母象形原则,那么它主要的来源形象,应当是【水】,也就是说,soft一词和smooth(a.光滑的)、ski(滑雪)/skate(滑冰)、slip(滑倒)/slippers(拖鞋)、slide(滑动)是相通的,并最终和sea(海)、sweat(汗/汗水)这一类和水一直相关的单词也相通。

nshkfhwr的博客 1271

易灵思Ti60F100 FPGA的HyperRAM实战:从硬件连接到Native接口时序调试

本文详细介绍了易灵思Ti60F100 FPGA内置HyperRAM控制器的实战应用。文章从硬件设计要点(如400MHz+信号完整性、等长匹配)切入,重点解析了如何通过Interface Designer配置高效的Native接口,并分享了其时序详解与调试技巧,为开发者提供了一份从硬件连接到软件调试的深度指南。

weixin_29168153的博客 459

Windows内核新手上路2——挂钩shadow SSDT

Windows内核新手上路2——挂钩shadow SSDT          文章核心内容:安全软件窗口保护、安全输入、截屏保护的一些思路。挂钩NtUserFindWindowEx、NtUserGetForegroundWindow、NtUserBuildHwndList、NtUserQueryWindow、NtUserWindowFromPoint、NtUserSetParent、NtUser

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 2028

winget安装提示:执行此命令时发生意外错误: InternetOpenUrl() failed. 0x80072efd

当我们使用Winget包管理器安装应用,提示错误:执行此命令时发生意外错误: InternetOpenUrl() failed. 0x80072efd 该怎么处理呢?请听我娓娓道来。

Linux I Tell U 8139

驱动编程:注册表回调,进程回调,文件回调,进程隐藏断链,窗口保护

#include "struct.h" #define debug_pott_offset 0x298 //#define debug_pott_offset 0x1f0 DWORD changge_size_NtClose = 0; //NtClose被修改了N字节 PUCHAR ori_head_NtClose = NULL; //NtClose的前N字节数组 PVOID ori_addr_NtClose = NULL; //NtCl..

追逐光芒,追随内心 2712

Amber实战:小分子配体MD模拟全流程避坑指南(附磷酸基团处理技巧)

本文提供了一份基于Amber软件进行小分子配体分子动力学模拟的实战避坑指南。详细解析了从晶体结构预处理、配体参数化(重点探讨AM1-BCC与RESP电荷选择)、复合物体系构建到模拟稳定性调试的全流程。特别针对磷酸基团等特殊官能团处理中常见的模拟崩溃问题,给出了系统性的诊断与解决方案,旨在帮助研究者获得稳定可靠的模拟结果。

weixin_29237635的博客 682

【实战篇】【硅基流动API+Cherry Studio搭建个人知识库全流程解析:从零到精通的超详细指南】

在人工智能技术高速发展的今天,基于大语言模型的知识库已成为开发者提效的必备工具。然而云端服务存在响应延迟、数据隐私、硬件依赖等痛点。通过硅基流动API与的深度整合,我们既能享受大模型的强大能力,又能实现本地化部署与高效管理。本文将从环境配置到高阶调优,手把手带你构建企业级知识库系统。

商务合作|问题讨论|交流学习 请联系作者微信,加微信请务必注明来意,博客主页有联系方式 1083

[ScyllaHide] 04 ScyllaHide配置报错原因定位

[ScyllaHide] 文章列表-看雪地址: 00 简单介绍和使用 01 项目概览 02 InjectorCLI源码分析 03 PEB相关反调试 04 ScyllaHide配置报错原因定位 05 ScyllaHide的Hook原理 ScyllaHide配置报错原因定位 使用OD进行调试的时候,一直报错,如下图所示: 下面我们一步一步的开始分析错误原因,分享下解决问题的思路,希望对大家有一定的帮助。 定位问题 通过关键字“[ScyllaHide] NtUser* API Addresses are m

kinghzking的专栏 1068

使用Captum库对CIFAR数据集进行模型可解释性分析

为了训练模型,我们需要指定损失函数和优化技术。损失函数用于衡量模型的性能,在训练过程中,我们通过调整模型参数来最小化损失。本教程使用。

2501_90323865的博客 178

Anti-Screen Capture(Prevent Screen Captures)截屏与反截屏

1.数字图片使用类似与动画的方式显示,每次显示的是数字的一部分,当动态显示的时候人眼是可以分辨出具体数字的。但是截图的话就只能截取一部分,参考: cups.cs.cmu.edu/soups/2007/posters/p147_lim.pdf 2.屏蔽系统按键:Print Screen 和 Alt + Print Screen,主要原理是注册热键的方式,参考: http://www.v

Koma的主页 8227

Python 爬虫实战:共享单车数据采集全流程与市场洞察深度剖析

本文介绍了如何利用Python爬虫技术获取和分析共享单车运营数据。文章从项目背景出发,详细阐述了系统架构设计,包括数据抓取、清洗存储、分析和可视化模块。通过Scrapy、BeautifulSoup等工具实现数据采集,使用Pandas进行数据清洗,并借助Matplotlib进行可视化分析。实战部分展示了爬虫代码示例和城市分布、使用频率等分析案例。最终指出数据驱动分析有助于了解行业现状和市场趋势,未来可结合机器学习等方法进行深入洞察。该技术方案为共享单车行业研究提供了有效的数据支持。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2235

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Hook Shadow SSDT

作 者: sislcb时 间: 2008-06-02,23:21链 接: http://bbs.pediy.com/showthread.php?t=65931网上很多文章都有关于SSDT的完整的实现,但是没有关于Shadow SSDT的完整实现,目前最好的文章是《shadow ssdt学习笔记 by zhuwg》,我这里的程序也很多参考了他的文章,在这里谢谢了。我这里给出一个hook shado

1478

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

内核交互函数调用和函数地址动态寻找

【代码】内核交互函数调用。

weixin_48257887的博客 332

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

分析了一下360安全卫士的 HOOK(二)——架构与实现(zt)

上一篇的分析中漏掉了三个函数,现补上: NtSetSystemInformation    0×24 ProcessNotify        0×45 //这个并非Hook,只是HookPort安装的一个Notify KeUserModeCallback      0×4B 这样一共是从0到0×4B,共0×4C个过滤函数,齐了~~ 上次先列出了360所hook的系统服务,让大家对它做了

lionzl的专栏 3612

自写API绕过R3下所有HOOK

拿FindWindow来做测试,先OD跟一下HWND hWnd=::FindWindow(_T("SciCalc"),_T("计算器")); ::SendMessage(hWnd,WM_CLOSE,NULL,NULL);为了方便分析参数,给FindWindow也传递了类名。 OD载入,bp FindWindowW,运行后断下来,来到FindWindowW里面77D2C9C5 55 ...

huobengle 997

win10 tagWnd部分成员逆向(窗口隐藏,窗口保护)

题外话:窗口隐藏:效果就是spy++ 彗星小助手发现不了窗口,但是窗口确实存在.(副作用:不透明窗口,鼠标不穿透窗口白屏或无反应,进程退出蓝屏(如果恢复了就不会)) 一大波黑产在路上了??? 怎么隐藏呢? 跟断链一致,前一个的下一个等于当前的下一个,后一个的前一个等于当前的前一个.已经说的很明白了! 另外在17763及以上,在你内核修改是木有效果的哦.具体可以自己研究一下应用层的tagWn...

zhuhuibeishadiao 8146

谈谈 通杀SSDT hook和Shadow SSDT hook的方法

链 接: http://bbs.pediy.com/showthread.php?t=143987 有点纠结,不知道应不应该发,本来想多攒点东西,留着以后找工作。毕竟说空话被bs过。其实技术含量也不高,耐心研究下都能实现。发出来了,权当促进游戏保护和反保护事业的发展吧。大牛飘过吧,那些还没成为大牛就开始倚老卖老喜欢对刚入门的小菜指手画脚的,时不时的来一句“别瞎鼓捣了,你应该从这学起,你应该从

cqyczj的专栏 1711

用户模式与内核模式

从用户模式到内核模式 首先了解一下用户模式和内核模式。 一般说来,进程既可在用户模式下运行,又可在内核模式下运行。内核模式的权限高于用户模式的权限。进程每次调用一个系统调用时,进程的运行方式都发生变化:从用户模式切换到内核模式,然后继续执行。 可见:一个进程在CPU上运行可以有两种运行模式(进程状态):用户模式和内核模式。如果当前运行的是用户程序(用户代码),那么对应进程就处

feidegengao的专栏 1711
上一篇: 抹掉所有进程中自己的句柄(源代码)
下一篇: 微软IE7 0day网马分析(图解)
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值