我是靠谱客的博主 愤怒小松鼠,最近开发中收集的这篇文章主要介绍无硬编码获取所有对象类型地址,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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");




最后

以上就是愤怒小松鼠为你收集整理的无硬编码获取所有对象类型地址的全部内容,希望文章能够帮你解决无硬编码获取所有对象类型地址所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部