能力值:
( LV5,RANK:65 )
|
-
-
26 楼
不懂,MARK一下!
|
能力值:
(RANK:290 )
|
-
-
27 楼
#ifndef PTE_SHIFT
#define PTE_SHIFT 3
#endif
#ifndef PTI_SHIFT
#define PTI_SHIFT 12
#endif
#ifndef PDI_SHIFT
#define PDI_SHIFT 21
#endif
#ifndef PPI_SHIFT
#define PPI_SHIFT 30
#endif
#ifndef PXI_SHIFT
#define PXI_SHIFT 39
#endif
#define VIRTUAL_ADDRESS_BITS 48
#define VIRTUAL_ADDRESS_MASK ((((ULONG_PTR)1) << VIRTUAL_ADDRESS_BITS) - 1)
#define PXE_PER_PAGE 512
#define PXI_MASK (PXE_PER_PAGE - 1)
#define MiGetPxeOffset(va) \
((ULONG)(((ULONG_PTR)(va) >> PXI_SHIFT) & PXI_MASK))
#define MiGetPxeAddress(va) \
((PMMPTE)PXE_BASE + MiGetPxeOffset(va))
#define MiGetPpeAddress(va) \
((PMMPTE)(((((ULONG_PTR)(va) & VIRTUAL_ADDRESS_MASK) >> PPI_SHIFT) << PTE_SHIFT) + PPE_BASE))
#define MiGetPdeAddress(va) \
((PMMPTE)(((((ULONG_PTR)(va) & VIRTUAL_ADDRESS_MASK) >> PDI_SHIFT) << PTE_SHIFT) + PDE_BASE))
#define MiGetPteAddress(va) \
((PMMPTE)(((((ULONG_PTR)(va) & VIRTUAL_ADDRESS_MASK) >> PTI_SHIFT) << PTE_SHIFT) + PTE_BASE))
namespace PETMAP
{
typedef struct _PXXPHYSICAL_
{
ULONG64 Pte_PhyAddress;
ULONG64 Pde_PhyAddress;
ULONG64 Ppe_PhyAddress;
ULONG64 Pxe_PhyAddress;
PULONG64 Pte_Address;
PULONG64 Pde_Address;
PULONG64 Ppe_Address;
PULONG64 Pxe_Address;
}*PPXXPHYSICAL,PXXPHYSICAL;
typedef struct _PXXINDX_
{
ULONG64 Pte_Index;
ULONG64 Pde_Index;
ULONG64 Ppe_Index;
ULONG64 Pxe_Index;
}*PPXXINDXL,PXXINDX;
static PXXINDX pxxindex_info = {0};
static PXXPHYSICAL pxxphysical_base_info = {0};
static PVOID Pte_Base = NULL;
static PVOID Pde_Base = NULL;
static PVOID Ppe_Base = NULL;
static PVOID Pxe_Base = NULL;
LONGLONG QuadPart;
PVOID MiGetAddress(ULONG64 VirtualAddress){
return (PVOID)(((uintptr_t)VirtualAddress & 0xfff) + reinterpret_cast<ULONG64>(Pte_Base));
}
PVOID MiGetPXXAddress(ULONG64 VirtualAddress){
return (PVOID)(((VirtualAddress >> 9) & 0x7FFFFFFFF8) + reinterpret_cast<ULONG64>(Pte_Base));
}
PVOID MmGetPteAddress(ULONG64 VirtualAddress){
return ((PVOID)(((((ULONG_PTR)(VirtualAddress) & VIRTUAL_ADDRESS_MASK) >> PTI_SHIFT) << PTE_SHIFT) + reinterpret_cast<ULONG64>(Pte_Base)));
}
PVOID MmGetPdeAddress(ULONG64 VirtualAddress){
return ((PVOID)(((((ULONG_PTR)(VirtualAddress) & VIRTUAL_ADDRESS_MASK) >> PDI_SHIFT) << PTE_SHIFT) + reinterpret_cast<ULONG64>(Pde_Base)));
}
PVOID MmGetPpeAddress(ULONG64 VirtualAddress){
return ((PVOID)(((((ULONG_PTR)(VirtualAddress) & VIRTUAL_ADDRESS_MASK) >> PPI_SHIFT) << PTE_SHIFT) + reinterpret_cast<ULONG64>(Ppe_Base)));
}
PVOID MmGetPxeAddress(ULONG64 VirtualAddress){
return ((PMMPTE)Pxe_Base + MiGetPxeOffset(VirtualAddress));
}
PVOID MiGetXXXAddress(ULONG64 VirtualAddress, PVOID PteBase)
{
return (PVOID)(((VirtualAddress >> 9) & 0x7FFFFFFFF8) + (ULONG64)PteBase);
}
NTSTATUS MmGetVirtualPxxPhyAddressEx(ULONG64 VirtualAddress,PPXXPHYSICAL VirtualInfor)
{
__faststorefence();
PULONG64 Pte_PhyAddress = reinterpret_cast<PULONG64>(MmGetPteAddress(VirtualAddress));
PULONG64 Pde_PhyAddress = reinterpret_cast<PULONG64>(MmGetPdeAddress(VirtualAddress));
PULONG64 Ppe_PhyAddress = reinterpret_cast<PULONG64>(MmGetPpeAddress(VirtualAddress));
PULONG64 Pxe_PhyAddress = reinterpret_cast<PULONG64>(MmGetPxeAddress(VirtualAddress));
if (MmIsAddressValid(Pte_PhyAddress))
{
VirtualInfor->Pte_Address = Pte_PhyAddress;
VirtualInfor->Pte_PhyAddress = *reinterpret_cast<PULONG64>(Pte_PhyAddress);
}
if (MmIsAddressValid(Pde_PhyAddress))
{
VirtualInfor->Pde_Address = Pde_PhyAddress;
VirtualInfor->Pde_PhyAddress = *reinterpret_cast<PULONG64>(Pde_PhyAddress);
}
if (MmIsAddressValid(Ppe_PhyAddress))
{
VirtualInfor->Ppe_Address = Ppe_PhyAddress;
VirtualInfor->Ppe_PhyAddress = *reinterpret_cast<PULONG64>(Ppe_PhyAddress);
}
if (MmIsAddressValid(Pxe_PhyAddress))
{
VirtualInfor->Pxe_Address = Pxe_PhyAddress;
VirtualInfor->Pxe_PhyAddress = *reinterpret_cast<PULONG64>(Pxe_PhyAddress);
}
return STATUS_SUCCESS;
}
NTSTATUS MmGetVirtualPxxPhyAddress(ULONG64 VirtualAddress){
if (MmIsAddressValid(Pte_Base)&&MmIsAddressValid(Ppe_Base)&&MmIsAddressValid(Pxe_Base)&&MmIsAddressValid(Pde_Base)){
PULONG64 Pte_PhyAddress = reinterpret_cast<PULONG64>(MmGetPteAddress(VirtualAddress));
PULONG64 Pde_PhyAddress = reinterpret_cast<PULONG64>(MmGetPdeAddress(VirtualAddress));
PULONG64 Ppe_PhyAddress = reinterpret_cast<PULONG64>(MmGetPpeAddress(VirtualAddress));
PULONG64 Pxe_PhyAddress = reinterpret_cast<PULONG64>(MmGetPxeAddress(VirtualAddress));
if (MmIsAddressValid(Pte_PhyAddress)){
pxxphysical_base_info.Pte_Address = Pte_PhyAddress;
pxxphysical_base_info.Pte_PhyAddress = *reinterpret_cast<PULONG64>(Pte_PhyAddress);
}
if (MmIsAddressValid(Pde_PhyAddress)){
pxxphysical_base_info.Pde_Address = Pde_PhyAddress;
pxxphysical_base_info.Pde_PhyAddress = *reinterpret_cast<PULONG64>(Pde_PhyAddress);
}
if (MmIsAddressValid(Ppe_PhyAddress)){
pxxphysical_base_info.Ppe_Address = Ppe_PhyAddress;
pxxphysical_base_info.Ppe_PhyAddress = *reinterpret_cast<PULONG64>(Ppe_PhyAddress);
}
if (MmIsAddressValid(Pxe_PhyAddress)){
pxxphysical_base_info.Pxe_Address = Pxe_PhyAddress;
pxxphysical_base_info.Pxe_PhyAddress = *reinterpret_cast<PULONG64>(Pxe_PhyAddress);
}
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
VOID MmGetVirtualPxxIndex(ULONG64 VirtualAddress){
pxxindex_info.Pxe_Index = (VirtualAddress >> 0x27) & 0x1FF;
pxxindex_info.Ppe_Index = (VirtualAddress >> 0x1E) & 0x1FF;
pxxindex_info.Pde_Index = (VirtualAddress >> 0x15) & 0x1FF;
pxxindex_info.Pte_Index = (VirtualAddress >> 0xC) & 0x1FF;
}
LONG MmSetPhyAddressPointer(PVOID volatile *Target,_In_opt_ LONG64 Value){
PVOID OldValue = InterlockedExchangePointer (Target,(PVOID)Value);
return reinterpret_cast<LONG>(OldValue);
}
ULONG64 MmSetPhyAddress64(PVOID volatile Target,_In_opt_ ULONG64 Value){
PULONG64 m_Target = reinterpret_cast<PULONG64>(Target);
ULONG64 value;
if (MmIsAddressValid(Target)){
value = *m_Target;
*m_Target = Value;
}
return value;
}
NTSTATUS MmCreateNewTable(PVOID Address,int Index,ULONG64 ShadowPhyAddress,ULONG64 PhyAddress)
{
ULONG64 flags = PhyAddress & 0xFF00000000000FFF;
ULONG64 new_pteflags = ShadowPhyAddress&~0xFF00000000000FFF|flags; //保持原本属性
NTSTATUS Status = STATUS_SUCCESS;
if (MmIsAddressValid(Address)){
*(PULONG64)((ULONG64)Address + Index * 8) = new_pteflags;
}
else
Status = STATUS_UNSUCCESSFUL;
return Status;
}
}
KIRQL wpoff()
{
KIRQL irql = KeRaiseIrqlToDpcLevel();
ULONG_PTR cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
_disable();
__writecr0(cr0);
return irql;
}
VOID wpon(KIRQL irql)
{
ULONG_PTR cr0 = __readcr0();
cr0 |= 0x10000;
__writecr0(cr0);
_enable();
KeLowerIrql(irql);
}
VOID Hook(UINT64 Address, UINT64 ProxAddress)
{
UCHAR code[]= "\xFF\x25\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
KIRQL irql = wpoff();
KIRQL dpc_irql = KeRaiseIrqlToDpcLevel();
memcpy(code + 6, &ProxAddress, 8);
memcpy((PVOID)Address, &code, 14);
KeLowerIrql(dpc_irql);
wpon(irql);
}
NTSTATUS RtlMapCopyMemroy(PVOID BaseAddress,PVOID TartAddress,SIZE_T Size)
{
PMDL pMDL = IoAllocateMdl(BaseAddress,Size,FALSE,FALSE,NULL);
NTSTATUS Status = STATUS_UNSUCCESSFUL;
if (!pMDL) return Status;
MmBuildMdlForNonPagedPool(pMDL);
__try{
MmProbeAndLockPages(pMDL,KernelMode,IoWriteAccess);
}
__except(EXCEPTION_EXECUTE_HANDLER){
DBG("MmProbeAndLockPages erro\n");
}
__try{
PVOID pMapedAddr = MmMapLockedPagesSpecifyCache(pMDL,KernelMode,MmCached,NULL,FALSE,NormalPagePriority);
memcpy(BaseAddress,pMapedAddr,Size); Status = STATUS_SUCCESS;
}
__except(EXCEPTION_EXECUTE_HANDLER){
DBG(("erro\n"));
}
return Status;
}
NTSTATUS RtlMapCopyMemroy(PVOID BaseAddress,PVOID TartAddress,SIZE_T Size)
{
PMDL pMDL = IoAllocateMdl(BaseAddress,Size,FALSE,FALSE,NULL);
NTSTATUS Status = STATUS_UNSUCCESSFUL;
if (!pMDL) return Status;
MmBuildMdlForNonPagedPool(pMDL);
__try{
MmProbeAndLockPages(pMDL,KernelMode,IoWriteAccess);
}
__except(EXCEPTION_EXECUTE_HANDLER){
DBG("MmProbeAndLockPages erro\n");
}
__try{
PVOID pMapedAddr = MmMapLockedPagesSpecifyCache(pMDL,KernelMode,MmCached,NULL,FALSE,NormalPagePriority);
memcpy(BaseAddress,pMapedAddr,Size); Status = STATUS_SUCCESS;
}
__except(EXCEPTION_EXECUTE_HANDLER){
DBG(("erro\n"));
}
return Status;
}
NTSTATUS PTE_Hook(ULONG64 VirtualAddress)
{
NTSTATUS status;
PETMAP::Pte_Base = (PVOID)PTE_BASE;
PETMAP::Pxe_Base = (PVOID)PXE_BASE;
PETMAP::Ppe_Base = (PVOID)PPE_BASE;
PETMAP::Pde_Base = (PVOID)PDE_BASE;
PETMAP::MmGetVirtualPxxIndex(VirtualAddress);
DBG("VirtualAddress Pte_Index 0x%x\n",PETMAP::pxxindex_info.Pte_Index);
DBG("VirtualAddress Pde_Index 0x%x\n",PETMAP::pxxindex_info.Pde_Index);
DBG("VirtualAddress Ppe_Index 0x%x\n",PETMAP::pxxindex_info.Ppe_Index);
DBG("VirtualAddress Pxe_Index 0x%x\n",PETMAP::pxxindex_info.Pxe_Index);
PETMAP::MmGetVirtualPxxPhyAddress(VirtualAddress);
DBG("VirtualAddress Pte_PhyAddress 0x%p\n",PETMAP::pxxphysical_base_info.Pte_PhyAddress);
DBG("VirtualAddress Pde_PhyAddress 0x%p\n",PETMAP::pxxphysical_base_info.Pde_PhyAddress);
DBG("VirtualAddress Ppe_PhyAddress 0x%p\n",PETMAP::pxxphysical_base_info.Ppe_PhyAddress);
DBG("VirtualAddress Pxe_PhyAddress 0x%p\n",PETMAP::pxxphysical_base_info.Pxe_PhyAddress);
DBG("VirtualAddress Pte_Address 0x%p\n",PETMAP::pxxphysical_base_info.Pte_Address);
DBG("VirtualAddress Pde_Address 0x%p\n",PETMAP::pxxphysical_base_info.Pde_Address);
DBG("VirtualAddress Ppe_Address 0x%p\n",PETMAP::pxxphysical_base_info.Ppe_Address);
DBG("VirtualAddress Pxe_Address 0x%p\n",PETMAP::pxxphysical_base_info.Pxe_Address);
DBG("VirtualAddress 0x%p\n",VirtualAddress);
FuncOffset = VirtualAddress & 0xFFF;
DbgPrint("VirtualAddress Pxe_Address 0x%p\n",PETMAP::pxxphysical_base_info.Pxe_Address + FuncOffset);
DbgPrint("VirtualAddress FuncOffset 0x%p\n",FuncOffset);
LARGE_INTEGER High,Low;
DWORD64 ImageBase = 0;
UNWIND_HISTORY_TABLE HistoryTable;
ULONG SizeOfImage ;
RtlLookupFunctionEntry(VirtualAddress,&ImageBase,&HistoryTable);
DBG("VirtualAddress ImageBase 0x%p\n",ImageBase);
if (MmIsAddressValid((PVOID)ImageBase))
SizeOfImage = RtlImageNtHeader((PVOID)ImageBase)->OptionalHeader.SizeOfImage;
DBG("SizeOfImage 0x%p\n",SizeOfImage);
High.QuadPart = ~0;
PUCHAR m_new_pte_pageble = (PUCHAR)MmAllocateContiguousMemorySpecifyCache(SizeOfImage, Low, High, RtlConvertUlongToLargeInteger(0), MmCached);
if (MmIsAddressValid(m_new_pte_pageble)){
status = RtlMapCopyMemroy(m_new_pte_pageble,(PVOID)ImageBase,SizeOfImage);
if (NT_SUCCESS(status))
{
PHYSICAL_ADDRESS new_funtion_pte_phy;
DWORD64 m_funtion_offset = (PUCHAR)VirtualAddress - (PUCHAR)ImageBase;
PUCHAR m_funtion = m_new_pte_pageble + m_funtion_offset;
new_funtion_pte_phy = MmGetPhysicalAddress(m_funtion);
ULONG64 flags = PETMAP::pxxphysical_base_info.Pte_PhyAddress & 0xFF00000000000FFF;
ULONG64 new_pteflags = new_funtion_pte_phy.QuadPart&~0xFF00000000000FFF|flags;
PETMAP::MmSetPhyAddress64(PETMAP::pxxphysical_base_info.Pte_Address,new_pteflags);
Hook((UINT64)m_funtion,(UINT64)NewNtVmd);
}
}
__invlpg(&DirectoryTableBase);
return STATUS_SUCCESS;
}
来Pte 也是ok 的 HOOK 几个页面
最后于 2021-4-8 18:55
被viphack编辑
,原因:
|
能力值:
( LV3,RANK:30 )
|
-
-
28 楼
看了一下不知道理解的是否正确: 0.PG只会在SYSTEM进程的虚拟内存空间中校验内核代码 1.在一个进程运行前,通过改变页表,将原本所有进程共享的,有内核代码的,物理页单独为新进程准备一份。 2.我们HOOK自己准备的物理页,这样在SYSTEM中的PG,扫描不到我们HOOK的物理页。 几个问题: 0. 单独替换一个PTE不可以么? 1.为SYSTEM复制一份物理页,这样PG扫的永远是复制的,我们随便HOOK其他的,是否可行(被注释部分的代码是做这个的么)?
|
能力值:
( LV2,RANK:10 )
|
-
-
29 楼
小白养的菜鸡
看了一下不知道理解的是否正确:
0.PG只会在SYSTEM进程的虚拟内存空间中校验内核代码
1.在一个进程运行前,通过改变页表,将原本所有进程共享的,有内核代码的,物理页单独为新进程准备一份。
...
应该是这样
|
能力值:
( LV3,RANK:30 )
|
-
-
30 楼
yy虫子yy
应该是这样
哈哈哈哈刚才还在看你的triple fault
|
能力值:
( LV2,RANK:10 )
|
-
-
31 楼
小白养的菜鸡
哈哈哈哈刚才还在看你的triple fault
那个是CPU指令缺陷引起的,看我最后面的回复 https://bbs.pediy.com/thread-258766-2.htm
|
能力值:
( LV1,RANK:0 )
|
-
-
32 楼
只改NtOpenProcess的PTE好像也可以达到相同的目的吧
|
能力值:
( LV1,RANK:0 )
|
-
-
33 楼
小白养的菜鸡
看了一下不知道理解的是否正确:
0.PG只会在SYSTEM进程的虚拟内存空间中校验内核代码
1.在一个进程运行前,通过改变页表,将原本所有进程共享的,有内核代码的,物理页单独为新进程准备一份。
...
被注销的代码应该是失败的代码,他本来应该是想给system一个假的物理页,让PG检测不到,但是运行中的进程无法修改页表,所以他想挂起进程,修改之后再恢复,但是我猜system进程挂起来之后电脑就死了,所以折中了一下
|
能力值:
( LV4,RANK:50 )
|
-
-
34 楼
只是推迟了触发PG,并没有完全避免PG的触发
|
能力值:
( LV2,RANK:10 )
|
-
-
35 楼
感谢亲亲,KeDelayExecutionThread这个函数帮助了我
|