在Windows系统中,若要检测某进程的数量,可以通过多个种方式实现.
例如:
通过CreateToolhelp32Snapshot()以及Process32First()枚举进程。
通过psapi.dll中的EnumProcesses()进行枚举。
通过WtsApi32.dll中的WTSEnumerateProcesses()进行枚举。
以上方法均可以拿到当前系统中运行的所有进程ID,虽然它们所在的库不相同,但是它们在底层都是调用同一个系统函数来实现的.
这个函数就是位于ntdll.dll中的NtQuerySystemInformation().
它是一个内核函数,微软对应用程序提供了接口以供调用.
其函数原型是:
__kernel_entry NTSTATUS NtQuerySystemInformation(
[in] SYSTEM_INFORMATION_CLASS SystemInformationClass,
[in, out] PVOID SystemInformation,
[in] ULONG SystemInformationLength,
[out, optional] PULONG ReturnLength
);
作弊程序为了防止多开检测,往往会挂钩系统API来实现进程隐藏.
想要最大限度的实现真实的进程检测,我们仅需要针对这一个函数进行调用和检测即可.
以下是实现程序多开限制的实例代码:
头文件部分(CheckStarts.h)
#pragma once
#include <iostream>
#include <Windows.h>
using namespace std;
//宏定义DLL函数获取方法
#define FUN_Get_static(dll,return_value, calling_convention, apiname, ...) \
typedef return_value(calling_convention * pf_##apiname)(__VA_ARGS__);\
static pf_##apiname pFun_##apiname =NULL;\
if (!pFun_##apiname)\
pFun_##apiname=(pf_##apiname)myGetProc(dll, #apiname);
//宏定义DLL函数指针
#define FUN_point(apiname)pFun_##apiname
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef enum _KWAIT_REASON {
Executive,
FreePage,
PageIn,
PoolAllocation,
DelayExecution,
Suspended1,
UserRequest,
WrExecutive,
WrFreePage,
WrPageIn,
WrPoolAllocation,
WrDelayExecution,
WrSuspended,
WrUserRequest,
WrSpare0,
WrQueue,
WrLpcReceive,
WrLpcReply,
WrVirtualMemory,
WrPageOut,
WrRendezvous,
WrKeyedEvent,
WrTerminated,
WrProcessInSwap,
WrCpuRateControl,
WrCalloutStack,
WrKernel,
WrResource,
WrPushLock,
WrMutex,
WrQuantumEnd,
WrDispatchInt,
WrPreempted,
WrYieldExecution,
WrFastMutex,
WrGuardedMutex,
WrRundown,
WrAlertByThreadId,
WrDeferredPreempt,
WrPhysicalFault,
MaximumWaitReason
} KWAIT_REASON;
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, * PCLIENT_ID;
typedef struct _LSA_UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} LSA_UNICODE_STRING, * PLSA_UNICODE_STRING, UNICODE_STRING, * PUNICODE_STRING;
typedef LONG KPRIORITY;
typedef struct _SYSTEM_THREAD_INFORMATION
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId; //拥有者的进程和线程ID
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitches;
ULONG ThreadState;
KWAIT_REASON WaitReason;
}SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION
{
ULONG NextEntryOffset; //下个进程数据偏移
ULONG NumberOfThreads; //线程数量
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId; //当前进程PID
HANDLE InheritedFromProcessId; //父进程PID
ULONG HandleCount; //句柄数量
BYTE Reserved4[4];
PVOID Reserved5[11];
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER Reserved6[6];
SYSTEM_THREAD_INFORMATION Threads[0]; //线程信息数组
}SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation, // q: SYSTEM_BASIC_INFORMATION
SystemProcessorInformation, // q: SYSTEM_PROCESSOR_INFORMATION
SystemPerformanceInformation, // q: SYSTEM_PERFORMANCE_INFORMATION
SystemTimeOfDayInformation, // q: SYSTEM_TIMEOFDAY_INFORMATION
SystemPathInformation, // not implemented
SystemProcessInformation, // q: SYSTEM_PROCESS_INFORMATION
SystemCallCountInformation, // q: SYSTEM_CALL_COUNT_INFORMATION
SystemDeviceInformation, // q: SYSTEM_DEVICE_INFORMATION
SystemProcessorPerformanceInformation, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
SystemFlagsInformation, // q: SYSTEM_FLAGS_INFORMATION
SystemCallTimeInformation, // not implemented // SYSTEM_CALL_TIME_INFORMATION // 10
SystemModuleInformation, // q: RTL_PROCESS_MODULES
SystemLocksInformation, // q: RTL_PROCESS_LOCKS
SystemStackTraceInformation, // q: RTL_PROCESS_BACKTRACES
SystemPagedPoolInformation, // not implemented
SystemNonPagedPoolInformation, // not implemented
SystemHandleInformation, // q: SYSTEM_HANDLE_INFORMATION
SystemObjectInformation, // q: SYSTEM_OBJECTTYPE_INFORMATION mixed with SYSTEM_OBJECT_INFORMATION
SystemPageFileInformation, // q: SYSTEM_PAGEFILE_INFORMATION
SystemVdmInstemulInformation, // q
SystemVdmBopInformation, // not implemented // 20
SystemFileCacheInformation, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemCache)
SystemPoolTagInformation, // q: SYSTEM_POOLTAG_INFORMATION
SystemInterruptInformation, // q: SYSTEM_INTERRUPT_INFORMATION
SystemDpcBehaviorInformation, // q: SYSTEM_DPC_BEHAVIOR_INFORMATION; s: SYSTEM_DPC_BEHAVIOR_INFORMATION (requires SeLoadDriverPrivilege)
SystemFullMemoryInformation, // not implemented
SystemLoadGdiDriverInformation, // s (kernel-mode only)
SystemUnloadGdiDriverInformation, // s (kernel-mode only)
SystemTimeAdjustmentInformation, // q: SYSTEM_QUERY_TIME_ADJUST_INFORMATION; s: SYSTEM_SET_TIME_ADJUST_INFORMATION (requires SeSystemtimePrivilege)
SystemSummaryMemoryInformation, // not implemented
SystemMirrorMemoryInformation, // s (requires license value "Kernel-MemoryMirroringSupported") (requires SeShutdownPrivilege) // 30
SystemPerformanceTraceInformation, // q; s: (type depends on EVENT_TRACE_INFORMATION_CLASS)
SystemObsolete0, // not implemented
SystemExceptionInformation, // q: SYSTEM_EXCEPTION_INFORMATION
SystemCrashDumpStateInformation, // s (requires SeDebugPrivilege)
SystemKernelDebuggerInformation, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION
SystemContextSwitchInformation, // q: SYSTEM_CONTEXT_SWITCH_INFORMATION
SystemRegistryQuotaInformation, // q: SYSTEM_REGISTRY_QUOTA_INFORMATION; s (requires SeIncreaseQuotaPrivilege)
SystemExtendServiceTableInformation, // s (requires SeLoadDriverPrivilege) // loads win32k only
SystemPrioritySeperation, // s (requires SeTcbPrivilege)
SystemVerifierAddDriverInformation, // s (requires SeDebugPrivilege) // 40
SystemVerifierRemoveDriverInformation, // s (requires SeDebugPrivilege)
SystemProcessorIdleInformation, // q: SYSTEM_PROCESSOR_IDLE_INFORMATION
SystemLegacyDriverInformation, // q: SYSTEM_LEGACY_DRIVER_INFORMATION
SystemCurrentTimeZoneInformation, // q; s: RTL_TIME_ZONE_INFORMATION
SystemLookasideInformation, // q: SYSTEM_LOOKASIDE_INFORMATION
SystemTimeSlipNotification, // s (requires SeSystemtimePrivilege)
SystemSessionCreate, // not implemented
SystemSessionDetach, // not implemented
SystemSessionInformation, // not implemented (SYSTEM_SESSION_INFORMATION)
SystemRangeStartInformation, // q: SYSTEM_RANGE_START_INFORMATION // 50
SystemVerifierInformation, // q: SYSTEM_VERIFIER_INFORMATION; s (requires SeDebugPrivilege)
SystemVerifierThunkExtend, // s (kernel-mode only)
SystemSessionProcessInformation, // q: SYSTEM_SESSION_PROCESS_INFORMATION
SystemLoadGdiDriverInSystemSpace, // s (kernel-mode only) (same as SystemLoadGdiDriverInformation)
SystemNumaProcessorMap, // q
SystemPrefetcherInformation, // q: PREFETCHER_INFORMATION; s: PREFETCHER_INFORMATION // PfSnQueryPrefetcherInformation
SystemExtendedProcessInformation, // q: SYSTEM_PROCESS_INFORMATION
SystemRecommendedSharedDataAlignment, // q
SystemComPlusPackage, // q; s
SystemNumaAvailableMemory, // 60
SystemProcessorPowerInformation, // q: SYSTEM_PROCESSOR_POWER_INFORMATION
SystemEmulationBasicInformation,
SystemEmulationProcessorInformation,
SystemExtendedHandleInformation, // q: SYSTEM_HANDLE_INFORMATION_EX
SystemLostDelayedWriteInformation, // q: ULONG
SystemBigPoolInformation, // q: SYSTEM_BIGPOOL_INFORMATION
SystemSessionPoolTagInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION
SystemSessionMappedViewInformation, // q: SYSTEM_SESSION_MAPPED_VIEW_INFORMATION
SystemHotpatchInformation, // q; s: SYSTEM_HOTPATCH_CODE_INFORMATION
SystemObjectSecurityMode, // q: ULONG // 70
SystemWatchdogTimerHandler, // s (kernel-mode only)
SystemWatchdogTimerInformation, // q (kernel-mode only); s (kernel-mode only)
SystemLogicalProcessorInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION
SystemWow64SharedInformationObsolete, // not implemented
SystemRegisterFirmwareTableInformationHandler, // s (kernel-mode only)
SystemFirmwareTableInformation, // SYSTEM_FIRMWARE_TABLE_INFORMATION
SystemModuleInformationEx, // q: RTL_PROCESS_MODULE_INFORMATION_EX
SystemVerifierTriageInformation, // not implemented
SystemSuperfetchInformation, // q; s: SUPERFETCH_INFORMATION // PfQuerySuperfetchInformation
SystemMemoryListInformation, // q: SYSTEM_MEMORY_LIST_INFORMATION; s: SYSTEM_MEMORY_LIST_COMMAND (requires SeProfileSingleProcessPrivilege) // 80
SystemFileCacheInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (same as SystemFileCacheInformation)
SystemThreadPriorityClientIdInformation, // s: SYSTEM_THREAD_CID_PRIORITY_INFORMATION (requires SeIncreaseBasePriorityPrivilege)
SystemProcessorIdleCycleTimeInformation, // q: SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION[]
SystemVerifierCancellationInformation, // not implemented // name:wow64:whNT32QuerySystemVerifierCancellationInformation
SystemProcessorPowerInformationEx, // not implemented
SystemRefTraceInformation, // q; s: SYSTEM_REF_TRACE_INFORMATION // ObQueryRefTraceInformation
SystemSpecialPoolInformation, // q; s (requires SeDebugPrivilege) // MmSpecialPoolTag, then MmSpecialPoolCatchOverruns != 0
SystemProcessIdInformation, // q: SYSTEM_PROCESS_ID_INFORMATION
SystemErrorPortInformation, // s (requires SeTcbPrivilege)
SystemBootEnvironmentInformation, // q: SYSTEM_BOOT_ENVIRONMENT_INFORMATION // 90
SystemHypervisorInformation, // q; s (kernel-mode only)
SystemVerifierInformationEx, // q; s: SYSTEM_VERIFIER_INFORMATION_EX
SystemTimeZoneInformation, // s (requires SeTimeZonePrivilege)
SystemImageFileExecutionOptionsInformation, // s: SYSTEM_IMAGE_FILE_EXECUTION_OPTIONS_INFORMATION (requires SeTcbPrivilege)
SystemCoverageInformation, // q; s // name:wow64:whNT32QuerySystemCoverageInformation; ExpCovQueryInformation
SystemPrefetchPatchInformation, // not implemented
SystemVerifierFaultsInformation, // s (requires SeDebugPrivilege)
SystemSystemPartitionInformation, // q: SYSTEM_SYSTEM_PARTITION_INFORMATION
SystemSystemDiskInformation, // q: SYSTEM_SYSTEM_DISK_INFORMATION
SystemProcessorPerformanceDistribution, // q: SYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION // 100
SystemNumaProximityNodeInformation,
SystemDynamicTimeZoneInformation, // q; s (requires SeTimeZonePrivilege)
SystemCodeIntegrityInformation, // q: SYSTEM_CODEINTEGRITY_INFORMATION // SeCodeIntegrityQueryInformation
SystemProcessorMicrocodeUpdateInformation, // s
SystemProcessorBrandString, // q // HaliQuerySystemInformation -> HalpGetProcessorBrandString, info class 23
SystemVirtualAddressInformation, // q: SYSTEM_VA_LIST_INFORMATION[]; s: SYSTEM_VA_LIST_INFORMATION[] (requires SeIncreaseQuotaPrivilege) // MmQuerySystemVaInformation
SystemLogicalProcessorAndGroupInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX // since WIN7 // KeQueryLogicalProcessorRelationship
SystemProcessorCycleTimeInformation, // q: SYSTEM_PROCESSOR_CYCLE_TIME_INFORMATION[]
SystemStoreInformation, // q; s: SYSTEM_STORE_INFORMATION // SmQueryStoreInformation
SystemRegistryAppendString, // s: SYSTEM_REGISTRY_APPEND_STRING_PARAMETERS // 110
SystemAitSamplingValue, // s: ULONG (requires SeProfileSingleProcessPrivilege)
SystemVhdBootInformation, // q: SYSTEM_VHD_BOOT_INFORMATION
SystemCpuQuotaInformation, // q; s // PsQueryCpuQuotaInformation
SystemNativeBasicInformation, // not implemented
SystemSpare1, // not implemented
SystemLowPriorityIoInformation, // q: SYSTEM_LOW_PRIORITY_IO_INFORMATION
SystemTpmBootEntropyInformation, // q: TPM_BOOT_ENTROPY_NT_RESULT // ExQueryTpmBootEntropyInformation
SystemVerifierCountersInformation, // q: SYSTEM_VERIFIER_COUNTERS_INFORMATION
SystemPagedPoolInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypePagedPool)
SystemSystemPtesInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemPtes) // 120
SystemNodeDistanceInformation,
SystemAcpiAuditInformation, // q: SYSTEM_ACPI_AUDIT_INFORMATION // HaliQuerySystemInformation -> HalpAuditQueryResults, info class 26
SystemBasicPerformanceInformation, // q: SYSTEM_BASIC_PERFORMANCE_INFORMATION // name:wow64:whNtQuerySystemInformation_SystemBasicPerformanceInformation
SystemQueryPerformanceCounterInformation, // q: SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION // since WIN7 SP1
SystemSessionBigPoolInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION // since WIN8
SystemBootGraphicsInformation, // q; s: SYSTEM_BOOT_GRAPHICS_INFORMATION (kernel-mode only)
SystemScrubPhysicalMemoryInformation, // q; s: MEMORY_SCRUB_INFORMATION
SystemBadPageInformation,
SystemProcessorProfileControlArea, // q; s: SYSTEM_PROCESSOR_PROFILE_CONTROL_AREA
SystemCombinePhysicalMemoryInformation, // s: MEMORY_COMBINE_INFORMATION, MEMORY_COMBINE_INFORMATION_EX, MEMORY_COMBINE_INFORMATION_EX2 // 130
SystemEntropyInterruptTimingCallback,
SystemConsoleInformation, // q: SYSTEM_CONSOLE_INFORMATION
SystemPlatformBinaryInformation, // q: SYSTEM_PLATFORM_BINARY_INFORMATION
SystemThrottleNotificationInformation,
SystemHypervisorProcessorCountInformation, // q: SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION
SystemDeviceDataInformation, // q: SYSTEM_DEVICE_DATA_INFORMATION
SystemDeviceDataEnumerationInformation,
SystemMemoryTopologyInformation, // q: SYSTEM_MEMORY_TOPOLOGY_INFORMATION
SystemMemoryChannelInformation, // q: SYSTEM_MEMORY_CHANNEL_INFORMATION
SystemBootLogoInformation, // q: SYSTEM_BOOT_LOGO_INFORMATION // 140
SystemProcessorPerformanceInformationEx, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_EX // since WINBLUE
SystemSpare0,
SystemSecureBootPolicyInformation, // q: SYSTEM_SECUREBOOT_POLICY_INFORMATION
SystemPageFileInformationEx, // q: SYSTEM_PAGEFILE_INFORMATION_EX
SystemSecureBootInformation, // q: SYSTEM_SECUREBOOT_INFORMATION
SystemEntropyInterruptTimingRawInformation,
SystemPortableWorkspaceEfiLauncherInformation, // q: SYSTEM_PORTABLE_WORKSPACE_EFI_LAUNCHER_INFORMATION
SystemFullProcessInformation, // q: SYSTEM_PROCESS_INFORMATION with SYSTEM_PROCESS_INFORMATION_EXTENSION (requires admin)
SystemKernelDebuggerInformationEx, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX
SystemBootMetadataInformation, // 150
SystemSoftRebootInformation, // q: ULONG
SystemElamCertificateInformation, // s: SYSTEM_ELAM_CERTIFICATE_INFORMATION
SystemOfflineDumpConfigInformation,
SystemProcessorFeaturesInformation, // q: SYSTEM_PROCESSOR_FEATURES_INFORMATION
SystemRegistryReconciliationInformation,
SystemEdidInformation,
SystemManufacturingInformation, // q: SYSTEM_MANUFACTURING_INFORMATION // since THRESHOLD
SystemEnergyEstimationConfigInformation, // q: SYSTEM_ENERGY_ESTIMATION_CONFIG_INFORMATION
SystemHypervisorDetailInformation, // q: SYSTEM_HYPERVISOR_DETAIL_INFORMATION
SystemProcessorCycleStatsInformation, // q: SYSTEM_PROCESSOR_CYCLE_STATS_INFORMATION // 160
SystemVmGenerationCountInformation,
SystemTrustedPlatformModuleInformation, // q: SYSTEM_TPM_INFORMATION
SystemKernelDebuggerFlags, // SYSTEM_KERNEL_DEBUGGER_FLAGS
SystemCodeIntegrityPolicyInformation, // q: SYSTEM_CODEINTEGRITYPOLICY_INFORMATION
SystemIsolatedUserModeInformation, // q: SYSTEM_ISOLATED_USER_MODE_INFORMATION
SystemHardwareSecurityTestInterfaceResultsInformation,
SystemSingleModuleInformation, // q: SYSTEM_SINGLE_MODULE_INFORMATION
SystemAllowedCpuSetsInformation,
SystemVsmProtectionInformation, // q: SYSTEM_VSM_PROTECTION_INFORMATION (previously SystemDmaProtectionInformation)
SystemInterruptCpuSetsInformation, // q: SYSTEM_INTERRUPT_CPU_SET_INFORMATION // 170
SystemSecureBootPolicyFullInformation, // q: SYSTEM_SECUREBOOT_POLICY_FULL_INFORMATION
SystemCodeIntegrityPolicyFullInformation,
SystemAffinitizedInterruptProcessorInformation,
SystemRootSiloInformation, // q: SYSTEM_ROOT_SILO_INFORMATION
SystemCpuSetInformation, // q: SYSTEM_CPU_SET_INFORMATION // since THRESHOLD2
SystemCpuSetTagInformation, // q: SYSTEM_CPU_SET_TAG_INFORMATION
SystemWin32WerStartCallout,
SystemSecureKernelProfileInformation, // q: SYSTEM_SECURE_KERNEL_HYPERGUARD_PROFILE_INFORMATION
SystemCodeIntegrityPlatformManifestInformation, // q: SYSTEM_SECUREBOOT_PLATFORM_MANIFEST_INFORMATION // since REDSTONE
SystemInterruptSteeringInformation, // 180
SystemSupportedProcessorArchitectures,
SystemMemoryUsageInformation, // q: SYSTEM_MEMORY_USAGE_INFORMATION
SystemCodeIntegrityCertificateInformation, // q: SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION
SystemPhysicalMemoryInformation, // q: SYSTEM_PHYSICAL_MEMORY_INFORMATION // since REDSTONE2
SystemControlFlowTransition,
SystemKernelDebuggingAllowed, // s: ULONG
SystemActivityModerationExeState, // SYSTEM_ACTIVITY_MODERATION_EXE_STATE
SystemActivityModerationUserSettings, // SYSTEM_ACTIVITY_MODERATION_USER_SETTINGS
SystemCodeIntegrityPoliciesFullInformation,
SystemCodeIntegrityUnlockInformation, // SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION // 190
SystemIntegrityQuotaInformation,
SystemFlushInformation, // q: SYSTEM_FLUSH_INFORMATION
SystemProcessorIdleMaskInformation, // q: ULONG_PTR // since REDSTONE3
SystemSecureDumpEncryptionInformation,
SystemWriteConstraintInformation, // SYSTEM_WRITE_CONSTRAINT_INFORMATION
SystemKernelVaShadowInformation, // SYSTEM_KERNEL_VA_SHADOW_INFORMATION
SystemHypervisorSharedPageInformation, // SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION // since REDSTONE4
SystemFirmwareBootPerformanceInformation,
SystemCodeIntegrityVerificationInformation, // SYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION
SystemFirmwarePartitionInformation, // SYSTEM_FIRMWARE_PARTITION_INFORMATION // 200
SystemSpeculationControlInformation, // SYSTEM_SPECULATION_CONTROL_INFORMATION // (CVE-2017-5715) REDSTONE3 and above.
SystemDmaGuardPolicyInformation, // SYSTEM_DMA_GUARD_POLICY_INFORMATION
SystemEnclaveLaunchControlInformation, // SYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION
SystemWorkloadAllowedCpuSetsInformation, // SYSTEM_WORKLOAD_ALLOWED_CPU_SET_INFORMATION // since REDSTONE5
SystemCodeIntegrityUnlockModeInformation,
SystemLeapSecondInformation, // SYSTEM_LEAP_SECOND_INFORMATION
SystemFlags2Information, // q: SYSTEM_FLAGS_INFORMATION
SystemSecurityModelInformation, // SYSTEM_SECURITY_MODEL_INFORMATION // since 19H1
SystemCodeIntegritySyntheticCacheInformation,
MaxSystemInfoClass
} SYSTEM_INFORMATION_CLASS, * PSYSTEM_INFORMATION_CLASS;
PVOID myGetProc(LPCSTR lpLibFileName, LPCSTR lpProcName);
PVOID myGetSystemInformation(ULONG SystemInformationClass, PULONG pRetLen);
DWORD myGetProcessPath(DWORD nPID, LPWSTR lpPath, DWORD nSize);
LONG GetProcessCountByCurrentPath(PVOID SystemInformation, ULONG SystemInformationLength);
BOOL CheckCountByProcess(LONG nMaxCount);
代码解释:
我们实现了对FUN_Get_static宏的定义,以便直接在函数内部针对库导出函数进行声明.
然后通过宏FUN_point用来对函数指针的使用.
同样也对需要使用的结构体和枚举值进行定义,例如:SYSTEM_PROCESS_INFORMATION、SYSTEM_INFORMATION_CLASS等。
.cpp部分(CheckStarts.cpp)
#include "CheckStarts.h"
//获取dll导出函数地址
PVOID myGetProc(LPCSTR lpLibFileName, LPCSTR lpProcName)
{
HMODULE hMod = NULL;
do
{
hMod = GetModuleHandleA(lpLibFileName);
if (hMod)
break;
hMod = LoadLibraryA(lpLibFileName);
} while (FALSE);
if (!hMod)
return NULL;
PVOID pFun = GetProcAddress(hMod, lpProcName);
return pFun;
}
//调用NtQuerySystemInformation来获取数据
//如果成功,函数内部会申请内存作为数据缓冲区,并返回数据指针和数据长度
//需要在合适的时候通过free()释放内存,避免内存溢出.
PVOID myGetSystemInformation(ULONG SystemInformationClass, PULONG pRetLen)
{
__try
{
if (pRetLen)
*pRetLen = 0;
//通过宏定义FUN_Get_static在函数内部获取静态函数指针NtQuerySystemInformation;
//此命令将会加载ntdll.DLL并通过调用GetProcAddress获取函数指针.
FUN_Get_static("ntdll.DLL", NTSTATUS, NTAPI, NtQuerySystemInformation,
ULONG SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
//判断指针是否获取成功.
if (!FUN_point(NtQuerySystemInformation))
return NULL;
PVOID pSystemInformation = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
DWORD nRetLen = 0;
__try
{
do
{
//调用NtQuerySystemInformation,并初始化缓冲区为NULL,来获取所需缓冲区长度.
status = FUN_point(NtQuerySystemInformation)(SystemInformationClass, NULL, NULL, &nRetLen);
if (!nRetLen)
break;
status = STATUS_UNSUCCESSFUL;
//申请足够长度的缓冲区内存
pSystemInformation = malloc(nRetLen);
if (!pSystemInformation)
break;
memset(pSystemInformation, 0, nRetLen);
DWORD nInLen = nRetLen;
//此时才是真正通过NtQuerySystemInformation来获取数据.
status = FUN_point(NtQuerySystemInformation)(SystemInformationClass, pSystemInformation, nInLen, &nRetLen);
if (!NT_SUCCESS(status))
break;
} while (FALSE);
}
__except (EXCEPTION_EXECUTE_HANDLER) { ; }
//若是调用失败,则进行清理
if (!NT_SUCCESS(status))
{
if (pSystemInformation)
free(pSystemInformation);
pSystemInformation = NULL;
}
//返回获取到的数据长度.
if (pRetLen)
*pRetLen = nRetLen;
//返回获取到的数据存放的缓冲区指针.
return pSystemInformation;
}
__except (EXCEPTION_EXECUTE_HANDLER) { ; }
//发生异常错误,返回NULL
return NULL;
}
//获取进程的完整路径,并返回路径文本长度
DWORD myGetProcessPath(DWORD nPID, LPWSTR lpPath,DWORD nSize)
{
if (!nPID || !lpPath)
return 0;
DWORD nRet = 0;
HANDLE handle = NULL;
__try{
do
{
wsprintfW(lpPath, L"");
handle = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, nPID);
if (!handle)
break;
::QueryFullProcessImageNameW(handle, 0, lpPath, &nSize);
nRet = wcslen(lpPath);
} while (FALSE);
}
__except (EXCEPTION_EXECUTE_HANDLER) { ; }
if(handle)
CloseHandle(handle);
return nRet;
}
//解析PSYSTEM_PROCESS_INFORMATION数据,并且获取与当前进程路径相同的所有进程数量
LONG GetProcessCountByCurrentPath(PVOID SystemInformation, ULONG SystemInformationLength)
{
//获取自身进程完整路径
DWORD nCurrPID = GetCurrentProcessId();
WCHAR strCurrPath[MAX_PATH] = { 0 };
DWORD nRet = myGetProcessPath(nCurrPID, strCurrPath,sizeof(strCurrPath));
if (!nRet)
{
//获取自身进程完整路径失败!
return -1;
}
LONG nCount = 0;
PSYSTEM_PROCESS_INFORMATION pInfo = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;
__try
{
do
{
//判断数据是否溢出
if (!pInfo || ((PCHAR)pInfo) - SystemInformation >= SystemInformationLength)
break;
//获取进程PID
DWORD nPID = (DWORD)pInfo->UniqueProcessId;
WCHAR strPath[MAX_PATH] = { 0 };
DWORD nRet = myGetProcessPath(nPID, strPath,sizeof(strPath));
if (nRet)
{
if (wcscmp(strPath, strCurrPath) == 0)
{
nCount++;
}
}
//判断是否最后一个进程
if (!pInfo->NextEntryOffset)
break;
//pCurr指针指向下一个进程数据地址
pInfo = (PSYSTEM_PROCESS_INFORMATION)((PCHAR)pInfo + pInfo->NextEntryOffset);
} while (pInfo);
}
__except (EXCEPTION_EXECUTE_HANDLER) { ; }
return nCount;
}
//检测进程数量是否达到指定最大数
BOOL CheckCountByProcess(LONG nMaxCount)
{
BOOL isLimit = FALSE;
ULONG nSize = 0;
PVOID pSystemInformation = NULL;
__try{
do
{
//枚举当下所有进程信息
pSystemInformation = myGetSystemInformation(SystemProcessInformation, &nSize);
if (!pSystemInformation)
break;
//解析进程信息数据,并获取与当前进程路径相同的所有进程数量.
LONG nCount = GetProcessCountByCurrentPath(pSystemInformation, nSize);
//进程数量超出最大数
if (nCount > nMaxCount)
isLimit = TRUE;
//进程数量=0或者-1均表示系统环境异常,此处直接返回TRUE.
if (nCount <= 0)
isLimit = TRUE;
} while (FALSE);
}
__except (EXCEPTION_EXECUTE_HANDLER) { ; }
if (pSystemInformation)
free(pSystemInformation);
return isLimit;
}
代码解释:
在CheckCountByProcess()函数中,我们首先通过调用myGetSystemInformation()实现当下系统进程的枚举.
然后通过GetProcessCountByCurrentPath()对进程路径进行解析,并且返回与本进程相同路径的进程数量.
最后比较是否超出本进程的最大限制数量,执行多开检测.
在myGetSystemInformation()函数中实现了对NtQuerySystemInformation()函数指针的获取以及调用.
函数内部自动获取调用NtQuerySystemInformation()所需的内存大小以及申请足够的内存空间.
并且将成功拿到的系统数据存放指针返回给调用函数.
我们在调用它之后,仅需要关注数据部分以及释放内存即可.
在GetProcessCountByCurrentPath()函数中,先是调用GetCurrentProcessId()和myGetProcessPath()获取自身进程的路径.
再对SYSTEM_PROCESS_INFORMATION数据的指针进行解析,获取当下所有进程的PID以及进程路径.
对于与自身路径相同的进程,则视为被多开的程序.
在这里我们是通过进程路径进行识别的,您也可以通过其他方式来实现,例如程序文件的MD5值等.
以上便是针对进程开启数量的检测,调用方式如下代码:
#include "CheckStarts.h"
int main()
{
//限制多开数量
LONG nMaxCount = 2;
//判断进程数量是否超出限制数量
BOOL isLimit = CheckCountByProcess(nMaxCount);
if (isLimit)
MessageBoxA(0, "客户端开启数量超出限制!", "提示", 0);
system("pause");
}
运行结果如图: