程序防多开之一:进程数量检测

在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_INFORMATIONSYSTEM_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");

    
}

        运行结果如图:

        

        

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

°默然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值