获取ssdt表中所有函数的地址
for (int i = 0; i < KeServiceDescriptorTable->NumberOfServices; i++)
{
    KdPrint(("NumberOfService[%d]-------%X\n", i, KeServiceDescriptorTable->ServiceTableBase[i]));
}
 
需要这样定义
typedef struct _ServiceDescriptorTable {
unsigned int* ServiceTableBase; //System Service Dispatch Table 的基地址  
unsigned int* ServiceCounterTable;
//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 
unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。  
unsigned char* ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 
}*PServiceDescriptorTable;  
 
extern "C" extern PServiceDescriptorTable KeServiceDescriptorTable;
 
流程:
1、在ssdt_hook()函数中保存要hook函数的(NtOpenProcess)地址
2、将原来ssdt中所要hook的函数地址换成我们自己的函数地址
3、在UnHookSsdt中恢复ssdt中原来的函数地址
 
当驱动加载成功后,首先执行DriverEntry里面的ssdt_hook()函数,此时我们用CE打开我们保护的进程,
就会执行到我自己定义的函数MyNtOpenProcess()
最后卸载驱动,执行Driver_Unload()里面的UnHookSsdt()函数
 
 
作用:
防止被其他进程用OpenProcess打开,例如Cheat Engine
 
注意:
修改地址的时候,都应该先去掉页面保护,再恢复页面保护
使用了PsLookupProcessByProcessId后,必须用ObDereferenceObject回收!
PsLookupProcessByProcessId获取指定进程的EPROCESS结构,目的就是获取进程名
 
总结:
ssdt_hook的代码都是这样,
ssdt_hook()函数里面先保存要hook的地址,接着修改为自己定义函数的地址,
UnSsdt_hook()函数里面就是还原地址
而且自己定义函数里面要还原之前那个函数
 
VOID UnHookSsdt()
{
PageProtectOff();
KeServiceDescriptorTable->ServiceTableBase[122] = O_NtOpenProcess; //恢复ssdt中原来的函数地址
PageProtectOn();
}
 
NTSTATUS HookSsdt()
{
// 1、在ssdt_hook()函数中保存要hook函数的(NtOpenProcess)地址
O_NtOpenProcess = KeServiceDescriptorTable->ServiceTableBase[122];
PageProtectOff();
// 2、将原来ssdt中所要hook的函数地址换成我们自己的函数地址
KeServiceDescriptorTable->ServiceTableBase[122] = (unsigned int)MyNtOpenProcess;
// 此时我们用CE打开被保护的进程,就会调用我们自己的函数
PageProtectOn();
 
return STATUS_SUCCESS;
}
 
效果:
 
cpp代码:
 #ifdef __cplusplus
