[mark][/mark][mark][/mark]

可以解决国内某游戏代理商内存保护的东东 修改页表数据达到无法正确寻址到具体的物理地址借此打乱内存数据
下面的代码可以达到绕过它内存保护的目的

NTSTATUS MMcopyProcessMemory(PEPROCESS tagetProcess,PVOID addr,SIZE_T size,PVOID data){
KAPC_STATE ApcState;
SIZE_T tosize;
PMDL mdl=NULL;
PVOID MappedAddress=NULL;

BOOLEAN attach = FALSE;
BOOLEAN lockpage = FALSE;
BOOLEAN maplockpage = FALSE;
BOOLEAN havemdl = FALSE;

if (size<PAGE_SIZE)
{
tosize = PAGE_SIZE;
}else{
tosize = size;
}
if (!MmIsAddressValid(data))
{
return STATUS_NOT_MAPPED_DATA;
}
__try{

KeStackAttachProcess(tagetProcess, &ApcState);
attach = TRUE;
mdl=IoAllocateMdl(addr, tosize, FALSE, FALSE, NULL);
if (mdl==NULL)
{
KeUnstackDetachProcess(&ApcState);
return STATUS_NOT_MAPPED_DATA;
}

havemdl = TRUE;

MmProbeAndLockPages(mdl, KernelMode, IoReadAccess);
lockpage = TRUE;
MappedAddress = MmMapLockedPagesSpecifyCache(mdl,
KernelMode,
MmCached,
NULL,
FALSE,
HighPagePriority);
maplockpage = TRUE;

RtlCopyMemory(data, MappedAddress, size);

MmUnmapLockedPages(MappedAddress, mdl);
maplockpage = FALSE;
MmUnlockPages(mdl);
lockpage = FALSE;
IoFreeMdl(mdl);
havemdl = FALSE;
KeUnstackDetachProcess(&ApcState);
attach = FALSE;
}__except(1){
if (maplockpage)
{
MmUnmapLockedPages(MappedAddress, mdl);
}
if (lockpage)
{
MmUnlockPages(mdl);
}
if (havemdl)
{
IoFreeMdl(mdl);
}
if (attach)
{

KeUnstackDetachProcess(&ApcState);
}
return STATUS_NOT_FOUND;
}
return STATUS_SUCCESS;
}

下面是写入

NTSTATUS MMWriteProcessMemory(PEPROCESS tagetProcess, PVOID addr, SIZE_T size, PVOID data) {
KAPC_STATE ApcState;
SIZE_T tosize;
PMDL mdl = NULL;
PVOID MappedAddress = NULL;

BOOLEAN attach = FALSE;
BOOLEAN lockpage = FALSE;
BOOLEAN maplockpage = FALSE;
BOOLEAN havemdl = FALSE;

if (size < PAGE_SIZE)

{ tosize = PAGE_SIZE; }

else

{ tosize = size; }

if (!MmIsAddressValid(data))

{ return STATUS_NOT_MAPPED_DATA; } __try

{

KeStackAttachProcess(tagetProcess, &ApcState);

attach = TRUE;

mdl = IoAllocateMdl(addr, tosize, FALSE, FALSE, NULL);

if (mdl == NULL) { KeUnstackDetachProcess(&ApcState);

return STATUS_NOT_MAPPED_DATA;
}
havemdl = TRUE; MmProbeAndLockPages(mdl, KernelMode, IoReadAccess);

lockpage = TRUE;

MappedAddress = MmMapLockedPagesSpecifyCache(mdl, KernelMode, MmCached, NULL, FALSE, HighPagePriority);

maplockpage = TRUE; RtlCopyMemory(MappedAddress, data, size); MmUnmapLockedPages(MappedAddress, mdl);

maplockpage = FALSE;
MmUnlockPages(mdl);

lockpage = FALSE;
IoFreeMdl(mdl);
havemdl = FALSE; KeUnstackDetachProcess(&ApcState); attach = FALSE;

}

__except (1)

{
if (maplockpage) { MmUnmapLockedPages(MappedAddress, mdl);

} if (lockpage)

{ MmUnlockPages(mdl);

} if (havemdl)

{
IoFreeMdl(mdl);
}
if (attach) { KeUnstackDetachProcess(&ApcState);

} return STATUS_NOT_FOUND;

} return STATUS_SUCCESS;
}

原理是windows在每个页表中都映射了几个固定的虚拟地址用来指向ppe pxe pde pte... 而且TP只XO了页表的用户内存然而映射内核内存 却没有变动。所以 MDL中直接利用PTE表地址 得到va的pa然后 用系统空闲pte重新映射。 原先cpu寻址:PML4E索引 PDPTE索引 PDE索引 PTE索引 页内偏移 现在 : PTE索引 页内偏移 =拿到物理地址 还可以自己在回掉中记录这个PTE表的物理地址 以后都不用切换CR3了。 PMMPTE MiGetPteAddress(ULONG64 va) {

return ((PMMPTE)(((((ULONG64)(va)& VIRTUAL_ADDRESS_MASK) >> PTI_SHIFT) << PTE_SHIFT) + pte_base)); } 即可得到Pte 然后pte->u.Hard.PageFrameNumber 得到页框号= MmMapIoSpace(phy2, PAGE_SIZE, MmNonCached);映射至系统Va即可读写

还是在0e中做检测比较好,毕竟被破坏的CR3讲道理不会正常寻址。

本站文章基于国际协议BY-NA-SA 4.0协议共享;
如未特殊说明,本站文章皆为原创文章,请规范转载。

0

博客管理员