#include"ntddk.h"
#pragma pack(1) //写这个内存以一字节对齐 如果不写是以4字节的对齐的
typedef struct ServiceDescriptorEntry {//这个结构就是为了管理这个数组而来的 内核api所在的数组 才有这个结构的 这个是ssdt
unsigned int *ServiceTableBase;//就是ServiceTable ssdt数组
unsigned int *ServiceCounterTableBase; //仅适用于checked build版本 无用
unsigned int NumberOfServices;//(ServiceTableBase)数组中有多少个元素 有多少个项
unsigned char *ParamTableBase;//参数表基址 我们层传过来的api的参数 占用多少字节 多大
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack(1)
_declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;//(名字不要写错) //导入ssdt表
ULONG lao_ntopenproesss;
UCHAR tezhengma2[5];
void yebaohuguanbi()//页保护关闭
{
__asm{//去掉内存保护
cli
mov eax, cr0
and eax, not 10000h
mov cr0, eax
}
}
void yebaohukaiqi()//页保护开启
{
__asm{//恢复内存保护
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
}
VOID xiezai1(PDRIVER_OBJECT qudongduixiang)
{
yebaohuguanbi();//页保护关闭
RtlCopyMemory((PVOID)lao_ntopenproesss, tezhengma2, 5);//把现在inline hook后 的代码还原
yebaohukaiqi();//页保护开启
KdPrint(("驱动卸载历程 已经执行\n"));
}
void guolvlicheng()
{
KdPrint(("进入到我的过滤历程来了 当前进程%s\n", (char*)PsGetCurrentProcess() + 0x16c));
}
_declspec(naked)
void lisaisaide_ntopenkey()//我的ntopenkey
{
__asm
{
call guolvlicheng //直接call 这个函数 不用转换
pop eax
mov edi, edi
push ebp
mov ebp, esp //前面5个是我们填写特征码的 字节 要补上
jmp eax //测试下 看会蓝屏吗
}
}
void inline_hook_ntopenkey()
{
unsigned int wodehanshudizhi1 = (unsigned int)&lisaisaide_ntopenkey;
UCHAR tezhengma1[5];
ULONG pianyi1 = 0;//call wodehanshudizhi1 的特征码 就是e8后面跟的便宜
tezhengma1[0] = 0xe8;
pianyi1 = wodehanshudizhi1 - 5 - lao_ntopenproesss;//lao_ntopkey就是od反汇编 最前面的地址
*(ULONG*)&tezhengma1[1] = pianyi1;//特征码计算完毕
yebaohuguanbi();//页保护关闭 //拷贝内存的时候关开
RtlCopyMemory(tezhengma2, (PVOID)lao_ntopenproesss, 5);
RtlCopyMemory((PVOID)lao_ntopenproesss, tezhengma1, 5);//5个字节的特征码 拷贝到原始ssdt的ntopenprocess函数的汇编代码 改写
yebaohukaiqi();//页保护开启
}
NTSTATUS DriverEntry(PDRIVER_OBJECT qudongduixiang, PUNICODE_STRING zhucebiao)
{
lao_ntopenproesss = KeServiceDescriptorTable.ServiceTableBase[190];//系统老的nt_openprocess
inline_hook_ntopenkey();
qudongduixiang->DriverUnload = xiezai1;
return STATUS_SUCCESS;
}