概述
NTKERNELAPI PVOID NTAPI
ObGetObjectType(
IN PVOID pObject
);
void GetObjectTypeWin7x86()
{
BOOLEAN i = 2;
ULONG j= 2;
ULONG64 ObjectType;
//
while (ObGetObjectType(&i+0xC))
{
ObjectType = ObGetObjectType(&i + 0xC);//C来自于ObGetObjectType反汇编处的eax-0xC win7 x86
KdPrint(("对象类型[%d]=%wZn", j, ObjectType+0x8));
i++;
j++;
}
/*获取TypeIndex的值,解释一下为什么是减去0Ch。正常的计算应该是:
object地址-Object_header的大小+TypeIndex的偏移,所以有:
eax-0x18h+0x0Ch 即为 eax – 0x0Ch
82a8f3fe 0fb640f4 movzx eax,byte ptr [eax-0Ch]
根据索引值在ObTypeIndexTable数组中找到对应的ObjectType。
url:http://www.blogfshare.com/win7-obtypeindextable.html
*/
}
void GetObjectTypeWin7x64()//0x18来的原理同上
{
BOOLEAN i = 2;
ULONG j = 2;
ULONG64 ObjectType;
UNICODE_STRING ObjectName;
RtlInitUnicodeString(&ObjectName,L"Process");
while (ObGetObjectType(&i+0x18))
{
ObjectType = ObGetObjectType(&i + 0x18);
KdPrint(("对象类型[%d]=%wZn", j, ObjectType+0x10));
i++;
j++;
}
/*
ObGetObjectType(&i + 0x18) 里面就要一个地址我们给他i的地址, + 0x18就是还原TypeIndex的
相当于把这个指令变为
movzx eax,byte ptr [rcx-18h] --> movzx eax,i
nt!ObGetObjectType:
fffff800`0613c854 0fb641e8 movzx eax,byte ptr [rcx-18h] //rcx-18h = rcx - sizeof(OBJECT_TYPE)0x30 + TypeIndex偏移0x18
fffff800`0613c858 488d0da1e2efff lea rcx,[nt!ObTypeIndexTable (fffff800`0603ab00)]
fffff800`0613c85f 488b04c1 mov rax,qword ptr [rcx+rax*8]
fffff800`0613c863 c3 ret
*/
/*
ObjectType = ObGetObjectType(&i + 0x18);
KdPrint(("对象类型[%d]=%wZn", j, ObjectType+0x10));
ObjectType = ObGetObjectType(&k + 0x18);
KdPrint(("对象类型[%d]=%wZn", j, ObjectType+0x10));
*/
}
为什么一个是+0x18 一个是+0xc
首先,确定一点是ObGetObjectType这个函数是根据TypeIndex去ObTypeIndexTable取地址的
这个函数在没有检查参数,直接读了一个内存地址
看反汇编,这里以win7x64为例子:
PAGE:000000014032A854 public ObGetObjectType
PAGE:000000014032A854 ObGetObjectType proc near ; CODE XREF: CMFCheckAccess:loc_14032AB3Ep
PAGE:000000014032A854 ; PnpHandleProcessWalkWorker+15p ...
PAGE:000000014032A854 movzx eax, byte ptr [rcx-18h]
PAGE:000000014032A858 lea rcx, ObTypeIndexTable
PAGE:000000014032A85F mov rax, [rcx+rax*8]
PAGE:000000014032A863 retn
PAGE:000000014032A863 ObGetObjectType endp
PAGE:000000014032A863
从参数的地址中获取数据当TypeIndex
那么我们只需要改变这个地址,怎么改呢?这里的参数放在rcx中,我们只能改rcx的值,我们先把-18h除去,就是+0x18
rcx的值我们用我们变量的地址来填充
就变成了
movzx eax,byte ptr [变量的地址+18h - 18h]
那么结果呢,你懂得
下面是封转好的
/根据调试对象类型名字,获取调试对象类型指针
PVOID GetObjectTypeByName(PWCHAR ObjectTypeName)
{
UNICODE_STRING name;
BOOLEAN i = 2;
PVOID pObjectType;
if (ObjectTypeName == NULL)
{
return 0;
}
RtlInitUnicodeString(&name, ObjectTypeName);
while (ObGetObjectType((PVOID)(&i + 0x18)))
{
pObjectType = ObGetObjectType(&i + 0x18);
i++;
if (RtlEqualUnicodeString((PVOID)((ULONG_PTR)pObjectType + 0x10), &name, TRUE))
{
return pObjectType;
}
}
return 0;
}
//调用方法
PVOID gProcessObjectType = 0;
gProcessObjectType = <span style="font-family: Arial, Helvetica, sans-serif;">GetObjectTypeByName</span>(L"Process");
最后
以上就是愤怒小松鼠为你收集整理的无硬编码获取所有对象类型地址的全部内容,希望文章能够帮你解决无硬编码获取所有对象类型地址所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复