extern "C"
{
#endif
#include <ntddk.h>
#ifdef __cplusplus
}
#endif typedef struct _ServiceDescriptorTable {
unsigned int* ServiceTableBase; //System Service Dispatch Table 的基地址
unsigned int* ServiceCounterTable;
//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。
unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。
unsigned char* ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表
}*PServiceDescriptorTable; extern "C" extern PServiceDescriptorTable KeServiceDescriptorTable; typedef NTSTATUS(*MYNTOPENPROCESS)(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId );//定义一个函数指针,用于下面对O_NtOpenProcess进行强制转换 ULONG O_NtOpenProcess = ; extern "C" NTSTATUS
PsLookupProcessByProcessId(
IN HANDLE ProcessId,
OUT PEPROCESS *Process
); void PageProtectOff()//关闭页面保护
{
__asm{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
}
void PageProtectOn()//打开页面保护
{
__asm{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
} // 判断是否打开的是自己想保护的进程
BOOLEAN ProtectProcess(HANDLE ProcessId,char *str_ProtectObjName)
{
NTSTATUS status;
PEPROCESS process_obj; if(!MmIsAddressValid(str_ProtectObjName))//这个条件是用来判断目标进程名是否有效
{
return FALSE;
}
if(ProcessId == )//这个条件是用来排除System Idle Process进程的干扰
{
return FALSE;
}
status=PsLookupProcessByProcessId(ProcessId, &process_obj);//这句用来获取目标进程的EPROCESS结构
if(!NT_SUCCESS(status))
{
KdPrint(("我错了,这个是错误号:%X---这个是进程ID:%d\n",status,ProcessId));
return FALSE;
}
if(!strcmp((char *)process_obj + 0x174, str_ProtectObjName))//进行比较
{
ObDereferenceObject(process_obj);//对象计数器减1,为了恢复对象管理器计数,便于回收
return TRUE;
}
ObDereferenceObject(process_obj);
return FALSE;
//使用了PsLookupProcessByProcessId后,必须用ObDereferenceObject回收!
//PsLookupProcessByProcessId获取指定进程的EPROCESS结构,目的就是获取进程名
}
NTSTATUS MyNtOpenProcess (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
)
{
if(ProtectProcess(ClientId->UniqueProcess,"notepad.exe")) // 如果打开的进程是目标进程
{
KdPrint(("%s打开文件失败\n",(char *)PsGetCurrentProcess()+0x174));
return STATUS_UNSUCCESSFUL; // 这是一个关键,设置STATUS_UNSUCCESSFUL,CE就会提示打开不成功
} return ((MYNTOPENPROCESS)O_NtOpenProcess)(ProcessHandle,//处理完自己的任务后,调用原来的函数,让其它进程正常工作
DesiredAccess,
ObjectAttributes,
ClientId);
} VOID UnHookSsdt()
{
PageProtectOff();
KeServiceDescriptorTable->ServiceTableBase[] = O_NtOpenProcess; //恢复ssdt中原来的函数地址
PageProtectOn();
}
NTSTATUS HookSsdt()
{
// 1、在ssdt_hook()函数中保存要hook函数的(NtOpenProcess)地址
O_NtOpenProcess = KeServiceDescriptorTable->ServiceTableBase[];
PageProtectOff();
// 2、将原来ssdt中所要hook的函数地址换成我们自己的函数地址
KeServiceDescriptorTable->ServiceTableBase[] = (unsigned int)MyNtOpenProcess;
// 此时我们用CE打开被保护的进程,就会调用我们自己的函数
PageProtectOn(); return STATUS_SUCCESS;
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
UnHookSsdt();
KdPrint(("Driver Unload Success !\n"));
} extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath )
{
KdPrint(("Welcome to My Driver\n"));
pDriverObject->DriverUnload = DriverUnload;
/* 所有函数的地址
for (int i = 0; i < KeServiceDescriptorTable->NumberOfServices; i++)
{
KdPrint(("NumberOfService[%d]-------%X\n", i, KeServiceDescriptorTable->ServiceTableBase[i]));
}*/
HookSsdt();
return STATUS_SUCCESS;
}

ssdt_hook NtOpenProcess的更多相关文章

  1. CMStepCounter Class Refernce

    CMStepCounter Class Refernce https://developer.apple.com/library/ios/documentation/CoreMotion/Refere ...

  2. 64位下Hook NtOpenProcess的实现进程保护 + 源码 (升级篇 )

    64位下Hook NtOpenProcess的实现进程保护 + 源码 (升级篇 ) [PS: 如果在64位系统下,出现调用测试demo,返回false的情况下,请修改Hook Dll的代码] glhH ...

  3. NtOpenProcess被HOOK,跳回原函数地址后仍然无法看到进程

    点击打开链接http://www.ghoffice.com/bbs/read-htm-tid-103923.html

  4. 菜鸟开始学习SSDT HOOK((附带源码)

    看了梦无极的ssdt_hook教程,虽然大牛讲得很细,但是很多细节还是要自己去体会,才会更加深入.在这里我总结一下我的分析过程,若有不对的地方,希望大家指出来.首先我们应该认识 ssdt是什么?从梦无 ...

  5. Hook集合----SSDTHook(x86 Win7)

    最近在学习Ring0层Hook的一些知识点,很久就写完SSDTHook的代码了,但是一直没有整理成笔记,最近有时间也就整理整理. 介绍: SSDTHook 实质是利用Ntoskrnl.exe 中全局导 ...

  6. 硬件断点 DrxHook

    硬件断点 DrxHook 硬件断点的实现需要依赖于调试寄存器 DR0~DR7  调试寄存器 DR0~DR3-----调试地址寄存器DR4~DR5-----保留DR6 -----调试状态寄存器 指示哪个 ...

  7. windbg常见命令

    WinDbg WinDbg支持以下三种类型的命令: ·        常规命令,用来调试进程 ·        点命令,用来控制调试器 ·        扩展命令,可以添加叫WinDbg的自定义命令, ...

  8. InLineHookSSDT

    //当Ring3调用OpenProcess //1从自己的模块(.exe)的导入表中取值 //2Ntdll.dll模块的导出表中执行ZwOpenProcess(取索引 进入Ring0层) //3进入R ...

  9. Resume Hook SSDT

    在HookSSDT中  通过在第4部通过索引将NtOpenProcess 换成 Base[索引] = FakeNtOpenProcess; so 在阻止时应该在ntoskrnl.exe 找到真正的Op ...

随机推荐

  1. oracle_面试题

    SELECT a.name ,IFNULL(b.name,"BOSS") FROM boss a LEFT JOIN boss b ON a.MANAGER_ID = b.ID 员 ...

  2. XEvent – SQL Server Log文件对磁盘的写操作大小是多少

    原文:XEvent – SQL Server Log文件对磁盘的写操作大小是多少 本篇是上一篇SQL Server Log文件对磁盘的写操作大小是多少的续,使用XEvent收集SQL Server D ...

  3. 6最好的之一 HTML5/CSS3 演示(PPT)框架

    HTML 是全世界最流行的网页编程语言.而HTML5是这门语言的升级版本号.越来越多的开发人员和设计师開始使用HTML5.以下介绍几个 HTML5/CSS3 的演示工具和框架,你能够用它们来创建你的网 ...

  4. 浅谈 js 正则之 test 方法

    原文:浅谈 js 正则之 test 方法 其实我很少用这个,所以之前一直没注意这个问题,自从落叶那厮写了个变态的测试我才去看了下这东西.先来看个东西吧. var re = /\d/; console. ...

  5. POJ 1035 代码+具体的目光

    Spell checker Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 19319 Accepted: 7060 Descri ...

  6. 小结css2与css3的区别

    CSS3引进了一些新的元素新的特性,我收集以下,自己做了一个小结: animation(基础动画)eg:  div{animation: myfirst 5s linear 2s infinite a ...

  7. 关于MariaDB和Mysql

    最近安装数据库的时候发现执行yum install mysql 命令时安装成了mariadb的数据库,它其实也是mysql的一个分支,完全兼容mysql 安装数据库: yum install mysq ...

  8. C# 获取与解析枚举类型的 DescriptionAttribute

    原文:C# 获取与解析枚举类型的 DescriptionAttribute System.ComponentModel.DescriptionAttribute 这个 Attribute,经常被用来为 ...

  9. .NET开源项目 TOP 25

    .NET开源项目 TOP 25 如果知道.NET项目在开源中国的git上所占的比重只有5%的话,为什么这个<2014年国人开发的最热门的开源软件TOP 100>榜中.NET项目那么少就是情 ...

  10. Oracle / PLSQL写语句的时候常使用的函数

    最近在学习数据库方面的知识,做个标记. 这里有英文解释,建议多看看英文文档: https://www.techonthenet.com/oracle/functions/ 下面开始记录一下,自己在Or ...