static NTSTATUS GetNtoskrnlRegion(PVOID* pNtoskrnlStart,PVOID* pNtoskrnlEnd) { PMODULES pModules=(PMODULES)&pModules; ULONG rc,uNeededSize; if (!pNtoskrnlStart || !pNtoskrnlEnd) return STATUS_UNSUCCESSFUL; // get system modules - ntoskrnl is always first there rc=ZwQuerySystemInformation(SystemModuleInformation,pModules,4,&uNeededSize); if (rc==STATUS_INFO_LENGTH_MISMATCH) { pModules=ExAllocatePool(PagedPool,uNeededSize); RtlZeroMemory(pModules,uNeededSize); rc=ZwQuerySystemInformation(SystemModuleInformation,pModules,uNeededSize,NULL); } if (!NT_SUCCESS(rc)) { #ifdef DEBUG DbgPrint("GetNtoskrnlRegion(): strange NtQuerySystemInformation()!\n"); #endif return STATUS_NTOSKRNL_NOT_FOUND; } *pNtoskrnlStart=pModules->smi.Base; *pNtoskrnlEnd=(PUCHAR)pModules->smi.Base+pModules->smi.Size; ExFreePool(pModules); return STATUS_SUCCESS; }
NTSTATUS GatherKernelStats(BALLOON_STAT stats[VIRTIO_BALLOON_S_NR]) { SYSTEM_BASIC_INFORMATION basicInfo; SYSTEM_PERFORMANCE_INFORMATION perfInfo; ULONG outLen = 0; NTSTATUS ntStatus; ULONG idx = 0; UINT64 SoftFaults; RtlZeroMemory(&basicInfo,sizeof(basicInfo)); RtlZeroMemory(&perfInfo,sizeof(perfInfo)); ntStatus = ZwQuerySystemInformation(SystemBasicInformation, &basicInfo, sizeof(basicInfo), &outLen); if(!NT_SUCCESS(ntStatus)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "GatherKernelStats (SystemBasicInformation) failed 0x%08x (outLen=0x%x)\n", ntStatus, outLen); return ntStatus; } if ((!bBasicInfoWarning)&&(outLen != sizeof(basicInfo))) { bBasicInfoWarning = TRUE; TraceEvents(TRACE_LEVEL_WARNING, DBG_HW_ACCESS, "GatherKernelStats (SystemBasicInformation) expected outLen=0x%08x returned with 0x%0x", sizeof(basicInfo), outLen); } ntStatus = ZwQuerySystemInformation(SystemPerformanceInformation, &perfInfo, sizeof(perfInfo), &outLen); if(!NT_SUCCESS(ntStatus)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "GatherKernelStats (SystemPerformanceInformation) failed 0x%08x (outLen=0x%x)\n", ntStatus, outLen); return ntStatus; } if ((!bPerfInfoWarning)&&(outLen != sizeof(perfInfo))) { bPerfInfoWarning = TRUE; TraceEvents(TRACE_LEVEL_WARNING, DBG_HW_ACCESS, "GatherKernelStats (SystemPerformanceInformation) expected outLen=0x%08x returned with 0x%0x", sizeof(perfInfo), outLen); } #define UpdateNoOverflow(x) UpdateOverflowFreeCounter(&Counters[_##x],perfInfo.##x) UpdateStat(&stats[idx++], VIRTIO_BALLOON_S_SWAP_IN, UpdateNoOverflow(PageReadCount) << PAGE_SHIFT); UpdateStat(&stats[idx++], VIRTIO_BALLOON_S_SWAP_OUT, (UpdateNoOverflow(DirtyPagesWriteCount) + UpdateNoOverflow(MappedPagesWriteCount)) << PAGE_SHIFT); SoftFaults = UpdateNoOverflow(CopyOnWriteCount) + UpdateNoOverflow(TransitionCount) + UpdateNoOverflow(CacheTransitionCount) + UpdateNoOverflow(DemandZeroCount); UpdateStat(&stats[idx++], VIRTIO_BALLOON_S_MAJFLT, UpdateNoOverflow(PageReadCount)); UpdateStat(&stats[idx++], VIRTIO_BALLOON_S_MINFLT, SoftFaults); UpdateStat(&stats[idx++], VIRTIO_BALLOON_S_MEMFREE, U32_2_S64(perfInfo.AvailablePages) << PAGE_SHIFT); UpdateStat(&stats[idx++], VIRTIO_BALLOON_S_MEMTOT, U32_2_S64(basicInfo.NumberOfPhysicalPages) << PAGE_SHIFT); #undef UpdateNoOverflow return ntStatus; }
/*通过ZwQuerySystemInformation获取驱动信息*/ PVOID GetKernelModuleInfo(CHAR *DriverName) { NTSTATUS status; ULONG ulSize; PMODULES pModuleList; char *lpszKernelName=NULL; ULONG i; PSYSTEM_MODULE_INFORMATION pSmi = NULL; ULONG uCount; PVOID pDriverBase = NULL; status=ZwQuerySystemInformation( 11, NULL, 0, &ulSize ); if (status!=STATUS_INFO_LENGTH_MISMATCH) { return NULL; } pModuleList=(PMODULES)ExAllocatePool(NonPagedPool,ulSize); if (!pModuleList) { return NULL; } status=ZwQuerySystemInformation( 11, pModuleList, ulSize, &ulSize ); if (!NT_SUCCESS(status)) { CodeVprint("ZwQuerySystemInformation error:0X%x\r\n",status); ExFreePool(pModuleList); return NULL; } uCount = pModuleList->ulCount; pSmi = (PSYSTEM_MODULE_INFORMATION)((ULONG)pModuleList + sizeof(ULONG)); for (i = 0; i<uCount;i++) { lpszKernelName = pSmi->ModuleNameOffset+pSmi->ImageName; if (_stricmp(lpszKernelName,DriverName) == 0) { pDriverBase = (PVOID)(pSmi->Base); break; } pSmi++; } if (pModuleList) { ExFreePool(pModuleList); } return pDriverBase; }
DWORD GetProcessIdByName(const wchar_t * pszProcessName) { DWORD nRet = 0; #define UsingNTApi(x) pfn_##x x = NULL; {\ x = (pfn_##x)::GetProcAddress(::GetModuleHandleA( \ "ntdll.dll"), #x); \ if (NULL == x) { \ ::RaiseException( \ EXCEPTION_ACCESS_VIOLATION, \ EXCEPTION_NONCONTINUABLE, \ 0, \ NULL); \ } \ } typedef NTSTATUS (NTAPI *pfn_ZwQuerySystemInformation)( IN ULONG SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength ); UsingNTApi(ZwQuerySystemInformation); if (!ZwQuerySystemInformation) return nRet; ULONG cbNeeded = 0; ZwQuerySystemInformation(5, NULL, 0, &cbNeeded); if (cbNeeded < 1) return nRet; PVOID pProcEs = (PVOID)malloc(cbNeeded + 2); if (!pProcEs) return nRet; if (!(NT_SUCCESS(ZwQuerySystemInformation( 5, pProcEs, cbNeeded, NULL)))) { free(pProcEs); return nRet; } PSYSTEM_PROCESSES pProc = (PSYSTEM_PROCESSES)pProcEs; do { pProc = (PSYSTEM_PROCESSES)((char *)pProc + pProc->NextEntryDelta); if (wcsncmp(pProc->ProcessName.Buffer, pszProcessName, wcslen(pszProcessName))) continue; nRet = pProc->ProcessId; break; } while (pProc->NextEntryDelta != 0); free(pProcEs); return nRet; }
BOOL LoadKernelImg() { PVOID buffer; NTSTATUS status; DWORD dwLength = 0; BOOL ret = FALSE; PSYSTEM_MODULE_INFORMATION sysMod; char *start; if(KernelHandle != NULL) return TRUE; ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, &dwLength); if(dwLength == 0) goto _LoadKernelImgExit; buffer = new char[dwLength]; if(buffer == NULL) goto _LoadKernelImgExit; status = ZwQuerySystemInformation(SystemModuleInformation, buffer, dwLength, &dwLength); if(!NT_SUCCESS(status)) goto _LoadKernelImgExit; sysMod = (PSYSTEM_MODULE_INFORMATION)buffer; //获得内核基地址 KernelImgBase = sysMod->Module[0].Base; //组合出内核文件路径 dwLength = GetSystemDirectoryA(KernelImgName, sizeof(KernelImgName)); if(KernelImgName[dwLength - 1] != '\\') { KernelImgName[dwLength++] = '\\'; KernelImgName[dwLength] = 0; } start = sysMod->Module[0].ImageName + sysMod->Module[0].PathLength; if(*start == '\\') start++; while(*start) { KernelImgName[dwLength++] = *start; start++; } KernelImgName[dwLength] = 0; KernelHandle = LoadLibraryA(KernelImgName); if(KernelHandle == NULL) goto _LoadKernelImgExit; ret = TRUE; _LoadKernelImgExit: if(buffer) delete[] buffer; return ret; }
//List loaded modules (we only need the first one, which is the kernel) PMODULE_LIST GetModuleList(){ NTSTATUS NtStatus; ULONG ulNeededSize; PULONG pulModuleList; ZwQuerySystemInformation(SystemModuleInformation, &ulNeededSize, 0, &ulNeededSize); pulModuleList = ExAllocatePoolWithTag(PagedPool, ulNeededSize, 'mlst'); NtStatus = ZwQuerySystemInformation(SystemModuleInformation, pulModuleList, ulNeededSize, 0); if(!NT_SUCCESS(NtStatus)){ DbgPrint("ZwQuerySystemInformation failed! ulNeededSize = %ul, NtStatus = %u.\n", ulNeededSize, NtStatus); } return (PMODULE_LIST) pulModuleList; }
NTSTATUS EnumKrnlModByZwQuerySysInfo(PULONG numOfDrv, PDRVMOD_ITEM pDrvItem) { NTSTATUS status=STATUS_SUCCESS; PSYSTEM_MODULE_INFORMATION pDrvModInfo=NULL; PVOID pDrvtmp=NULL; ULONG dwRetSize=0; ULONG drvNums=0; ULONG i; ULONG pDrvObject=0; WCHAR wName[256]; WCHAR wPath[256]; //获取大小 status=ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, &dwRetSize); //申请内存 pDrvtmp = ExAllocatePoolWithTag(PagedPool, dwRetSize, 'tmp'); //dwRetSize 需要的大小 if (pDrvtmp) { //再次执行,将枚举结果放到指定的内存区域 status=ZwQuerySystemInformation(SystemModuleInformation, pDrvtmp, dwRetSize, NULL); if ( NT_SUCCESS(status) ) { //模块数 drvNums = *( (PULONG)pDrvtmp ); //模块链表头指针 pDrvModInfo=(PSYSTEM_MODULE_INFORMATION)( (PULONG)pDrvtmp + 1 ); for (i=0; i< drvNums; i++) { // DbgPrint("驱动名:%s\n", pDrvModInfo[i].imagePath+pDrvModInfo[i].imageNameOffset); //获取驱动对象 GetDrvObjectByName(pDrvModInfo[i].imagePath+pDrvModInfo[i].imageNameOffset, &pDrvObject); //转换驱动名 CharStringToWideChar(TRUE, pDrvModInfo[i].imagePath+pDrvModInfo[i].imageNameOffset, wName); //转换驱动路径 CharStringToWideChar(TRUE, pDrvModInfo[i].imagePath, wPath); //存储驱动信息 StoreOrCheckKrnlMod(TRUE, wName, (ULONG)pDrvModInfo[i].ImageBase, pDrvModInfo[i].ImageSize, pDrvObject, wPath, pDrvModInfo[i].LoadOrderIndex, numOfDrv, pDrvItem); } KdPrint(("EnumKrnlModByZwQuerySysInfo()->驱动模块:%d个\n", drvNums )); } ExFreePoolWithTag(pDrvtmp, 'tmp'); } return status; }
PVOID GetInfoTable(IN SYSTEM_INFORMATION_CLASS ATableType) { ULONG mSize = 0x2000; PVOID mPtr = NULL; NTSTATUS status; PAGED_CODE(); do { mPtr = ExAllocatePoolWithTag( PagedPool, mSize, INFO_MEM_TAG); if (mPtr) { status = ZwQuerySystemInformation(ATableType, mPtr, mSize, &mSize); } else { return NULL; } if (!NT_SUCCESS(status)) { ExFreePoolWithTag( mPtr, INFO_MEM_TAG); KdPrint(("SYS:GetInfoTable:The buf len is too small,need size %d\n", mSize)); } } while (status == STATUS_INFO_LENGTH_MISMATCH); if (NT_SUCCESS(status)) { return mPtr; } else { KdPrint(("SYS:GetInfoTable Fail(Error:0x%08x)", status)); return NULL; } }
static NTSTATUS _getModuleList ( PSYSTEM_MODULE_INFORMATION *ppModuleList ) { NTSTATUS status = STATUS_INFO_LENGTH_MISMATCH; SIZE_T allocSize = 0; ULONG retLen = 0; while (status == STATUS_INFO_LENGTH_MISMATCH) { allocSize = retLen; //incase the list grew since the last call allocSize += 0x1000; status = STATUS_MEMORY_NOT_ALLOCATED; if (NULL != *ppModuleList) { ExFreePool(*ppModuleList); *ppModuleList = NULL; } if (NULL != (*ppModuleList = ExAllocatePool(NonPagedPool, allocSize))) { status = ZwQuerySystemInformation(11, *ppModuleList, (ULONG)allocSize, &retLen); } } return status; }
PVOID NTAPI GetSystemInformation ( SYSTEM_INFORMATION_CLASS InfoClass ) { NTSTATUS Status; PVOID Buffer; ULONG Size = PAGE_SIZE; do { Buffer = halloc (Size); Status = ZwQuerySystemInformation ( InfoClass, Buffer, Size, &Size ); if (Status == STATUS_INFO_LENGTH_MISMATCH) hfree (Buffer); } while (Status == STATUS_INFO_LENGTH_MISMATCH); if (!NT_SUCCESS(Status)) { hfree (Buffer); return NULL; } return Buffer; }
//获取当前函数对应的模块 BOOL SetFunctionModuleName(PServiceTableInfo serviceTableInfo) { NTSTATUS status; DWORD dwLength = 0, dwLength2, i, j, address, index; memset(serviceTableInfo->CurrentModuleName, 0, sizeof(serviceTableInfo->CurrentModuleName)); ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, &dwLength); if(dwLength == 0) return FALSE; if(SystemModuleInfo != NULL) delete[] SystemModuleInfo; SystemModuleInfo = (PSYSTEM_MODULE_INFORMATION)(new BYTE[dwLength]); status = ZwQuerySystemInformation(SystemModuleInformation, SystemModuleInfo, dwLength, &dwLength2); if(!NT_SUCCESS(status)) { delete[] SystemModuleInfo; SystemModuleInfo = NULL; return FALSE; } for(i = 0; i < serviceTableInfo->Count; ++i) { address = (DWORD)serviceTableInfo->CurrentAddress[i]; index = -1; for(j = 0; j < SystemModuleInfo->Count; ++j) { if(address >= (DWORD)SystemModuleInfo->Module[j].Base && address <= (DWORD)SystemModuleInfo->Module[j].Base + SystemModuleInfo->Module[j].Size) { index = j; break; } } if(index == -1) continue; serviceTableInfo->CurrentModuleName[i] = SystemModuleInfo->Module[index].ImageName; } return TRUE; }
/* Dynamically binding to ntdll.dll * From Windows NT/2000 Native API Reference */ PVOID FindNT() { ULONG n, *q; PSYSTEM_MODULE_INFORMATION p; PVOID ntdll=NULL; ZwQuerySystemInformation(SystemModuleInformation, &n, 0, &n); q = (ULONG *) ExAllocatePool(PagedPool, n); ZwQuerySystemInformation(SystemModuleInformation, q, n*sizeof(*q), 0); p = (PSYSTEM_MODULE_INFORMATION)(q+1); for (n=0; n<*q; n++) { if (_stricmp(p[n].ImageName + p[n].ModuleNameOffset, "ntdll.dll")==0) ntdll = p[n].Base; } ExFreePool(q); return ntdll; }
PSYSTEM_HANDLE_INFORMATION_EX GetInfoTable(OUT PULONG nSize) { PVOID Buffer; NTSTATUS status; Buffer =ExAllocatePool(PagedPool,0x1000); status = ZwQuerySystemInformation(SystemHandleInformation, Buffer, 0x1000, nSize); ExFreePool(Buffer); if(status == STATUS_INFO_LENGTH_MISMATCH) { Buffer = ExAllocatePool(NonPagedPool, *nSize); status = ZwQuerySystemInformation(SystemHandleInformation, Buffer, *nSize, NULL); if(NT_SUCCESS(status)) { return (PSYSTEM_HANDLE_INFORMATION_EX)Buffer; } } return (PSYSTEM_HANDLE_INFORMATION_EX)0; }
MY_SYSTEM_HANDLE_INFORMATION * enumerateHandles() { MY_SYSTEM_HANDLE_INFORMATION shi = {0}; MY_SYSTEM_HANDLE_INFORMATION *shiTable; unsigned long shiTableSize; int status = ZwQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemHandleInformation, &shi, sizeof(MY_SYSTEM_HANDLE_INFORMATION), &shiTableSize); //TODO: check status shiTable = (MY_SYSTEM_HANDLE_INFORMATION*)ExAllocatePoolWithTag(NonPagedPool,shiTableSize,0xdeadbeef); status = ZwQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemHandleInformation, shiTable, shiTableSize, 0); return shiTable; }
PVOID GetUndocumentFunctionAdress() { ULONG size,index; PULONG buf; ULONG i; PSYSTEM_MODULE_INFORMATION module; PVOID driverAddress=0; ULONG ntosknlBase; ULONG ntosknlEndAddr; ULONG curAddr; NTSTATUS status; PVOID retAddr; ULONG code1_sp2=0x8b55ff8b,code2_sp2=0x0cec83ec,code3_sp2=0xfff84d83,code4_sp2=0x7d8b5756; ZwQuerySystemInformation(SystemModuleInformation,&size, 0, &size); if(NULL==(buf = (PULONG)ExAllocatePool(PagedPool, size))) { DbgPrint("failed alloc memory failed \n"); return 0; } status=ZwQuerySystemInformation(SystemModuleInformation,buf, size , 0); if(!NT_SUCCESS( status )) { DbgPrint("failed query\n"); return 0; } module = (PSYSTEM_MODULE_INFORMATION)(( PULONG )buf + 1); ntosknlEndAddr=(ULONG)module->Base+(ULONG)module->Size; ntosknlBase=(ULONG)module->Base; curAddr=ntosknlBase; ExFreePool(buf); for (i=curAddr;i<=ntosknlEndAddr;i++) { if ((*((ULONG *)i)==code1_sp2)&&(*((ULONG *)(i+4))==code2_sp2)&&(*((ULONG *)(i+8))==code3_sp2)&&(*((ULONG*)(i+12))==code4_sp2)) { retAddr=(PVOID*)i; DbgPrint("MyPspTerminateThreadByPointer adress is:%x\n",retAddr); return retAddr; } } DbgPrint("Can't Find MyPspTerminateThreadByPointer Address:%x\n"); return 0; }
/////////////////////////////////////////////////////////////////////////////////// // // 功能实现: 获取函数所在的内核模块的路径 // 输入参数: dwFunAddress为要查找所在模块的函数地址; // cbName为pszName的总长度; // bFlag为TRUE,则是返回模块全路径,为FALSE则返回模块名字 // 输出参数: 是否调用成功 // /////////////////////////////////////////////////////////////////////////////////// BOOL GetKernelModuleNameByAddress(PSTR pszName, ULONG cbName, DWORD dwFunAddress, BOOL bFlag) { NTSTATUS Status; PSYSTEM_MODULE_INFORMATION Modules; PSYSTEM_MODULE_INFORMATION_ENTRY ModuleInfo; PVOID Buffer; ULONG BufferSize = 4096; ULONG ReturnLength; ULONG NameLen; if (dwFunAddress < 0x80000000) return FALSE; retry: Buffer = GlobalAlloc(GPTR, BufferSize); if (!Buffer) return FALSE; Status = ZwQuerySystemInformation(SystemModuleInformation, Buffer, BufferSize, &ReturnLength); if (Status == STATUS_INFO_LENGTH_MISMATCH) { GlobalFree(Buffer); BufferSize = ReturnLength; goto retry; } if (NT_SUCCESS(Status)) { Modules = (PSYSTEM_MODULE_INFORMATION)Buffer; ModuleInfo = &(Modules->Module[0]); for (ULONG i = 0; i < Modules->NumberOfModules; i ++, ModuleInfo ++) { if (dwFunAddress > (DWORD)(ModuleInfo->Base) && dwFunAddress < (DWORD)(ModuleInfo->Base) + ModuleInfo->Size) { if (bFlag) { NameLen = lstrlenA(ModuleInfo->FullPathName); if (cbName < NameLen) goto theEnd; strncpy(pszName, ModuleInfo->FullPathName, NameLen); } else { NameLen = lstrlenA(ModuleInfo->OffsetToFileName + ModuleInfo->FullPathName); if (cbName < NameLen) goto theEnd; strncpy(pszName, ModuleInfo->OffsetToFileName + ModuleInfo->FullPathName, NameLen); } GlobalFree(Buffer); return TRUE; } } } theEnd: GlobalFree(Buffer); return FALSE; }
PVOID GetKernelBase(OUT PULONG pSize) { NTSTATUS status = STATUS_SUCCESS; ULONG bytes = 0; PRTL_PROCESS_MODULES pMods = NULL; PVOID checkPtr = NULL; UNICODE_STRING routineName; ULONG i; // Already found if (g_KernelBase != NULL) { if (pSize) { *pSize = g_KernelSize; } return g_KernelBase; } RtlUnicodeStringInit (&routineName, L"NtOpenFile"); checkPtr = MmGetSystemRoutineAddress (&routineName); if (!checkPtr) { return NULL; } status = ZwQuerySystemInformation (SystemModuleInformation, 0, bytes, &bytes); if (bytes == 0) return NULL; pMods = (PRTL_PROCESS_MODULES)ExAllocatePoolWithTag (NonPagedPool, bytes, 'domP'); RtlZeroMemory (pMods, bytes); status = ZwQuerySystemInformation (SystemModuleInformation, pMods, bytes, &bytes); if (NT_SUCCESS(status)) { PRTL_PROCESS_MODULE_INFORMATION pMod = pMods->Modules; for (i = 0; i < pMods->NumberOfModules; i++) { if (checkPtr >= pMod[i].ImageBase && checkPtr < (PVOID)((PUCHAR)pMod[i].ImageBase + pMod[i].ImageSize)) { g_KernelBase = pMod[i].ImageBase; g_KernelSize = pMod[i].ImageSize; if (pSize) { *pSize = g_KernelSize; } } } } if (pMods) ExFreePoolWithTag (pMods, 'domP'); return g_KernelBase; }
NTSTATUS MuGetNtKernelImageInfo ( PVOID *ImageBase, PULONG ImageSize ) { NTSTATUS status; PSYSTEM_MODULE SystemModule; PSYSTEM_MODULE_INFORMATION ModuleInfo = NULL; ULONG CbSize = 0; while (TRUE) { status = ZwQuerySystemInformation(SystemModuleInformation, ModuleInfo, CbSize, &CbSize); if (NT_SUCCESS(status)) { SystemModule = &ModuleInfo->Modules[0]; *ImageBase = SystemModule->ImageBaseAddress; // the first module is always ntoskrnl/ntkrnlmp/ntkrnlpa/ntkrpamp *ImageSize = SystemModule->ImageSize; break; } else { if (status == STATUS_INFO_LENGTH_MISMATCH) { if (ModuleInfo) MuFree(ModuleInfo); ModuleInfo = MuPagedAlloc(CbSize); if (!ModuleInfo) break; } else { break; } } } if (ModuleInfo) MuFree(ModuleInfo); return status; }
HANDLE GetPidAndTidByName(PWCHAR ProcessName, PHANDLE pThreadId) { HANDLE Ret = 0; PVOID SysInfo; ULONG Size = 0x1000; NTSTATUS St; UNICODE_STRING NeededName; do { SysInfo = ExAllocatePool(NonPagedPool, Size); if (!SysInfo) return Ret; St = ZwQuerySystemInformation(SystemProcessInformation, SysInfo, Size, NULL); if (St == STATUS_INFO_LENGTH_MISMATCH) { ExFreePool(SysInfo); Size *= 2; } else if (!NT_SUCCESS(St)) { ExFreePool(SysInfo); return Ret; } } while (St == STATUS_INFO_LENGTH_MISMATCH); RtlInitUnicodeString(&NeededName, ProcessName); PSYSTEM_PROCESS_INFORMATION pProcess = (PSYSTEM_PROCESS_INFORMATION)SysInfo; for (;;) { if (RtlEqualUnicodeString(&NeededName, &pProcess->ImageName, TRUE)) { Ret = pProcess->ProcessId; *pThreadId = pProcess->Threads[0].ClientId.UniqueThread; break; } if (!pProcess->NextEntryOffset) break; pProcess = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)pProcess + pProcess->NextEntryOffset); } ExFreePool(SysInfo); return Ret; }
/////////////////////////////////////////////////////////////////////////////////// // // 功能实现: 根据内核模块名称获取内核模块的加载地址 // 输入参数: pszName 为输入内核模块名称 // pBase 为返回内核模块加载地址 // 输出参数: 是否调用成功 // /////////////////////////////////////////////////////////////////////////////////// BOOL GetKernelModuleBaseByName(PSTR pszName, PULONG SysBase) { NTSTATUS Status; PSYSTEM_MODULE_INFORMATION Modules; PSYSTEM_MODULE_INFORMATION_ENTRY ModuleInfo; PVOID Buffer; ULONG BufferSize = 4096; ULONG ReturnLength; if (SysBase == NULL) return FALSE; retry: Buffer = GlobalAlloc(GPTR, BufferSize); if (!Buffer) return FALSE; Status = ZwQuerySystemInformation(SystemModuleInformation, Buffer, BufferSize, &ReturnLength ); if (Status == STATUS_INFO_LENGTH_MISMATCH) { GlobalFree(Buffer); BufferSize = ReturnLength; goto retry; } if (NT_SUCCESS(Status)) { Modules = (PSYSTEM_MODULE_INFORMATION)Buffer; ModuleInfo = &(Modules->Module[0]); for (ULONG i = 0; i < Modules->NumberOfModules; i ++, ModuleInfo ++) { if (_stricmp(ModuleInfo->OffsetToFileName + ModuleInfo->FullPathName, pszName) == 0) { *SysBase = (ULONG)(ModuleInfo->Base); GlobalFree(Buffer); return TRUE; } } } GlobalFree(Buffer); return FALSE; }
BOOLEAN FASTCALL XboxVmpMapVideoMemory( PXBOXVMP_DEVICE_EXTENSION DeviceExtension, PVIDEO_MEMORY RequestedAddress, PVIDEO_MEMORY_INFORMATION MapInformation, PSTATUS_BLOCK StatusBlock) { PHYSICAL_ADDRESS FrameBuffer; ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY; SYSTEM_BASIC_INFORMATION BasicInfo; ULONG Length; /* FIXME: this should probably be done differently, without native API */ StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION); FrameBuffer.u.HighPart = 0; if (ZwQuerySystemInformation(SystemBasicInformation, (PVOID) &BasicInfo, sizeof(SYSTEM_BASIC_INFORMATION), &Length) == NO_ERROR) { FrameBuffer.u.LowPart = BasicInfo.HighestPhysicalPageNumber * PAGE_SIZE; } else { VideoPortDebugPrint(Error, "ZwQueryBasicInformation failed, assuming 64MB total memory\n"); FrameBuffer.u.LowPart = 60 * 1024 * 1024; } FrameBuffer.QuadPart += DeviceExtension->PhysFrameBufferStart.QuadPart; MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress; MapInformation->VideoRamLength = 4 * 1024 * 1024; VideoPortMapMemory(DeviceExtension, FrameBuffer, &MapInformation->VideoRamLength, &inIoSpace, &MapInformation->VideoRamBase); MapInformation->FrameBufferBase = MapInformation->VideoRamBase; MapInformation->FrameBufferLength = MapInformation->VideoRamLength; /* Tell the nVidia controller about the framebuffer */ *((PULONG)((char *) DeviceExtension->VirtControlStart + CONTROL_FRAMEBUFFER_ADDRESS_OFFSET)) = FrameBuffer.u.LowPart; VideoPortDebugPrint(Info, "Mapped 0x%x bytes of phys mem at 0x%lx to virt addr 0x%p\n", MapInformation->VideoRamLength, FrameBuffer.u.LowPart, MapInformation->VideoRamBase); return TRUE; }
/* * @implemented */ NTSTATUS NTAPI RtlSystemTimeToLocalTime(IN PLARGE_INTEGER SystemTime, OUT PLARGE_INTEGER LocalTime) { SYSTEM_TIMEOFDAY_INFORMATION TimeInformation; NTSTATUS Status; Status = ZwQuerySystemInformation(SystemTimeOfDayInformation, &TimeInformation, sizeof(TimeInformation), NULL); if (!NT_SUCCESS(Status)) return Status; LocalTime->QuadPart = SystemTime->QuadPart - TimeInformation.TimeZoneBias.QuadPart; return STATUS_SUCCESS; }
/////////////////////////////////////////////////////////////////////////////////// // // 功能实现: 获取函数所在的内核模块的路径 // 输入参数: pszKernelName 为返回内核名称 // cbName为pszName的总长度; // 输出参数: 是否调用成功 // /////////////////////////////////////////////////////////////////////////////////// BOOL GetKernelInformation(PSTR pszKernelName, ULONG cbName, PULONG KernelBase) { NTSTATUS Status; PSYSTEM_MODULE_INFORMATION Modules; PSYSTEM_MODULE_INFORMATION_ENTRY ModuleInfo; PVOID Buffer; ULONG BufferSize = 4096; ULONG ReturnLength; ULONG NameLen; retry: Buffer = GlobalAlloc(GPTR, BufferSize); if (!Buffer) return FALSE; Status = ZwQuerySystemInformation(SystemModuleInformation, Buffer, BufferSize, &ReturnLength); if (Status == STATUS_INFO_LENGTH_MISMATCH) { GlobalFree(Buffer); BufferSize = ReturnLength; goto retry; } if (NT_SUCCESS(Status)) { Modules = (PSYSTEM_MODULE_INFORMATION)Buffer; ModuleInfo = &(Modules->Module[0]); if (KernelBase != NULL) KernelBase[0] = (DWORD)ModuleInfo->Base; NameLen = lstrlenA(ModuleInfo->OffsetToFileName + ModuleInfo->FullPathName); if (cbName < NameLen) goto theEnd; strncpy(pszKernelName, ModuleInfo->OffsetToFileName + ModuleInfo->FullPathName, NameLen); GlobalFree(Buffer); return TRUE; } theEnd: GlobalFree(Buffer); return FALSE; }
PVOID GetInfoTable(ULONG ATableType) { ULONG mSize = 0x4000; PVOID mPtr = NULL; NTSTATUS St; do { mPtr = ExAllocatePool(PagedPool, mSize); memset(mPtr, 0, mSize); if (mPtr) { St = ZwQuerySystemInformation(ATableType, mPtr, mSize, NULL); } else return NULL; if (St == STATUS_INFO_LENGTH_MISMATCH) { ExFreePool(mPtr); mSize = mSize * 2; } } while (St == STATUS_INFO_LENGTH_MISMATCH); if (St == STATUS_SUCCESS) return mPtr; ExFreePool(mPtr); return NULL; }
LPVOID GetSystemHandleInformation(__out ULONG *NumOfHandle,__out ULONG *ulSize) { *ulSize = 0x4000; ULONG ulRequired; NTSTATUS Status; LPVOID pvBuffer; do { pvBuffer = HeapAlloc(GetProcessHeap(), 0, *ulSize); if (!pvBuffer) { printf("HeapAlloc() failed \r\n"); return FALSE; } Status = ZwQuerySystemInformation(SystemHandleInformation, pvBuffer, *ulSize, &ulRequired); if (Status == STATUS_INFO_LENGTH_MISMATCH) { HeapFree(GetProcessHeap(), 0, pvBuffer); *ulSize =ulRequired+25; } } while(Status == STATUS_INFO_LENGTH_MISMATCH); if (NT_SUCCESS(Status)) { *NumOfHandle= *(ULONG*)pvBuffer; return pvBuffer; } HeapFree(GetProcessHeap(), 0, pvBuffer); return FALSE; }
PVOID GetSystemInformation ( SYSTEM_INFORMATION_CLASS InfoClass ) /** Get system information by class. ZwQuerySystemInformation wrapper */ { NTSTATUS Status; PVOID Buffer; ULONG Size = PAGE_SIZE; do { Buffer = ExAllocatePool (PagedPool, Size); Status = ZwQuerySystemInformation ( InfoClass, Buffer, Size, &Size ); if (Status == STATUS_INFO_LENGTH_MISMATCH) ExFreePool (Buffer); } while (Status == STATUS_INFO_LENGTH_MISMATCH); if (!NT_SUCCESS(Status)) { ExFreePool (Buffer); return NULL; } return Buffer; }
// Executes \a callback_routine for all processes. _Use_decl_annotations_ static NTSTATUS EopmonpForEachProcess( bool (*callback_routine)(HANDLE pid, void*), void* context) { PAGED_CODE(); // For ZwQuerySystemInformation enum SystemInformationClass { kSystemProcessInformation = 5, }; // For ZwQuerySystemInformation struct SYSTEM_PROCESS_INFORMATION { ULONG NextEntryOffset; ULONG NumberOfThreads; UCHAR Reserved1[48]; PVOID Reserved2[3]; HANDLE UniqueProcessId; PVOID Reserved3; ULONG HandleCount; UCHAR Reserved4[4]; PVOID Reserved5[11]; SIZE_T PeakPagefileUsage; SIZE_T PrivatePageCount; LARGE_INTEGER Reserved6[6]; }; // prototype NTSTATUS NTAPI ZwQuerySystemInformation( _In_ SystemInformationClass SystemInformationClass, _Inout_ PVOID SystemInformation, _In_ ULONG SystemInformationLength, _Out_opt_ PULONG ReturnLength); // Get a necessary size of buffer ULONG_PTR dummy = 0; ULONG return_length = 0; auto status = ZwQuerySystemInformation(kSystemProcessInformation, &dummy, sizeof(dummy), &return_length); if (NT_SUCCESS(status) || return_length <= sizeof(dummy)) { return status; } // Allocate s bit larger buffer to handle new processes in case const ULONG allocation_size = return_length + sizeof(SYSTEM_PROCESS_INFORMATION) * 10; const auto system_info = reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>(ExAllocatePoolWithTag( PagedPool, allocation_size, kHyperPlatformCommonPoolTag)); if (!system_info) { return STATUS_MEMORY_NOT_ALLOCATED; } status = ZwQuerySystemInformation(kSystemProcessInformation, system_info, allocation_size, &return_length); if (!NT_SUCCESS(status)) { ExFreePoolWithTag(system_info, kHyperPlatformCommonPoolTag); return status; } // For each process for (auto current = system_info; /**/; current = reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>( reinterpret_cast<ULONG_PTR>(current) + current->NextEntryOffset)) { if (!callback_routine(current->UniqueProcessId, context)) { // Exit when a callback returned false, but not as failure break; } if (!current->NextEntryOffset) { break; } } ExFreePoolWithTag(system_info, kHyperPlatformCommonPoolTag); return status; }
{ /* Simply ignore the exception */ } _SEH2_END; /* Finalize and copy the MD4 hash */ MD4Final(&Md4Context); RtlCopyMemory(&EntropyData->EnvironmentHash, Md4Context.digest, 16); } /* Read some machine specific hardware counters */ KsecReadMachineSpecificCounters(&EntropyData->MachineSpecificCounters); /* Query processor performance information */ Status = ZwQuerySystemInformation(SystemProcessorPerformanceInformation, &EntropyData->SystemProcessorPerformanceInformation, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), &ReturnLength); if (!NT_SUCCESS(Status)) { return Status; } /* Query system performance information */ Status = ZwQuerySystemInformation(SystemPerformanceInformation, &EntropyData->SystemPerformanceInformation, sizeof(SYSTEM_PERFORMANCE_INFORMATION), &ReturnLength); if (!NT_SUCCESS(Status)) { return Status; }
//--------------------------------------------------------------------------- // KillProcessEx // // Terminates the specified process and, optionally, all processes started // from the specified process (the so-called process tree). // // Parameters: // dwProcessId - identifier of the process to terminate // bTree - specifies whether the entire process tree should be // terminated // // Returns: // TRUE, if successful, FALSE - otherwise. // BOOL WINAPI KillProcessEx(DWORD dwProcessId, BOOL bTree) { if (!bTree) return KillProcess(dwProcessId); OSVERSIONINFO osvi; DWORD dwError; // determine operating system version osvi.dwOSVersionInfoSize = sizeof(osvi); GetVersionEx(&osvi); if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion < 5) { // obtain a handle to the default process heap HANDLE hHeap = GetProcessHeap(); NTSTATUS Status; ULONG cbBuffer = 0x8000; PVOID pBuffer = NULL; // it is difficult to say a priory which size of the buffer // will be enough to retrieve all information, so we start // with 32K buffer and increase its size until we get the // information successfully do { pBuffer = HeapAlloc(hHeap, 0, cbBuffer); if (pBuffer == NULL) return SetLastError(ERROR_NOT_ENOUGH_MEMORY), FALSE; Status = ZwQuerySystemInformation( SystemProcessesAndThreadsInformation, pBuffer, cbBuffer, NULL); if (Status == STATUS_INFO_LENGTH_MISMATCH) { HeapFree(hHeap, 0, pBuffer); cbBuffer *= 2; } else if (!NT_SUCCESS(Status)) { HeapFree(hHeap, 0, pBuffer); return SetLastError(Status), NULL; } } while (Status == STATUS_INFO_LENGTH_MISMATCH); // call the helper function dwError = KillProcessTreeNtHelper((PSYSTEM_PROCESSES)pBuffer, dwProcessId); HeapFree(hHeap, 0, pBuffer); } else { // call the helper function dwError = KillProcessTreeWinHelper(dwProcessId); } SetLastError(dwError); return dwError == ERROR_SUCCESS; }
/// <summary> /// Find first thread of the target process /// </summary> /// <param name="pid">Target PID.</param> /// <param name="ppThread">Found thread. Thread object reference count is increased by 1</param> /// <returns>Status code</returns> NTSTATUS BBLookupProcessThread( IN HANDLE pid, OUT PETHREAD* ppThread ) { NTSTATUS status = STATUS_SUCCESS; PVOID pBuf = ExAllocatePoolWithTag( NonPagedPool, 1024 * 1024, BB_POOL_TAG ); PSYSTEM_PROCESS_INFO pInfo = (PSYSTEM_PROCESS_INFO)pBuf; ASSERT( ppThread != NULL ); if (ppThread == NULL) return STATUS_INVALID_PARAMETER; if (!pInfo) { DPRINT( "BlackBone: %s: Failed to allocate memory for process list\n", __FUNCTION__ ); return STATUS_NO_MEMORY; } // Get the process thread list status = ZwQuerySystemInformation( SystemProcessInformation, pInfo, 1024 * 1024, NULL ); if (!NT_SUCCESS( status )) { ExFreePoolWithTag( pBuf, BB_POOL_TAG ); return status; } // Find target thread if (NT_SUCCESS( status )) { status = STATUS_NOT_FOUND; for (;;) { if (pInfo->UniqueProcessId == pid) { status = STATUS_SUCCESS; break; } else if (pInfo->NextEntryOffset) pInfo = (PSYSTEM_PROCESS_INFO)((PUCHAR)pInfo + pInfo->NextEntryOffset); else break; } } // Reference target thread if (NT_SUCCESS( status )) { status = STATUS_NOT_FOUND; // Get first thread for (ULONG i = 0; i < pInfo->NumberOfThreads; i++) { // Skip current thread if (/*pInfo->Threads[i].WaitReason == Suspended || pInfo->Threads[i].ThreadState == 5 ||*/ pInfo->Threads[i].ClientId.UniqueThread == PsGetCurrentThread()) { continue; } status = PsLookupThreadByThreadId( pInfo->Threads[i].ClientId.UniqueThread, ppThread ); break; } } else DPRINT( "BlackBone: %s: Failed to locate process\n", __FUNCTION__ ); if (pBuf) ExFreePoolWithTag( pBuf, BB_POOL_TAG ); return status; }