获取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. Eclipse部署Web项目(图文讲解)

    讲解是在linux下完成的,但对windows系统,操作也是一样的,不要被吓到了 1.下载Eclipse

  2. 乐趣与你rabbitMQ 源代码

    RabbitMQ API RabbitMQ Server它提供了丰富的http api. 对于列子 须要HTTP基本身份验证.默认的username/password为guest/guest. 这些返 ...

  3. 《java系统性能调优》--1.发现瓶颈

    性能啊!性能! 之所以想写写性能调优,也是有感于我们的项目,我们採用一些手段使得系统性能上升了一个台阶,总是须要把这点经验沉淀一下.随着工作的深入,关于系统性能的事肯定还有非常多,也算是通过这个系列文 ...

  4. AngularJS之使用服务封装

    AngularJS之使用服务封装可复用代码   创建服务组件 在AngularJS中创建一个服务组件很简单,只需要定义一个具有$get方法的构造函数, 然后使用模块的provider方法进行登记: / ...

  5. struts2源代码分析(个人觉得非常经典)

    读者如果曾经学习过Struts1.x或者有过Struts1.x的开发经验,那么千万不要想当然地以为这一章可以跳过.实际上Struts1.x与Struts2并无我们想象的血缘关系.虽然Struts2的开 ...

  6. Mac下一个/usr/include失踪

    Mac升级到Yosemite后,突然发现vim的YouCompleteMe代码提示所以空头支票成员,排查了一下,原本/usr/include目录中缺少.所有的C/C++头文件不见了. .. 第一次发现 ...

  7. Java之final、finalize、finally的区别

    一.性质不同(1)final为关键字:(2)finalize()为方法:(3)finally为为区块标志,用于try语句中:二.作用(1)final为用于标识常量的关键字,final标识的关键字存储在 ...

  8. 基于Bootstrap的Asp.net Mvc 分页

    基于Bootstrap的Asp.net Mvc 分页的实现 最近写了一个mvc 的 分页,样式是基于 bootstrap 的 ,提供查询条件,不过可以自己写样式根据个人的喜好,以此分享一下.首先新建一 ...

  9. 《C语言及程序设计初步》网络课程主页

    题记 CSDN要开在线教育频道,向我发出邀请,看能否开些课程. 我近日一直在关注着翻转课堂,试图在传统课堂中引入新的元素,这须要资源建设的积累.没有时间表的工作,非常难把握. 为CSDN做在线课程,为 ...

  10. SQL点滴18—SqlServer中的merge操作,相当地风骚

    原文:SQL点滴18-SqlServer中的merge操作,相当地风骚 今天在一个存储过程中看见了merge这个关键字,第一个想法是,这个是配置管理中的概念吗,把相邻两次的更改合并到一起.后来在tec ...