本文为看雪论坛优秀文章
看雪论坛作者ID:学技术打豆豆
在最新的Windows版本中,内存动态并且很多在32位下的变量符号,Windbg现如今都没有了,变成了类似qword_1404687D8这样的东西,对于逆向内存的同学来说,非常不便,但是Windows为了提高效率来进行地址判断的前提下还是给我们留下了一条门缝,我们可以利用此机制反向推导出一些重要的内存布局。
注1:最下面的两个地址是特意申请的两个地址,分别是非分页内存和分页内存地址,用来和上面的基址来比较。
注2:MMPFNDATABASE的基址对比正确。
注3:MiVaProcessSpace 是动态内核虚拟地址空间。
Windows在内存设计之初,设计了一个内核Mark标记,从0xFFFF8000 0000 0000起一直标记了0x100个的标记,这里被微软根据特定的位算法进行了特别的划分(代码演示)。
其内核内存标记如下:
那这些数字代表什么意义?微软其实已经定了一个枚举类型来详细记录:
那通过这两个我们就可以反推出我们需要的内存布局(有些内存布局在这里无法得到,是因为有额外的处理流程,可以通过别的方法得到)。
PCHAR TypeName[NameSize] =
{
"MiVaUnused",
"MiVaSessionSpace",
"MiVaProcessSpace",
"MiVaBootLoaded",
"MiVaPfnDatabase",
"MiVaNonPagedPool",
"MiVaPagedPool",
"MiVaSpecialPoolPaged",
"MiVaSystemCache",
"MiVaSystemPtes",
"MiVaHal",
"MiVaSessionGlobalSpace",
"MiVaDriverImages",
"MiVaSystemPtesLarge",
"MiVaKernelStacks",
"MiVaMaximumType"
};
PVOID FindBase();
PVOID FindSystemKernenlRegion(PVOID pMark);
PVOID FindBaseRegion(PVOID pMark, UCHAR Type);
VOID Unload(PDRIVER_OBJECT pDriverObject)
{
KdPrint(("endn"));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
KdPrint(("startn"));
pDriverObject->DriverUnload = Unload;
//第一步找到Mark地址
PVOID pMarkAddr = FindBase();
//第二步开始解析
FindSystemKernenlRegion(pMarkAddr);
PVOID NonPool = ExAllocatePoolWithTag(NonPagedPool, 0x1000, 'NonP');
PVOID Pool = ExAllocatePoolWithTag(PagedPool, 0x1000, 'ionP');
KdPrint(("NonPagePool=%llx", NonPool));
KdPrint(("PagePool=%llx", Pool));
ExFreePool(NonPool);
ExFreePool(Pool);
return STATUS_SUCCESS;
}
PVOID FindBase()
{
UNICODE_STRING FuncName;
RtlInitUnicodeString(&FuncName, L"ExAcquirePushLockExclusiveEx");
PVOID FuncAddr=MmGetSystemRoutineAddress(&FuncName);
PUCHAR var = (PUCHAR)FuncAddr;
for (int i = 0; i < 0x100; i++)
{
if (*var == 0x48 && *(var+3)==0x27)
{
return var+(*(PUINT32)(var - 4));
}
var++;
}
return 0;
}
PVOID FindSystemKernenlRegion(PVOID pMark)
{
PVOID Region = 0;
for (int i = 0; i < 0x10; i++)
{
KdPrint(("%s=%llxn", TypeName[i], FindBaseRegion(pMark, i)));
}
}
PVOID FindBaseRegion(PVOID pMark,UCHAR Type)
{
PUCHAR var = pMark;
UINT64 pBaseAddr = 0x100;
//
for (int i = 0; i < 0x100; i++)
{
if (*(var) == Type)
{
pBaseAddr =((pBaseAddr | i) << 0x27 | 0xFFFF000000000000);
return pBaseAddr;
}
var++;
}
return 0;
}
可以利用点很多,希望能让大家了解一些Windows的内存机制,以后共同学习。
看雪ID:学技术打豆豆
https://bbs.pediy.com/user-814951.htm
*本文由看雪论坛 学技术打豆豆 原创,转载请注明来自看雪社区。
推荐文章++++
* 一种枚举系统热键的思路及代码实现(Win7&Win10)
好书推荐
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论