/* * TsmiHandleMemWrite * * Purpose: * * Patch vbox dll in memory. * * Warning: potential BSOD-generator due to nonstandard way of loading, take care with patch offsets. * */ NTSTATUS TsmiHandleMemWrite( _In_ PVOID SrcAddress, _In_ PVOID DestAddress, _In_ ULONG Size ) { PMDL mdl; NTSTATUS status = STATUS_SUCCESS; PAGED_CODE(); mdl = IoAllocateMdl(DestAddress, Size, FALSE, FALSE, NULL); if (mdl == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } if (DestAddress >= MmSystemRangeStart) if (!MmIsAddressValid(DestAddress)) { return STATUS_ACCESS_VIOLATION; } MmProbeAndLockPages(mdl, KernelMode, IoReadAccess); DestAddress = MmGetSystemAddressForMdlSafe(mdl, HighPagePriority); if (DestAddress != NULL) { status = MmProtectMdlSystemAddress(mdl, PAGE_EXECUTE_READWRITE); __movsb((PUCHAR)DestAddress, (const UCHAR *)SrcAddress, Size); MmUnmapLockedPages(DestAddress, mdl); MmUnlockPages(mdl); } else { status = STATUS_ACCESS_VIOLATION; } IoFreeMdl(mdl); return status; }
ULONGLONG GetKeServiceDescriptorTableShadow64() { #if 1 PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082); PUCHAR EndSearchAddress = StartSearchAddress + 0x500; PUCHAR i = NULL; UCHAR b1=0,b2=0,b3=0; ULONG templong=0; ULONGLONG addr=0; #if DBG //SetSoftBreakPoint(); #endif for(i=StartSearchAddress;i<EndSearchAddress;i++) { if( MmIsAddressValid(i) && MmIsAddressValid(i+1) && MmIsAddressValid(i+2) ) { b1=*i; b2=*(i+1); b3=*(i+2); if( b1==0x4c && b2==0x8d && b3==0x1d ) //4c8d1d { memcpy(&templong,i+3,4); addr = (ULONGLONG)templong + (ULONGLONG)i + 7; return addr; } } } #endif return 0; }
VOID GetKeServiceDescriptorTable() { PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082); PUCHAR EndSearchAddress = StartSearchAddress + 0x500; PUCHAR i = NULL; UCHAR b1 = 0, b2 = 0, b3 = 0; ULONG templong = 0; ULONGLONG addr = 0; for (i = StartSearchAddress; i<EndSearchAddress; i++) { if (MmIsAddressValid(i) && MmIsAddressValid(i + 1) && MmIsAddressValid(i + 1)) { b1 = *i; b2 = *(i + 1); b3 = *(i + 2); if (b1 == 0x4c && b2 == 0x8d && b3 == 0x15) //4c8d15 { memcpy(&templong, i + 3, 4); addr = (ULONGLONG)templong + (ULONGLONG)i + 7; KeServiceDescriptortable = addr; return; } } } KeServiceDescriptortable = 0; return; }
LARGE_INTEGER XpGetRegisterCallbackCookie(ULONG Address) { LARGE_INTEGER Cookie; ULONG Temp = 0; ULONG Item = 0; Cookie.QuadPart = 0; if (Address && MmIsAddressValid((PVOID)Address)) { Item = Address & 0xFFFFFFF8; if (MmIsAddressValid((PVOID)Item) && MmIsAddressValid((PVOID)(Item + 8))) { Temp = *(PULONG)(Item + 8); if (MmIsAddressValid((PVOID)Temp)) { Cookie.LowPart = *(PULONG)Temp; Cookie.HighPart = *(PULONG)(Temp + sizeof(ULONG)); } } } return Cookie; }
NTSTATUS GetDpcTimerInformation_x64(PDPC_TIMER_INFOR DpcTimerInfor) { ULONG CPUNumber = KeNumberProcessors; //系统变量 PUCHAR CurrentKPRCBAddress = NULL; PUCHAR CurrentTimerTableEntry = NULL; PLIST_ENTRY CurrentEntry = NULL; PLIST_ENTRY NextEntry = NULL; PULONG64 KiWaitAlways = NULL; PULONG64 KiWaitNever = NULL; int i = 0; int j = 0; int n = 0; PKTIMER Timer; typedef struct _KTIMER_TABLE_ENTRY { ULONG64 Lock; LIST_ENTRY Entry; ULARGE_INTEGER Time; } KTIMER_TABLE_ENTRY, *PKTIMER_TABLE_ENTRY; for(j=0; j<CPUNumber; j++) { KeSetSystemAffinityThread(j+1); //使当前线程运行在第一个处理器上 CurrentKPRCBAddress=(PUCHAR)__readmsr(0xC0000101) + 0x20; KeRevertToUserAffinityThread(); //恢复线程运行的处理器 CurrentTimerTableEntry=(PUCHAR)(*(ULONG64*)CurrentKPRCBAddress + 0x2200 + 0x200); FindKiWaitFunc(&KiWaitNever,&KiWaitAlways); //找KiWaitAlways 函数的地址 for(i=0; i<0x100; i++) { CurrentEntry = (PLIST_ENTRY)(CurrentTimerTableEntry + sizeof(KTIMER_TABLE_ENTRY) * i + 8); NextEntry = CurrentEntry->Blink; if( MmIsAddressValid(CurrentEntry) && MmIsAddressValid(CurrentEntry) ) { while( NextEntry != CurrentEntry ) { PKDPC RealDpc; //获得首地址 Timer = CONTAINING_RECORD(NextEntry,KTIMER,TimerListEntry); RealDpc=TransTimerDpcEx(Timer,*KiWaitNever,*KiWaitAlways); if( MmIsAddressValid(Timer)&&MmIsAddressValid(RealDpc)&&MmIsAddressValid(RealDpc->DeferredRoutine)) { if (DpcTimerInfor->ulCnt > DpcTimerInfor->ulRetCnt) { DpcTimerInfor->DpcTimer[n].Dpc = (ULONG64)RealDpc; DpcTimerInfor->DpcTimer[n].Period = Timer->Period; DpcTimerInfor->DpcTimer[n].TimeDispatch = (ULONG64)RealDpc->DeferredRoutine; DpcTimerInfor->DpcTimer[n].TimerObject = (ULONG64)Timer; n++; } DpcTimerInfor->ulRetCnt++; } NextEntry = NextEntry->Blink; } } } } }
uint64_t dtrace_fuword64(void *uaddr) { if ((uintptr_t)uaddr >= (uintptr_t)MM_HIGHEST_USER_ADDRESS || (uintptr_t)uaddr <= (uintptr_t) MM_LOWEST_USER_ADDRESS || MmIsAddressValid((PVOID) uaddr) == 0 || MmIsAddressValid((PVOID) ((UINT_PTR) uaddr + 7)) == 0) { DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); cpu_core[KeGetCurrentProcessorNumber()].cpuc_dtrace_illval = (uintptr_t)uaddr; return (0); } return (dtrace_fuword64_nocheck(uaddr)); }
IMAGE_DOS_HEADER *KernelGetModuleBaseByPtr(IN void *in_section, IN void *exported_name) { unsigned char *p; IMAGE_DOS_HEADER *dos; IMAGE_NT_HEADERS *nt; int count = 0; p = (unsigned char *)((uintptr_t)in_section & ~(PAGE_SIZE-1)); for(;p;p -= PAGE_SIZE) { count ++; // Dont go back too far. if (count > 0x800) { return NULL; }; __try { dos = (IMAGE_DOS_HEADER *)p; // If this address is not mapped in, there will be a BSOD // PAGE_FAULT_IN_NONPAGED_AREA so we check first. if(!MmIsAddressValid(dos)) { continue; } if(dos->e_magic != 0x5a4d) // MZ continue; nt = (IMAGE_NT_HEADERS *)((uintptr_t)dos + dos->e_lfanew); if((uintptr_t)nt >= (uintptr_t)in_section) continue; if((uintptr_t)nt <= (uintptr_t)dos) continue; if(!MmIsAddressValid(nt)) { continue; } if(nt->Signature != 0x00004550) // PE continue; break; // Ignore potential errors. } __except(EXCEPTION_CONTINUE_EXECUTION) {} } return dos; }
PUNICODE_STRING GetVADName(PMMVAD pVad) { PFILE_OBJECT pFileObject = NULL; pFileObject = GetFileObject(pVad); if (MmIsAddressValid((PULONG)pFileObject) == FALSE) return NULL; if (MmIsAddressValid((PULONG)((PUCHAR)&pFileObject->FileName)) == FALSE) return NULL; /* IoQueryFileDosDeviceName */ return &pFileObject->FileName; }
VOID KernelKillThreadRoutine( __in PKAPC Apc, __in __out PKNORMAL_ROUTINE* NormalRoutine, __in __out PVOID* NormalContext, __in __out PVOID* SystemArgument1, __in __out PVOID* SystemArgument2 ) { PULONG ThreadFlags = NULL; UNREFERENCED_PARAMETER(Apc); UNREFERENCED_PARAMETER(NormalRoutine); UNREFERENCED_PARAMETER(NormalContext); UNREFERENCED_PARAMETER(SystemArgument1); UNREFERENCED_PARAMETER(SystemArgument2); BDKitFreePool(Apc); //ETHREAD中CrossThreadFlags的偏移量为0x248 ThreadFlags=(PULONG)((ULONG)PsGetCurrentThread()+0x248); if( MmIsAddressValid(ThreadFlags) ) { *ThreadFlags |= PS_CROSS_THREAD_FLAGS_SYSTEM; //(*PspExitThread_XP)(STATUS_SUCCESS);//PspExitThread不可用,需要自己定位 PsTerminateSystemThread (STATUS_SUCCESS); } }
PCONTROL_AREA GetControlArea(PMMVAD pVad) { if (MmIsAddressValid(pVad) == FALSE || pVad == NULL) return NULL; return (PCONTROL_AREA)pVad->ControlArea; }
/* * @unimplemented */ BOOLEAN NTAPI MmIsNonPagedSystemAddressValid(IN PVOID VirtualAddress) { DPRINT1("WARNING: %s returns bogus result\n", __FUNCTION__); return MmIsAddressValid(VirtualAddress); }
unsigned int getAddressOfShadowTable() { unsigned int i; unsigned char *p; unsigned int dwordatbyte; p = (unsigned char*) KeAddSystemServiceTable; for(i = 0; i < 4096; i++, p++) { __try { dwordatbyte = *(unsigned int*)p; } __except(EXCEPTION_EXECUTE_HANDLER) { return 0; } if(MmIsAddressValid((PVOID)dwordatbyte)) { if(memcmp((PVOID)dwordatbyte, &KeServiceDescriptorTable, 16) == 0) { if((PVOID)dwordatbyte == &KeServiceDescriptorTable) { continue; } return dwordatbyte; } } } return 0; }
// HelpMapMMIOSpace: Map MMIO space bool HelpMapMMIOSpace( uint64 address, // IN size_t size, // IN uint64* mappedAddress, // OUT uint64* mappedSize) // OUT { bool result = false; void* pLinearAddress = NULL; PHYSICAL_ADDRESS physicalAddress; ResetPoolMemory(&physicalAddress, sizeof(PHYSICAL_ADDRESS)); physicalAddress.QuadPart = address; pLinearAddress = static_cast<PUCHAR>(MmMapIoSpace(physicalAddress, size, MmNonCached)); if (NULL != pLinearAddress) { if (MmIsAddressValid(pLinearAddress)) { *mappedAddress = reinterpret_cast<uint64>(pLinearAddress); *mappedSize = size; result = true; } else { MmUnmapIoSpace(pLinearAddress, size); } } return result; }
ULONG GetAddressOfShadowTable() { ULONG uAddress = 0; ULONG i = 0; PULONG pAddress = (PULONG)KeAddSystemServiceTable; for (i = 0; i < 4096; i++, pAddress++) { __try { uAddress = *pAddress; } __except(EXCEPTION_EXECUTE_HANDLER) { return 0; } if (MmIsAddressValid((PVOID)uAddress)) { if (RtlEqualMemory((PVOID)uAddress, &KeServiceDescriptorTable, sizeof(ULONG))) { if ((PVOID)uAddress == &KeServiceDescriptorTable) { continue; } return uAddress; } } } return 0; }
BOOLEAN HookByInline(ULONG target, ULONG myfake, char *pFunName) { kprintf("Inline Hooking %s from %X to %X\r\n", pFunName, target, myfake); if (!MmIsAddressValid(PVOID(target))) { kprintf("Target is not available\r\n"); return 1; } LONG mysrc,mydst; mysrc = target; mydst = myfake; HOOKINFO *pHI = (PHOOKINFO)kmalloc(sizeof(HOOKINFO)); if (pHI==NULL) { return FALSE; } #define JMPLEN 5 RtlZeroMemory(pHI, sizeof(HOOKINFO)); ULONG itmp=0; UCHAR JmpCode[JMPLEN]={0xe9,0,0,0,0}; itmp = mydst-mysrc-JMPLEN; *(PULONG)&JmpCode[1]= itmp; RtlCopyMemory(pHI->szOldCode, (PUCHAR)mysrc, JMPLEN); memcpy((PUCHAR)mysrc, JmpCode, JMPLEN); pHI->NewAddress = mydst; pHI->OldCodeSize = JMPLEN; pHI->OriAddress = mysrc; RtlCopyMemory(pHI->szFunName, pFunName, strlen(pFunName)); InsertTailList(&g_HookInfoListHead,&pHI->Next ); return 1; }
/* 获取影子表的地址 */ PVOID GetShadowTableAddress() { ULONG dwordatbyte,i; PUCHAR p = (PUCHAR)KeAddSystemServiceTable; for(i = 0; i < PAGE_SIZE; i++, p++)// 往下找一页 指针递增1 { __try { dwordatbyte = *(PULONG)p; } __except(EXCEPTION_EXECUTE_HANDLER) { return FALSE; } if(MmIsAddressValid((PVOID)dwordatbyte)) { if(memcmp((PVOID)dwordatbyte, KeServiceDescriptorTable, 16) == 0)//对比前16字节 相同则找到 { if((PVOID)dwordatbyte == KeServiceDescriptorTable)//排除自己 { continue; } return (PVOID)dwordatbyte; } } } return FALSE; }
/** * Tries a set against the current kernel. * * @retval @c true if it matched up, global variables are updated. * @retval @c false otherwise (no globals updated). * @param pSet The data set. * @param pbPrcb Pointer to the processor control block. * @param pszVendor Pointer to the processor vendor string. * @param pOsVerInfo The OS version info. */ static bool rtR0NtTryMatchSymSet(PCRTNTSDBSET pSet, uint8_t *pbPrcb, const char *pszVendor, PCRTNTSDBOSVER pOsVerInfo) { /* * Don't bother trying stuff where the NT kernel version number differs, or * if the build type or SMPness doesn't match up. */ if ( pSet->OsVerInfo.uMajorVer != pOsVerInfo->uMajorVer || pSet->OsVerInfo.uMinorVer != pOsVerInfo->uMinorVer || pSet->OsVerInfo.fChecked != pOsVerInfo->fChecked || (!pSet->OsVerInfo.fSmp && pOsVerInfo->fSmp /*must-be-smp*/) ) { //DbgPrint("IPRT: #%d Version/type mismatch.\n", pSet - &g_artNtSdbSets[0]); return false; } /* * Do the CPU vendor test. * * Note! The MmIsAddressValid call is the real #PF security here as the * __try/__except has limited/no ability to catch everything we need. */ char *pszPrcbVendorString = (char *)&pbPrcb[pSet->KPRCB.offVendorString]; if (!MmIsAddressValid(&pszPrcbVendorString[4 * 3 - 1])) { //DbgPrint("IPRT: #%d invalid vendor string address.\n", pSet - &g_artNtSdbSets[0]); return false; } __try { if (memcmp(pszPrcbVendorString, pszVendor, RT_MIN(4 * 3, pSet->KPRCB.cbVendorString)) != 0) { //DbgPrint("IPRT: #%d Vendor string mismatch.\n", pSet - &g_artNtSdbSets[0]); return false; } } __except(EXCEPTION_EXECUTE_HANDLER) { DbgPrint("IPRT: %#d Exception\n", pSet - &g_artNtSdbSets[0]); return false; } /* * Got a match, update the global variables and report succcess. */ g_offrtNtPbQuantumEnd = pSet->KPRCB.offQuantumEnd; g_cbrtNtPbQuantumEnd = pSet->KPRCB.cbQuantumEnd; g_offrtNtPbDpcQueueDepth = pSet->KPRCB.offDpcQueueDepth; #if 0 DbgPrint("IPRT: Using data set #%u for %u.%usp%u build %u %s %s.\n", pSet - &g_artNtSdbSets[0], pSet->OsVerInfo.uMajorVer, pSet->OsVerInfo.uMinorVer, pSet->OsVerInfo.uCsdNo, pSet->OsVerInfo.uBuildNo, pSet->OsVerInfo.fSmp ? "smp" : "uni", pSet->OsVerInfo.fChecked ? "checked" : "free"); #endif return true; }
ULONG_PTR GetShutdownDispatch(PDEVICE_OBJECT DeviceObject) { PDRIVER_OBJECT DriverObject = NULL; ULONG_PTR ShutdownDispatch = 0; if (DeviceObject && MmIsAddressValid((PVOID)DeviceObject)) { DriverObject = DeviceObject->DriverObject; if (DriverObject && MmIsAddressValid((PVOID)DriverObject)) { ShutdownDispatch = (ULONG_PTR)DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]; } } return ShutdownDispatch; }
// verify if the given ptr points to a valid address BOOL IsGoodPtr( PVOID ptr, ULONG size ) { ULONG i = 0; for(i=0; i<size; i++) if( !MmIsAddressValid( (PULONG)ptr+i) ) return FALSE; return TRUE; }
PFILE_OBJECT GetFileObject(PMMVAD pVad) { PCONTROL_AREA pControlArea = NULL; pControlArea = GetControlArea(pVad); if (MmIsAddressValid((PULONG)pControlArea) == FALSE) return NULL; return (PFILE_OBJECT)pControlArea->FilePointer; }
/* * TsmiHandleMemWrite * * Purpose: * * Patch vbox dll in memory. * * Warning: If compiled not in ReleaseSigned configuration this function is a * potential BSOD-generator due to nonstandard way of loading, take care with patch offsets. * */ NTSTATUS TsmiHandleMemWrite( _In_ PVOID SrcAddress, _In_ PVOID DestAddress, _In_ ULONG Size ) { PMDL mdl; NTSTATUS status = STATUS_SUCCESS; PAGED_CODE(); mdl = IoAllocateMdl(DestAddress, Size, FALSE, FALSE, NULL); if (mdl == NULL) { #ifdef _DEBUGMSG DbgPrint("[TSMI] Failed to create MDL at write\n"); #endif return STATUS_INSUFFICIENT_RESOURCES; } #ifdef _SIGNED_BUILD __try { #endif //_SIGNED_BUILD if (DestAddress >= MmSystemRangeStart) if (!MmIsAddressValid(DestAddress)) { #ifdef _DEBUGMSG DbgPrint("[TSMI] Invalid address\n"); #endif //_DEBUGMSG return STATUS_ACCESS_VIOLATION; } MmProbeAndLockPages(mdl, KernelMode, IoReadAccess); DestAddress = MmGetSystemAddressForMdlSafe(mdl, HighPagePriority); if (DestAddress != NULL) { status = MmProtectMdlSystemAddress(mdl, PAGE_EXECUTE_READWRITE); __movsb((PUCHAR)DestAddress, (const UCHAR *)SrcAddress, Size); MmUnmapLockedPages(DestAddress, mdl); MmUnlockPages(mdl); } else { status = STATUS_ACCESS_VIOLATION; } #ifdef _SIGNED_BUILD } __except (EXCEPTION_EXECUTE_HANDLER) { status = STATUS_ACCESS_VIOLATION; #ifdef _DEBUGMSG DbgPrint("[TSMI] MmProbeAndLockPages failed at write DestAddress = %p\n", DestAddress); #endif //_DEBUGMSG } #endif //_SIGNED_BUILD IoFreeMdl(mdl); return status; }
int fasttrap_copyout(void * kaddr, void * uaddr, int len) { if (MmIsAddressValid(uaddr)) { RtlCopyMemory((void *)uaddr, (void *)kaddr, len); return 0; } else { dprintf("fastrap.sys: fasttrap_copyout() failed for %p\n", uaddr); return 1; } }
void ShowProcess( PETHREAD pOldThread, PETHREAD pNewThread ) { ULONG index = 0; if( MmIsAddressValid( (PULONG)((ULONG)pNewThread+0x220) ) ) { PEPROCESS pAddr = (PEPROCESS)(*(PULONG)((ULONG)pNewThread+0x220 )); if( MmIsAddressValid( pAddr ) ) { for( index = 0; index < count; index++ ) { if( pEProcess[index] == pAddr ) break; } if( index == count ) pEProcess[count++] = pAddr; } } }
NTSTATUS DumpKernelMemory(PVOID DstAddr, PVOID SrcAddr, ULONG Size) { PMDL pSrcMdl, pDstMdl; PUCHAR pAddress, pDstAddress; NTSTATUS st = STATUS_UNSUCCESSFUL; ULONG r; // Создаем MDL для буфера-источника pSrcMdl = IoAllocateMdl(SrcAddr, Size, FALSE, FALSE, NULL); if (pSrcMdl) { // Построение MDL MmBuildMdlForNonPagedPool(pSrcMdl); // Получение адреса из MDL pAddress = (PUCHAR)MmGetSystemAddressForMdlSafe(pSrcMdl, NormalPagePriority); zDbgPrint("pAddress = %x", pAddress); if (pAddress != NULL) { pDstMdl = IoAllocateMdl(DstAddr, Size, FALSE, FALSE, NULL); zDbgPrint("pDstMdl = %x", pDstMdl); if (pDstMdl != NULL) { __try { MmProbeAndLockPages(pDstMdl, KernelMode, IoWriteAccess); pDstAddress = (PUCHAR)MmGetSystemAddressForMdlSafe(pDstMdl, NormalPagePriority); zDbgPrint("pDstAddress = %x", pDstAddress); if (pDstAddress != NULL) { memset(pDstAddress, 0, Size); zDbgPrint("Copy block"); for (r = 1; r < Size; r++) { if (MmIsAddressValid(pAddress)) *pDstAddress = *pAddress; else *pDstAddress = 0; pAddress++; pDstAddress++; } st = STATUS_SUCCESS; } MmUnlockPages(pDstMdl); } __except(EXCEPTION_EXECUTE_HANDLER) { zDbgPrint("Copy block exception"); } IoFreeMdl(pDstMdl); } }
/* Stores 64 bits of data to the user-space address base */ int suword64(void *base, int64_t word) { if (MmIsAddressValid(base)) { RtlCopyMemory(base, &word, sizeof(int64_t)); return 0; } else { dprintf("fasttrap.sys: fuword64 failed for %p\n", base); return -1; } }
/* Fetches 64 bits of data from the user-space address base */ int64_t fuword64(void *base) { int64_t ret; if (MmIsAddressValid(base)) { RtlCopyMemory(&ret, base, sizeof(int64_t)); return ret; } else { dprintf("fasttrap.sys: fuword64 failed for %p\n", base); return -1; } }
BOOLEAN IsUnicodeStringValid(PUNICODE_STRING uniString) { BOOLEAN bRet = FALSE; __try { if (uniString->Length > 0 && uniString->Buffer && MmIsAddressValid(uniString->Buffer) && MmIsAddressValid(&uniString->Buffer[uniString->Length / sizeof(WCHAR) - 1])) { bRet = TRUE; } } __except(EXCEPTION_EXECUTE_HANDLER) { bRet = FALSE; } return bRet; }
CBinTreeWalker( __in const TYPE** root, __in size_t parentOffset, __in size_t leftChildOffset, __in size_t rightChildOffset, __in size_t sanityMask = ~0x0 ) : m_root(root), m_parentOffset(parentOffset), m_leftChildOffset(leftChildOffset), m_rightChildOffset(rightChildOffset), m_sanityMask(sanityMask) { ASSERT(m_root && MmIsAddressValid((void*)m_root) && sanityMask); }
NTSTATUS RemoveDPCTimer(PVOID InBuffer) { PREMOVE_DPCTIMER Temp = (PREMOVE_DPCTIMER)InBuffer; ULONG_PTR TimerObject = Temp->TimerObject; if (TimerObject&&MmIsAddressValid((PVOID)TimerObject)) { if (KeCancelTimer((PKTIMER)TimerObject)) { return STATUS_SUCCESS; } } return STATUS_UNSUCCESSFUL; }
//取得指定虚拟地址的内容 bool HyGetSysValCore(PVOID addr,PVOID buf,size_t size) { bool bRet = false; if(!MmIsAddressValid(addr)) { PRINT("[%s]err : MmIsAddrValid Failed!\n",__func__); goto QUIT; } RtlCopyMemory(buf,addr,size); bRet = true; QUIT: return bRet; }