使用WinDbg获取SSDT函数表对应的索引再计算得出地址


当从Ring3进入Ring0的时候会将所需要的SSDT索引放入到寄存器EAX中去,
所以我们这里通过EAX的内容得到函数在SSDT中的索引号,然后计算出它的地址
首先打开WinDbug,我们以函数ZwQueryObject为例:

 


从mov eax 0F8h,知道我们的索引号是0F8h.
来验证一下,看看是不是函数ZwQueryObject。

我们先获取到SSDT的地址:

第一个8488a43c是SSDT的基地址,我们知道函数的地址等于SSDT基地址
+4*索引号,算出函数指针地址为8488a81c

最后u 84a0e0b5得到反汇编看出我们正确得到了ZwQueryObject

这两天学习一个大神的SSDT Hook下次贴出来当作心得

转载于:https://www.cnblogs.com/L-Sunny/p/8385880.html

通过我给出的代码,分析它的作用BOOLEAN HookDbgkDebugObjectType() { //如果是不以原始DbgkDebugObjectType指针来操作,以启动方式时则需要替换PspInsertProcess中的DbgkDebugObjectType UNICODE_STRING ObjectTypeName; //获取原始DbgkDebugObjectType CKernelTable Ssdt; /*根据给定的函数名NtCreateDebugObject,在系统服务描述符表(SSDT)中查找对应的函数地址*/ PVOID NtCreateDebugObject = Ssdt.GetAddressFromName("NtCreateDebugObject"); if (!NtCreateDebugObject) { return FALSE; } ULONG templong = 0; /* 指令序列用于查找 DbgkDebugObjectType 地址*/ UCHAR tzm[] = { 0x48, 0x8B, 0x15, 0xEC, 0x85, 0x47, 0x00 }; ULONG64 addr = 0; for (PUCHAR i = (PUCHAR)NtCreateDebugObject; i < (PUCHAR)NtCreateDebugObject + 0x100; i++) { if (*i == 0x48 && *(i + 1) == 0x8B && *(i + 2) == 0x15 ) { // 复制相对偏移量 memcpy(&templong, i + 3, 4); addr = (ULONG64)((ULONG)templong + (ULONG64)i + 7);// 计算绝对地址 break; } } g_DbgkDebugObjectType = (POBJECT_TYPE*)addr; if (g_DbgkDebugObjectType == 0) { return FALSE; // 返回失败状态,无法获取 DbgkDebugObjectType 地址 } DbgPrint("fh:sys g_DbgkDebugObjectType:%p\n", g_DbgkDebugObjectType); RtlInitUnicodeString(&ObjectTypeName, L"styone"); // 初始化对象类型名称 OBJECT_TYPE_INITIALIZER_WIN10 ObjectTypeInitializer; POBJECT_TYPE* DbgkDebugObjectType = g_DbgkDebugObjectType; //参数构造 //memcpy(&ObjectTypeInitializer, &DbgkDebugObjectType->TypeInfo, sizeof(ObjectTypeInitializer)); // 复制对象类型信息 memcpy(&ObjectTypeInitializer, &(*DbgkDebugObjectType)->TypeInfo, sizeof(OBJECT_TYPE_INITIALIZER_WIN10)); //这里恢复调试权限 //ObjectTypeInitializer.DeleteProcedure = &DbgkpDeleteObject; //ObjectTypeInitializer.CloseProcedure = &DbgkpCloseObject; //ObjectTypeInitializer.DeleteProcedure = &proxyDbgkpDeleteObject; //ObjectTypeInitializer.CloseProcedure = &proxyDbgkpCloseObject; ObjectTypeInitializer.DeleteProcedure = NULL; // 设置删除过程为空 ObjectTypeInitializer.CloseProcedure = NULL;// 设置关闭过程为空 ObjectTypeInitializer.GenericMapping.GenericRead = 0x00020001;// 设置通用读权限 ObjectTypeInitializer.GenericMapping.GenericWrite = 0x00020002; // 设置通用写权限 ObjectTypeInitializer.GenericMapping.GenericExecute = 0x00120000;// 设置通用执行权限 ObjectTypeInitializer.GenericMapping.GenericAll = 0x001f000f;// 设置通用所有权限 ObjectTypeInitializer.ValidAccessMask = 0x001f000f; // 设置有效访问掩码 //创建调试对象类型 NTSTATUS status = ObCreateObjectType(&ObjectTypeName, &ObjectTypeInitializer, NULL, (PVOID*)g_DbgkDebugObjectType); //return FALSE; if (!NT_SUCCESS(status)) { if (status == STATUS_OBJECT_NAME_COLLISION) { //对象名已经存在 DbgPrint("ObCreateObjectType STATUS_OBJECT_NAME_COLLISION 对象名已经存在\n"); PUCHAR j_ObGetObjectType = (PUCHAR)GetKernelAddress("ObGetObjectType"); if (!j_ObGetObjectType) { DbgPrint("ObGetObjectType函数 failed\n"); // 获取 ObGetObjectType函数 失败 return FALSE; } //ULONG uloffset = (ULONG)(*(PUINT32)(j_ObGetObjectType + 31)); //DbgPrint("uloffset:%x\n", uloffset); //ULONG64 baseAddr = (ULONG64)j_ObGetObjectType + 35; //DbgPrint("baseAddr:%p\n", baseAddr); //POBJECT_TYPE* ObTypeIndexTable = (POBJECT_TYPE*)(baseAddr + uloffset); // 获取对象类型索引地址 POBJECT_TYPE* ObTypeIndexTable = (POBJECT_TYPE*)(*(PUINT32)(j_ObGetObjectType + 31) + (ULONG64)j_ObGetObjectType + 35); if (!ObTypeIndexTable) { DbgPrint("ObGetObjectType get failed\n"); // 获取对象类型索引表失败 return FALSE; } DbgPrint("ObTypeIndexTable:%p\n", ObTypeIndexTable); // 打印对象类型索引地址 //DbgPrint("sizeof(_OBJECT_TYPE):%x\n", sizeof(_OBJECT_TYPE)); // 打印对象类型索引表第2个元素地址 DbgPrint("ObTypeIndexTable[2]:%p\n", ObTypeIndexTable[2]); ULONG Index = 2; while (ObTypeIndexTable[Index]) { // 打印当前对象类型地址 DbgPrint("ObTypeIndexTable[Index]:%p\n", ObTypeIndexTable[Index]); if (&ObTypeIndexTable[Index]->Name) { if (ObTypeIndexTable[Index]->Name.Buffer) { DbgPrint("RtlCompareUnicodeString:%ws %ws\n", ObTypeIndexTable[Index]->Name.Buffer, ObjectTypeName.Buffer); // 比较对象类型名称 if (RtlCompareUnicodeString(&ObTypeIndexTable[Index]->Name, &ObjectTypeName, FALSE) == 0) { // 设置 DbgkDebugObjectType 为找到的对象类型 *g_DbgkDebugObjectType = ObTypeIndexTable[Index]; // 打印已存在的 DbgkDebugObjectType 地址 DbgPrint("ObCreateObjectType already exist *g_DbgkDebugObjectType:%p\n", *g_DbgkDebugObjectType); return TRUE; } } } Index++; } } else { DbgPrint("ObCreateObjectType eeor!\n"); // 创建对象类型失败 return FALSE; } } // 打印创建成功的 DbgkDebugObjectType 地址 DbgPrint("ObCreateObjectType ok g_DbgkDebugObjectType:%p\n", g_DbgkDebugObjectType); return TRUE;// 返回成功状态 }
最新发布
08-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值