能力值:
( LV2,RANK:10 )
|
-
-
2 楼
进入流程解析机器码的时候又错了,无法解析。
|
能力值:
( LV8,RANK:130 )
|
-
-
3 楼
你用之前还是查一下WDK中ProbeForRead的用法啊!
The ProbeForRead routine checks that a user-mode buffer actually resides in the user portion of the address space, and is correctly aligned.
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
|
能力值:
( LV4,RANK:50 )
|
-
-
5 楼
代码 明明检测的是一个地址
但你在接下来的判断语句中 直接读了 这个地址+N的内存 很多情况下 这样的代码可以正常运行
但逻辑上 明显是错误的。
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
以下摘自A-Protect源码
c文件
#include "FuncAddrValid.h"
__inline ULONG CR4()
{
// mov eax, cr4
__asm _emit 0x0F __asm _emit 0x20 __asm _emit 0xE0
}
BOOLEAN
MmIsSystemAddressAccessable(
PVOID VirtualAddress
)
/*++
Routine Description
For a given virtual address this function returns TRUE if the address
is accessable without an access violation (it may incur a page fault).
Arguments
VirtualAddress
Address to be checked
Return value
TRUE if address may be safely accessed, FALSE otherwise
--*/
{
if (CR4() & PAE_ON)
{
PMMPTE_PAE PointerPte;
PointerPte = MiGetPdeAddressPae (VirtualAddress);
if ((PointerPte->u.Long.QuadPart == MM_ZERO_PTE) ||
(PointerPte->u.Long.QuadPart == MM_ZERO_KERNEL_PTE) ||
(PointerPte->u.Soft.Protection == MM_ZERO_ACCESS))
{
return FALSE;
}
PointerPte = MiGetPteAddressPae (VirtualAddress);
if ((PointerPte->u.Long.QuadPart == MM_ZERO_PTE) ||
(PointerPte->u.Long.QuadPart == MM_ZERO_KERNEL_PTE) ||
(PointerPte->u.Soft.Protection == MM_ZERO_ACCESS))
{
return FALSE;
}
}
else
{
PMMPTE PointerPte;
PointerPte = MiGetPdeAddress (VirtualAddress);
if ((PointerPte->u.Long == MM_ZERO_PTE) ||
(PointerPte->u.Long == MM_ZERO_KERNEL_PTE) ||
(PointerPte->u.Soft.Protection == MM_ZERO_ACCESS))
{
return FALSE;
}
PointerPte = MiGetPteAddress (VirtualAddress);
if ((PointerPte->u.Long == MM_ZERO_PTE) ||
(PointerPte->u.Long == MM_ZERO_KERNEL_PTE) ||
(PointerPte->u.Soft.Protection == MM_ZERO_ACCESS))
{
return FALSE;
}
}
return TRUE;
}
#if 0
extern "C" extern ULONG KiBugCheckData;
VOID MmAllowPageFaultsAtRaisedIrql ()
/**
Allow page faults at raised IRQL
*/
{
//
// KiTrap0E performs check if KiBugCheckData == 0.
// If so, KiTrap0E calls KeBugCheckEx(IRQL_NOT_LESS_OR_EQUAL,...)
// if not, it calls MmAccessFault and resolves fault.
//
KiBugCheckData = 0xFFFFFFFF;
}
VOID MmForbidPageFaultsAtRaisedIrql ()
{
KiBugCheckData = 0;
}
#endif
// Irql < DISPATCH_LEVEL
VOID MmMakeAddressWritable (PVOID VirtualAddress, BOOLEAN Write)
{
PMMPTE_PAE PointerPte_Pae;
PMMPTE PointerPte;
ULONG t;
ASSERT (MmIsSystemAddressAccessable(VirtualAddress));
// load page
t = *(ULONG*)VirtualAddress;
// make it writable
if (CR4() & PAE_ON)
{
PointerPte_Pae = MiGetPteAddressPae (VirtualAddress);
PointerPte_Pae->u.Hard.Write = Write;
}
else
{
PointerPte = MiGetPteAddress (VirtualAddress);
PointerPte->u.Hard.Valid = Write;
}
}
PMDL LockMem(PVOID Buffer, ULONG Size)
{
PMDL Mdl;
ULONG i;
Mdl = IoAllocateMdl (Buffer, Size, FALSE, FALSE, NULL);
if (Mdl)
{
//KdPrint(("LOCKMEM: Mdl allocated at %X\n", Mdl));
__try
{
for (i=0; i<Size; i++)
{
((UCHAR*)Buffer)[i] = ((UCHAR*)Buffer)[i];
}
KdPrint (("LOCKMEM: Loaded pages\n"));
MmProbeAndLockPages (Mdl, KernelMode, IoWriteAccess);
KdPrint (("LOCKMEM: Mdl probed and locked\n"));
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
IoFreeMdl (Mdl);
//KdPrint(("LockMem: MmProbeAndLock pages failed with exception code %X\n", GetExceptionCode()));
return NULL;
}
return Mdl;
}
//KdPrint(("LockMem: IoAllocateMdl failed\n"));
return NULL;
}
VOID UnlockMem (PMDL Mdl)
{
MmUnlockPages (Mdl);
IoFreeMdl (Mdl);
}
VALIDITY_CHECK_STATUS MmIsAddressValidExNotPae(
IN PVOID Pointer
)
{
VALIDITY_CHECK_STATUS Return = VCS_INVALID;
MMPTE* Pde;
MMPTE* Pte;
MMPTE pte;
Pde = MiGetPdeAddress(Pointer);
//KdPrint(("PDE is 0x%08x\n", Pde));
if( Pde->u.Hard.Valid )
{
//KdPrint(("PDE entry is valid, PTE PFN=%08x\n", Pde->u.Hard.PageFrameNumber));
Pte = MiGetPteAddress(Pointer);
//KdPrint(("PTE is 0x%08x\n", Pte));
if( Pte->u.Hard.Valid )
{
//KdPrint(("PTE entry is valid, PFN=%08x\n", Pte->u.Hard.PageFrameNumber));
Return = VCS_VALID;
}
else
{
//
// PTE is not valid
//
pte = *Pte;
//KdPrint(("Got invalid PTE [%08x]: Proto=%d,Transition=%d,Protection=0x%x,PageFilePFN=0x%x\n",
// pte.u.Long,
// pte.u.Soft.Prototype,
// pte.u.Soft.Transition,
// pte.u.Soft.Protection,
// pte.u.Soft.PageFileHigh));
if( pte.u.Long )
{
if( pte.u.Soft.Prototype == 1 )
{
//KdPrint(("PTE entry is not valid, points to prototype PTE.\n"));
// more accurate check should be performed here for pointed prototype PTE!
Return = VCS_PROTOTYPE;
}
else // not a prototype PTE
{
if( pte.u.Soft.Transition != 0 )
{
//
// This is a transition page. Consider it invalid.
//
//KdPrint(("PTE entry is not valid, points to transition page.\n"));
Return = VCS_TRANSITION;
}
else if (pte.u.Soft.PageFileHigh == 0)
{
//
// Demand zero page
//
//KdPrint(("PTE entry is not valid, points to demand-zero page.\n"));
Return = VCS_DEMANDZERO;
}
else
{
//
// Pagefile PTE
//
if( pte.u.Soft.Transition == 0 )
{
//KdPrint(("PTE entry is not valid, VA is paged out (PageFile offset=%08x)\n",
// pte.u.Soft.PageFileHigh));
Return = VCS_PAGEDOUT;
}
else
{
//KdPrint(("PTE entry is not valid, Refault\n"));
}
}
}
}
else
{
//KdPrint(("PTE entry is completely invalid\n"));
}
}
}
else
{
//KdPrint(("PDE entry is not valid\n"));
}
return Return;
}
VALIDITY_CHECK_STATUS MmIsAddressValidExPae(
IN PVOID Pointer
)
{
VALIDITY_CHECK_STATUS Return = VCS_INVALID;
MMPTE_PAE* Pde;
MMPTE_PAE* Pte;
MMPTE_PAE pte;
Pde = MiGetPdeAddressPae(Pointer);
//KdPrint(("PDE is at 0x%08x\n", Pde));
if( Pde->u.Hard.Valid )
{
//KdPrint(("PDE entry is valid, PTE PFN=%08x\n", Pde->u.Hard.PageFrameNumber));
if( Pde->u.Hard.LargePage != 0 )
{
//
// This is a large 2M page
//
//KdPrint(("! PDE points to large 2M page\n"));
Pte = Pde;
}
else
{
//
// Small 4K page
//
// Get its PTE
Pte = MiGetPteAddressPae(Pointer);
}
//KdPrint(("PTE is at 0x%08x\n", Pte));
if( Pte->u.Hard.Valid )
{
//KdPrint(("PTE entry is valid, PFN=%08x\n", Pte->u.Hard.PageFrameNumber));
Return = VCS_VALID;
}
else
{
//
// PTE is not valid
//
pte = *Pte;
//KdPrint(("Got invalid PTE [%08x%08x]\n", pte.u.Long.HighPart, pte.u.Long.LowPart));
if( pte.u.Long.LowPart == 0 )
{
//KdPrint(("PTE entry is completely invalid (page is not committed or is within VAD tree)\n"));
}
else
{
if( pte.u.Soft.Prototype == 1 )
{
// //KdPrint(("PTE entry is not valid, points to prototype PTE. Protection=%x[%s], ProtoAddress=%x\n",
// (ULONG)pte.u.Proto.Protection,
// MiPageProtectionString((UCHAR)pte.u.Proto.Protection),
// (ULONG)pte.u.Proto.ProtoAddress));
// more accurate check should be performed here for pointed prototype PTE!
Return = VCS_PROTOTYPE;
}
else // not a prototype PTE
{
if( pte.u.Soft.Transition != 0 )
{
//
// This is a transition page.
//
// //KdPrint(("PTE entry is not valid, points to transition page. PFN=%x, Protection=%x[%s]\n",
// (ULONG)pte.u.Trans.PageFrameNumber,
// (ULONG)pte.u.Trans.Protection,
// MiPageProtectionString((UCHAR)pte.u.Trans.Protection)));
Return = VCS_TRANSITION;
}
else if (pte.u.Soft.PageFileHigh == 0)
{
//
// Demand zero page
//
// //KdPrint(("PTE entry is not valid, points to demand-zero page. Protection=%x[%s]\n",
// (ULONG)pte.u.Soft.Protection,
// MiPageProtectionString((UCHAR)pte.u.Soft.Protection)));
Return = VCS_DEMANDZERO;
}
else
{
//
// Pagefile PTE
//
if( pte.u.Soft.Transition == 0 )
{
// //KdPrint(("PTE entry is not valid, VA is paged out. PageFile Offset=%08x, Protection=%x[%s]\n",
// (ULONG)pte.u.Soft.PageFileHigh,
// (ULONG)pte.u.Soft.Protection,
// MiPageProtectionString((UCHAR)pte.u.Soft.Protection)));
Return = VCS_PAGEDOUT;
}
else
{
//KdPrint(("PTE entry is not valid, Refault\n"));
}
}
}
}
}
}
else
{
//KdPrint(("PDE entry is not valid\n"));
}
return Return;
}
VALIDITY_CHECK_STATUS MiIsAddressValidEx(
IN PVOID Pointer
)
{
if( CR4() & PAE_ON ) {
return MmIsAddressValidExPae(Pointer);
}
else {
return MmIsAddressValidExNotPae(Pointer);
}
}
BOOL MmIsAddressValidEx(
IN PVOID Pointer
)
{
VALIDITY_CHECK_STATUS MmRet;
ULONG ulTry;
if (!ARGUMENT_PRESENT(Pointer) ||
!Pointer){
return FALSE;
}
/*
//VCS_TRANSITION、VCS_PAGEDOUT内存居然是这样子~~擦~
lkd> dd f8ad5ad8
f8ad5ad8 ???????? ???????? ???????? ????????
f8ad5ae8 ???????? ???????? ???????? ????????
f8ad5af8 ???????? ???????? ???????? ????????
f8ad5b08 ???????? ???????? ???????? ????????
f8ad5b18 ???????? ???????? ???????? ????????
f8ad5b28 ???????? ???????? ???????? ????????
f8ad5b38 ???????? ???????? ???????? ????????
f8ad5b48 ???????? ???????? ???????? ????????
*/
MmRet = MiIsAddressValidEx(Pointer);
if (MmRet != VCS_VALID){
return FALSE;
}
return TRUE;
}
BOOL MmIsAddressRangeValid(
IN PVOID Address,
IN ULONG Size
)
{
ULONG Ptr = 0;
VALIDITY_CHECK_STATUS MmRet;
for(Ptr = (ULONG)Address; Ptr <= (ULONG)Address + Size; Ptr++)
{
MmRet = MiIsAddressValidEx((PVOID)Ptr);
if (MmRet != VCS_VALID){
return FALSE;
}
}
return TRUE;
}
h文件
#include "ntifs.h"
typedef struct _MMPTE_SOFTWARE {
ULONG Valid : 1;
ULONG PageFileLow : 4;
ULONG Protection : 5;
ULONG Prototype : 1;
ULONG Transition : 1;
ULONG PageFileHigh : 20;
} MMPTE_SOFTWARE;
typedef struct _MMPTE_TRANSITION {
ULONG Valid : 1;
ULONG Write : 1;
ULONG Owner : 1;
ULONG WriteThrough : 1;
ULONG CacheDisable : 1;
ULONG Protection : 5;
ULONG Prototype : 1;
ULONG Transition : 1;
ULONG PageFrameNumber : 20;
} MMPTE_TRANSITION;
typedef struct _MMPTE_PROTOTYPE {
ULONG Valid : 1;
ULONG ProtoAddressLow : 7;
ULONG ReadOnly : 1; // if set allow read only access.
ULONG WhichPool : 1;
ULONG Prototype : 1;
ULONG ProtoAddressHigh : 21;
} MMPTE_PROTOTYPE;
typedef struct _MMPTE_HARDWARE {
ULONG Valid : 1;
ULONG Write : 1; // UP version
ULONG Owner : 1;
ULONG WriteThrough : 1;
ULONG CacheDisable : 1;
ULONG Accessed : 1;
ULONG Dirty : 1;
ULONG LargePage : 1;
ULONG Global : 1;
ULONG CopyOnWrite : 1; // software field
ULONG Prototype : 1; // software field
ULONG reserved : 1; // software field
ULONG PageFrameNumber : 20;
} MMPTE_HARDWARE, *PMMPTE_HARDWARE;
typedef struct _MMPTE {
union {
ULONG Long;
MMPTE_HARDWARE Hard;
MMPTE_PROTOTYPE Proto;
MMPTE_SOFTWARE Soft;
MMPTE_TRANSITION Trans;
} u;
} MMPTE, *PMMPTE;
typedef struct _MMPTE_SOFTWARE_PAE {
ULONGLONG Valid : 1;
ULONGLONG PageFileLow : 4;
ULONGLONG Protection : 5;
ULONGLONG Prototype : 1;
ULONGLONG Transition : 1;
ULONGLONG Unused : 20;
ULONGLONG PageFileHigh : 32;
} MMPTE_SOFTWARE_PAE;
typedef struct _MMPTE_TRANSITION_PAE {
ULONGLONG Valid : 1;
ULONGLONG Write : 1;
ULONGLONG Owner : 1;
ULONGLONG WriteThrough : 1;
ULONGLONG CacheDisable : 1;
ULONGLONG Protection : 5;
ULONGLONG Prototype : 1;
ULONGLONG Transition : 1;
ULONGLONG PageFrameNumber : 24;
ULONGLONG Unused : 28;
} MMPTE_TRANSITION_PAE;
typedef struct _MMPTE_PROTOTYPE_PAE {
ULONGLONG Valid : 1;
ULONGLONG Unused0: 7;
ULONGLONG ReadOnly : 1; // if set allow read only access. LWFIX: remove
ULONGLONG Unused1: 1;
ULONGLONG Prototype : 1;
ULONGLONG Protection : 5;
ULONGLONG Unused: 16;
ULONGLONG ProtoAddress: 32;
} MMPTE_PROTOTYPE_PAE;
typedef struct _MMPTE_HARDWARE_PAE {
ULONGLONG Valid : 1;
ULONGLONG Write : 1; // UP version
ULONGLONG Owner : 1;
ULONGLONG WriteThrough : 1;
ULONGLONG CacheDisable : 1;
ULONGLONG Accessed : 1;
ULONGLONG Dirty : 1;
ULONGLONG LargePage : 1;
ULONGLONG Global : 1;
ULONGLONG CopyOnWrite : 1; // software field
ULONGLONG Prototype : 1; // software field
ULONGLONG reserved0 : 1; // software field
ULONGLONG PageFrameNumber : 24;
ULONGLONG reserved1 : 28; // software field
} MMPTE_HARDWARE_PAE, *PMMPTE_HARDWARE_PAE;
typedef struct _MMPTE_PAE {
union {
LARGE_INTEGER Long;
MMPTE_HARDWARE_PAE Hard;
MMPTE_PROTOTYPE_PAE Proto;
MMPTE_SOFTWARE_PAE Soft;
MMPTE_TRANSITION_PAE Trans;
} u;
} MMPTE_PAE;
typedef MMPTE_PAE *PMMPTE_PAE;
#define PTE_BASE 0xC0000000
#define PDE_BASE 0xC0300000
#define PDE_BASE_PAE 0xc0600000
#define MiGetPdeAddress(va) ((MMPTE*)(((((ULONG)(va)) >> 22) << 2) + PDE_BASE))
#define MiGetPteAddress(va) ((MMPTE*)(((((ULONG)(va)) >> 12) << 2) + PTE_BASE))
#define MiGetPdeAddressPae(va) ((PMMPTE_PAE)(PDE_BASE_PAE + ((((ULONG)(va)) >> 21) << 3)))
#define MiGetPteAddressPae(va) ((PMMPTE_PAE)(PTE_BASE + ((((ULONG)(va)) >> 12) << 3)))
#define MM_ZERO_PTE 0
#define MM_ZERO_KERNEL_PTE 0
#define MM_ZERO_ACCESS 0 // this value is not used.
#define MM_READONLY 1
#define MM_EXECUTE 2
#define MM_EXECUTE_READ 3
#define MM_READWRITE 4 // bit 2 is set if this is writable.
#define MM_WRITECOPY 5
#define MM_EXECUTE_READWRITE 6
#define MM_EXECUTE_WRITECOPY 7
#define MM_NOCACHE 8
#define PAE_ON (1<<5)
typedef enum VALIDITY_CHECK_STATUS{
VCS_INVALID,
VCS_VALID,
VCS_TRANSITION,
VCS_PAGEDOUT,
VCS_DEMANDZERO,
VCS_PROTOTYPE
}VALIDITY_CHECK_STATUS;
PCHAR MiProtectionToString[] = {
"MM_ZERO_ACCESS", // 0 // this value is not used.
"MM_READONLY", // 1
"MM_EXECUTE", // 2
"MM_EXECUTE_READ", // 3
"MM_READWRITE", // 4 // bit 2 is set if this is writable.
"MM_WRITECOPY", // 5
"MM_EXECUTE_READWRITE", // 6
"MM_EXECUTE_WRITECOPY", // 7
"MM_NOCACHE" // 8
};
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
能给个正确的写法吗,不太熟悉这块。
|
能力值:
( LV4,RANK:50 )
|
-
-
8 楼
代码逻辑上就是错的 跟熟不熟悉完全无关
况且6楼已经贴出了完整的检测函数 还在问代码要怎么写? 还举白旗投降 ?
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
我也是菜鸟一只,我也遇到过这样的问题,对于检测,我感觉6楼的代码很精细。
但是明明这块内存里面确实应该有值,但是取出来就是非法的,这个该怎么办?怎么才能访问到里面的值呢
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
感谢,很有参考价值。
|