获取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. [转载]Arguments

    一.Arguments 该对象代表正在执行的函数和调用他的函数的参数. [function.]arguments[n] 参数function :选项.当前正在执行的 Function 对象的名字. n ...

  2. crawler_网络爬虫之数据分析_httpwatcher

    所谓爬虫,首先要通过各种手段爬取到想要站点的数据. web2.0之后,各种网络站点类型越来越多,早期的站点多为静态页面[html .htm],后来逐步加入 jsp.asp,等交互性强的页面.再后来随着 ...

  3. Swift得知——使用和分类功能(四)

    Swift得知--使用和分类功能(四) 总结Swift该功能使用的总可分为七类 1 ---- 没有返回值,没有參数的函数 2 ---- 有參数和返回值的函数 3 ---- 使用元祖来返回多个值 4 - ...

  4. JavaBean中DAO设计模式介绍

    一.信息系统的开发架构 客户层-------显示层-------业务层---------数据层---------数据库 1.客户层:客户层就是client,简单的来说就是浏览器. 2.显示层:JSP/ ...

  5. 【高德地图API】从零开始学高德JS API(五)路线规划——驾车|公交|步行

    原文:[高德地图API]从零开始学高德JS API(五)路线规划——驾车|公交|步行 先来看两个问题:路线规划与导航有什么区别?步行导航与驾车导航有什么区别? 回答: 1.路线规划,指的是为用户提供3 ...

  6. JQ优化性能

    一.注意定义jQuery变量的时候添加var关键字这个不仅仅是jQuery,所有javascript开发过程中,都需要注意,请一定不要定义成如下:$loading = $('#loading'); / ...

  7. 关于winlogo.exe中了“落雪”病毒的解决方法

    Windows Logon Process,Windows NT 用户登陆程序,管理用户登录和退出.该进程的正常路径应是 C:\Windows\System32 且是以 SYSTEM 用户运行,若不是 ...

  8. 数以百万计美元的融资YO是什么东东?

    给自己做个广告哈,新栏目"面试"已经推出,回复"面试"就可以获取. 这两天最火的应用是什么.非yo莫属,堪称史上最简单的社交应用,仅仅能向好友发送一个yo. 出 ...

  9. DDD分层架构之我见

    DDD分层架构之我见 前面介绍了应用程序框架的一个重要组成部分——公共操作类,并提供了一个数据类型转换公共操作类作为示例进行演示.下面准备介绍应用程序框架的另一个重要组成部分,即体系架构支持.你不一定 ...

  10. Wijmo 5 + Ionic Framework之:费用跟踪 App

    Wijmo 5 + Ionic Framework之:费用跟踪 App 费用跟踪应用采用了Wijmo5和Ionic Framework创建,目的是构建一个hybird app. 我们基于<Mob ...