/
/
1
获取虚拟内存的PXE PDPTE pde,pte的索引
ULONG PxeIndex
=
(VirtualAddress_s >>
0x27
) &
0x1FF
;
UINT32 PPEIndex
=
(VirtualAddress_s >>
0x1E
) &
0x1FF
;
/
/
PPEIndex
UINT32 PDEIndex
=
(VirtualAddress_s >>
0x15
) &
0x1FF
;
/
/
PDEIndex
UINT32 PTEIndex
=
(VirtualAddress_s >>
0xC
) &
0x1FF
;
/
/
DbgBreakPoint();
/
/
2
获取要hook进程的CR3
PEPROCESS pEprocess
=
NULL;
NTSTATUS status
=
PsLookupProcessByProcessId(Pid, &pEprocess);
if
(!NT_SUCCESS(status))
{
return
0
;
}
HANDLE hMemory
=
NULL;
UNICODE_STRING unName
=
{
0
};
RtlInitUnicodeString(&unName, L
"\\Device\\PhysicalMemory"
);
OBJECT_ATTRIBUTES obj;
InitializeObjectAttributes(&obj, &unName, OBJ_CASE_INSENSITIVE, NULL, NULL);
status
=
ZwOpenSection(&hMemory, SECTION_ALL_ACCESS, &obj);
if
(!NT_SUCCESS(status))
{
return
0
;
}
SIZE_T sizeView
=
PAGE_SIZE;
PVOID sectionObj
=
NULL;
status
=
ObReferenceObjectByHandle(hMemory, SECTION_ALL_ACCESS, NULL, KernelMode, §ionObj, NULL);
if
(!NT_SUCCESS(status))
{
return
status;
}
ULONG_PTR Cr3PhyAddr
=
*
(PULONG64)((ULONG64)pEprocess
+
KERNEL_CR3_OFFSET)&~(
0xf
);
PHYSICAL_ADDRESS Cr3
=
{
0
};
Cr3.QuadPart
=
Cr3PhyAddr;
ULONG_PTR VirtualAddresss
=
NULL;
status
=
ZwMapViewOfSection(hMemory,
NtCurrentProcess(), &VirtualAddresss,
0
, PAGE_SIZE, &Cr3, &sizeView, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE);
/
/
ULONG_PTR VirtualAddresss
=
MmMapIoSpace(Cr3, PAGE_SIZE, MmNonCached);
/
/
由于Cr3是物理地址我们需要映射到虚拟内存中去
if
(!NT_SUCCESS(status))
{
return
0
;
}
/
/
3
构建页表
/
/
*
(PULONG64)(VirtualAddresss
+
PxeIndex
*
8
) |
=
70
;
PHYSICAL_ADDRESS Low
=
{
0
};
PHYSICAL_ADDRESS High
=
{ MAXULONG64 };
/
/
ppe
do
{
pPhyAddr[
0
]
=
(ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, Low, High, Low, MmCached);
newPPEphy
=
MmGetPhysicalAddress(pPhyAddr[
0
]).QuadPart;
ULONG_PTR PPEPhyAddr
=
(ULONG_PTR)(((PHARDWARE_PTE)(VirtualAddresss
+
PxeIndex
*
8
))
-
>PageFrameNumber)
*
0x1000
;
PHYSICAL_ADDRESS temp
=
{
0
};
temp.QuadPart
=
PPEPhyAddr;
ULONG_PTR VirtualAddress_PPE
=
NULL;
ZwMapViewOfSection(hMemory,
NtCurrentProcess(), &VirtualAddress_PPE,
0
, PAGE_SIZE, &temp, &sizeView, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE);
memcpy(pPhyAddr[
0
], VirtualAddress_PPE, PAGE_SIZE);
/
/
pde
pPhyAddr[
1
]
=
(ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, Low, High, Low, MmCached);
newPDEphy
=
MmGetPhysicalAddress(pPhyAddr[
1
]).QuadPart;
ULONG_PTR pdePhy
=
(ULONG_PTR)(((PHARDWARE_PTE)(VirtualAddress_PPE
+
PPEIndex
*
8
))
-
>PageFrameNumber)
*
0x1000
;
temp.QuadPart
=
pdePhy;
ULONG_PTR VirtualAddress_PDE
=
NULL;
ZwMapViewOfSection(hMemory,
NtCurrentProcess(), &VirtualAddress_PDE,
0
, PAGE_SIZE, &temp, &sizeView, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE);
memcpy(pPhyAddr[
1
], VirtualAddress_PDE, PAGE_SIZE);
/
/
pte
ULONG_PTR ptePhy
=
(ULONG_PTR)(((PHARDWARE_PTE)(VirtualAddress_PDE
+
PDEIndex
*
8
))
-
>PageFrameNumber)
*
0x1000
;
temp.QuadPart
=
ptePhy;
if
(((PHARDWARE_PTE)(VirtualAddress_PDE
+
PDEIndex
*
8
))
-
>LargePage
=
=
1
)
{
pPhyAddr[
2
]
=
(ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE
*
1024
, Low, High, Low, MmCached);
memset(pPhyAddr[
2
],
0
, PAGE_SIZE
*
1024
);
ULONG_PTR Real
=
MmGetPhysicalAddress(pPhyAddr[
2
]).QuadPart;
ULONG_PTR Real1
=
Real;
ULONG_PTR Realtemp
=
0
;
if
(Real
=
=
0
)
{
MmFreeContiguousMemory(pPhyAddr[
0
]);
MmFreeContiguousMemory(pPhyAddr[
1
]);
MmFreeContiguousMemory(pPhyAddr[
2
]);
return
FALSE;
}
ULONG i
=
0
;
for
(i
=
0
; i <
1024
; i
+
+
)
{
Real
+
=
PAGE_SIZE;
/
/
Real &
=
0x1fffff
;
Realtemp
=
Real &
0x1fffff
;
if
(!Realtemp)
break
;
}
DbgBreakPoint();
pPhyAddr[
2
]
+
=
PAGE_SIZE
*
(i
+
1
);
newPTEphy
=
MmGetPhysicalAddress(pPhyAddr[
2
]).QuadPart;
ULONG_PTR VirtualAddress_PTE
=
NULL;
sizeView
=
PAGE_SIZE
*
0x200
;
ZwMapViewOfSection(hMemory,
NtCurrentProcess(), &VirtualAddress_PTE,
0
, PAGE_SIZE, &temp, &sizeView, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE);
memcpy(pPhyAddr[
2
], VirtualAddress_s &~(
0x1fffff
), PAGE_SIZE
*
0x200
);
((PHARDWARE_PTE)(pPhyAddr[
0
]
+
PPEIndex
*
8
))
-
>PageFrameNumber
=
newPDEphy >>
12
;
((PHARDWARE_PTE)(pPhyAddr[
1
]
+
PDEIndex
*
8
))
-
>PageFrameNumber
=
newPTEphy >>
12
;
/
/
((PHARDWARE_PTE)(pPhyAddr[
2
]
+
PTEIndex
*
8
))
-
>Write
=
1
;
ULONG_PTR newOffset
=
(VirtualAddress_s &
0x1ff000
)
+
offset;
/
/
((PHARDWARE_PTE)(pPhyAddr[
1
]
+
PTEIndex
*
8
))
-
>Write
=
1
;
*
(PUCHAR)(pPhyAddr[
2
]
+
newOffset
+
0x27
)
=
0x90
;
*
(PUCHAR)(pPhyAddr[
2
]
+
newOffset
+
0x28
)
=
0x90
;
*
(PUCHAR)(pPhyAddr[
2
]
+
newOffset
+
0x29
)
=
0xc3
;
ULONG_PTR ss
=
pPhyAddr[
2
];
ULONG_PTR ss2
=
VirtualAddress_s & ~(
0x1fffff
);
IsPdeLager
=
1
;
break
;
}
pPhyAddr[
2
]
=
(ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, Low, High, Low, MmCached);
newPTEphy
=
MmGetPhysicalAddress(pPhyAddr[
2
]).QuadPart;
ULONG_PTR VirtualAddress_PTE
=
NULL;
ZwMapViewOfSection(hMemory,
NtCurrentProcess(), &VirtualAddress_PTE,
0
, PAGE_SIZE, &temp, &sizeView, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE);
memcpy(pPhyAddr[
2
], VirtualAddress_PTE, PAGE_SIZE);
/
/
物理内存
pPhyAddr[
3
]
=
(ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, Low, High, Low, MmCached);
newphy
=
MmGetPhysicalAddress(pPhyAddr[
3
]).QuadPart;
ULONG_PTR Phy
=
(ULONG_PTR)(((PHARDWARE_PTE)(VirtualAddress_PTE
+
PTEIndex
*
8
))
-
>PageFrameNumber)
*
0x1000
;
temp.QuadPart
=
Phy;
ULONG_PTR VirtualAddress_PHY
=
NULL;
ZwMapViewOfSection(hMemory,
NtCurrentProcess(), &VirtualAddress_PHY,
0
, PAGE_SIZE, &temp, &sizeView, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE);
memcpy(pPhyAddr[
3
], VirtualAddress_PHY, PAGE_SIZE);
}
while
(
0
);
/
/
ULONG_PTR ss3
=
pPhyAddr[
3
];
/
/
ULONG_PTR ss1
=
pPhyAddr[
1
];
/
/
ULONG_PTR ss2
=
pPhyAddr[
2
];
/
/
DbgBreakPoint();
/
/
4
修改PXE PPE PDE PTE从而改变
if
(IsPdeLager)
{
((PHARDWARE_PTE)(VirtualAddresss
+
PxeIndex
*
8
))
-
>PageFrameNumber
=
newPPEphy >>
12
;
return
TRUE;
}
((PHARDWARE_PTE)(VirtualAddresss
+
PxeIndex
*
8
))
-
>PageFrameNumber
=
newPPEphy >>
12
;
((PHARDWARE_PTE)(pPhyAddr[
0
]
+
PPEIndex
*
8
))
-
>PageFrameNumber
=
newPDEphy >>
12
;
((PHARDWARE_PTE)(pPhyAddr[
1
]
+
PDEIndex
*
8
))
-
>PageFrameNumber
=
newPTEphy >>
12
;
((PHARDWARE_PTE)(pPhyAddr[
2
]
+
PTEIndex
*
8
))
-
>PageFrameNumber
=
newphy >>
12
;
return
TRUE;