标 题: 枚举进程句柄File,Section,Mutant,Timer关闭Mutex句柄实现游戏多开
作 者: Y4ng
时 间: 2012-09-06 19:50:32 星期四
链 接: http://www.cnblogs.com/Y4ng/archive/2012/09/06/EnumProcessHandle_EnumMutex.html
相信做过游戏多开的朋友就会发现,很多游戏普遍使用互斥mutex来防止程序多开,说实话这种方式已经非常OUT了。但是由于时间和技术的沉淀关系,留下来的游戏依然会存在这种方式。 最近接触到一款游戏是N前非常火热的对战游戏,可以称为经典之作;它就是用的Mutant来实现游戏防止多开的,一般咱们测试的时候都是用Xuetr来关闭游戏,但是要作为成品发布不可能要求客户拿Xuetr来列进程对象句柄,关句柄吧~
网上搜索了半天都没有找到枚举进程句柄的例子,经过群里的大牛提点指到 ZwQuerySystemInformation SystemHandleInformation 可以实现句柄枚举功能;经过一番搜索编码测试 于是有了本文代码;
- /*头文件声明*/
- typedef LONG NTSTATUS;
- #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
- #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
- typedef enum _SYSTEM_INFORMATION_CLASS {
- SystemBasicInformation, // 0 Y N
- SystemProcessorInformation, // 1 Y N
- SystemPerformanceInformation, // 2 Y N
- SystemTimeOfDayInformation, // 3 Y N
- SystemNotImplemented1, // 4 Y N
- SystemProcessesAndThreadsInformation, // 5 Y N
- SystemCallCounts, // 6 Y N
- SystemConfigurationInformation, // 7 Y N
- SystemProcessorTimes, // 8 Y N
- SystemGlobalFlag, // 9 Y Y
- SystemNotImplemented2, // 10 Y N
- SystemModuleInformation, // 11 Y N
- SystemLockInformation, // 12 Y N
- SystemNotImplemented3, // 13 Y N
- SystemNotImplemented4, // 14 Y N
- SystemNotImplemented5, // 15 Y N
- SystemHandleInformation, // 16 Y N
- SystemObjectInformation, // 17 Y N
- SystemPagefileInformation, // 18 Y N
- SystemInstructionEmulationCounts, // 19 Y N
- SystemInvalidInfoClass1, // 20
- SystemCacheInformation, // 21 Y Y
- SystemPoolTagInformation, // 22 Y N
- SystemProcessorStatistics, // 23 Y N
- SystemDpcInformation, // 24 Y Y
- SystemNotImplemented6, // 25 Y N
- SystemLoadImage, // 26 N Y
- SystemUnloadImage, // 27 N Y
- SystemTimeAdjustment, // 28 Y Y
- SystemNotImplemented7, // 29 Y N
- SystemNotImplemented8, // 30 Y N
- SystemNotImplemented9, // 31 Y N
- SystemCrashDumpInformation, // 32 Y N
- SystemExceptionInformation, // 33 Y N
- SystemCrashDumpStateInformation, // 34 Y Y/N
- SystemKernelDebuggerInformation, // 35 Y N
- SystemContextSwitchInformation, // 36 Y N
- SystemRegistryQuotaInformation, // 37 Y Y
- SystemLoadAndCallImage, // 38 N Y
- SystemPrioritySeparation, // 39 N Y
- SystemNotImplemented10, // 40 Y N
- SystemNotImplemented11, // 41 Y N
- SystemInvalidInfoClass2, // 42
- SystemInvalidInfoClass3, // 43
- SystemTimeZoneInformation, // 44 Y N
- SystemLookasideInformation, // 45 Y N
- SystemSetTimeSlipEvent, // 46 N Y
- SystemCreateSession, // 47 N Y
- SystemDeleteSession, // 48 N Y
- SystemInvalidInfoClass4, // 49
- SystemRangeStartInformation, // 50 Y N
- SystemVerifierInformation, // 51 Y Y
- SystemAddVerifier, // 52 N Y
- SystemSessionProcessesInformation // 53 Y N
- } SYSTEM_INFORMATION_CLASS;
- typedef struct _CLIENT_ID
- {
- HANDLE UniqueProcess;
- HANDLE UniqueThread;
- }CLIENT_ID,*PCLIENT_ID;
- typedef struct
- {
- USHORT Length;
- USHORT MaxLen;
- USHORT *Buffer;
- }UNICODE_STRING, *PUNICODE_STRING;
- typedef struct _OBJECT_ATTRIBUTES
- {
- ULONG Length;
- HANDLE RootDirectory;
- PUNICODE_STRING ObjectName;
- ULONG Attributes;
- PVOID SecurityDescriptor;
- PVOID SecurityQualityOfService;
- } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
- typedef struct _IO_COUNTERSEX {
- LARGE_INTEGER ReadOperationCount;
- LARGE_INTEGER WriteOperationCount;
- LARGE_INTEGER OtherOperationCount;
- LARGE_INTEGER ReadTransferCount;
- LARGE_INTEGER WriteTransferCount;
- LARGE_INTEGER OtherTransferCount;
- } IO_COUNTERSEX, *PIO_COUNTERSEX;
- typedef enum {
- StateInitialized,
- StateReady,
- StateRunning,
- StateStandby,
- StateTerminated,
- StateWait,
- StateTransition,
- StateUnknown
- } THREAD_STATE;
- typedef struct _VM_COUNTERS {
- SIZE_T PeakVirtualSize;
- SIZE_T VirtualSize;
- ULONG PageFaultCount;
- SIZE_T PeakWorkingSetSize;
- SIZE_T WorkingSetSize;
- SIZE_T QuotaPeakPagedPoolUsage;
- SIZE_T QuotaPagedPoolUsage;
- SIZE_T QuotaPeakNonPagedPoolUsage;
- SIZE_T QuotaNonPagedPoolUsage;
- SIZE_T PagefileUsage;
- SIZE_T PeakPagefileUsage;
- } VM_COUNTERS;
- typedef VM_COUNTERS *PVM_COUNTERS;
- typedef struct _SYSTEM_THREADS {
- LARGE_INTEGER KernelTime;
- LARGE_INTEGER UserTime;
- LARGE_INTEGER CreateTime;
- ULONG WaitTime;
- PVOID StartAddress;
- CLIENT_ID ClientId;
- ULONG Priority;
- ULONG BasePriority;
- ULONG ContextSwitchCount;
- THREAD_STATE State;
- ULONG WaitReason;
- } SYSTEM_THREADS, *PSYSTEM_THREADS;
- typedef struct _SYSTEM_PROCESSES { // Information Class 5
- ULONG NextEntryDelta;
- ULONG ThreadCount;
- ULONG Reserved1[6];
- LARGE_INTEGER CreateTime;
- LARGE_INTEGER UserTime;
- LARGE_INTEGER KernelTime;
- UNICODE_STRING ProcessName;
- ULONG BasePriority;
- ULONG ProcessId;
- ULONG InheritedFromProcessId;
- ULONG HandleCount;
- ULONG Reserved2[2];
- VM_COUNTERS VmCounters;
- IO_COUNTERSEX IoCounters; // Windows 2000 only
- SYSTEM_THREADS Threads[1];
- } SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
- typedef struct _SYSTEM_HANDLE_INFORMATION
- {
- ULONG ProcessId;
- UCHAR ObjectTypeNumber;
- UCHAR Flags;
- USHORT Handle;
- PVOID Object;
- ACCESS_MASK GrantedAccess;
- } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
- typedef enum _OBJECT_INFORMATION_CLASS {
- ObjectBasicInformation,
- ObjectNameInformation,
- ObjectTypeInformation,
- ObjectAllInformation,
- ObjectDataInformation
- } OBJECT_INFORMATION_CLASS;
- typedef struct _OBJECT_NAME_INFORMATION {
- UNICODE_STRING Name;
- } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
- typedef NTSTATUS (NTAPI *NTQUERYOBJECT)(
- _In_opt_ HANDLE Handle,
- _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,
- _Out_opt_ PVOID ObjectInformation,
- _In_ ULONG ObjectInformationLength,
- _Out_opt_ PULONG ReturnLength
- );
- typedef NTSTATUS
- (NTAPI *ZWQUERYSYSTEMINFORMATION)(
- IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
- OUT PVOID SystemInformation,
- IN ULONG SystemInformationLength,
- OUT PULONG ReturnLength OPTIONAL
- );
- ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle("ntdll.dll"),"ZwQuerySystemInformation");
- NTQUERYOBJECT NtQueryObject = (NTQUERYOBJECT)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQueryObject");
- /*功能函数体*/
- int _tmain(int argc, _TCHAR* argv[])
- {
- DWORD dwSize = 0;
- PSYSTEM_HANDLE_INFORMATION pmodule = NULL;
- POBJECT_NAME_INFORMATION pNameInfo;
- POBJECT_NAME_INFORMATION pNameType;
- PVOID pbuffer = NULL;
- NTSTATUS Status;
- int nIndex = 0;
- DWORD dwFlags = 0;
- char szType[128] = {0};
- char szName[512] = {0};
- if(!ZwQuerySystemInformation)
- {
- goto Exit0;
- }
- pbuffer = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
- if(!pbuffer)
- {
- goto Exit0;
- }
- Status = ZwQuerySystemInformation(SystemHandleInformation, pbuffer, 0x1000, &dwSize);
- if(!NT_SUCCESS(Status))
- {
- if (STATUS_INFO_LENGTH_MISMATCH != Status)
- {
- goto Exit0;
- }
- else
- {
- // 这里大家可以保证程序的正确性使用循环分配稍好
- if (NULL != pbuffer)
- {
- VirtualFree(pbuffer, 0, MEM_RELEASE);
- }
- if (dwSize*2 > 0x4000000) // MAXSIZE
- {
- goto Exit0;
- }
- pbuffer = VirtualAlloc(NULL, dwSize*2, MEM_COMMIT, PAGE_READWRITE);
- if(!pbuffer)
- {
- goto Exit0;
- }
- Status = ZwQuerySystemInformation(SystemHandleInformation, pbuffer, dwSize*2, NULL);
- if(!NT_SUCCESS(Status))
- {
- goto Exit0;
- }
- }
- }
- pmodule = (PSYSTEM_HANDLE_INFORMATION)((PULONG)pbuffer+1);
- dwSize = *((PULONG)pbuffer);
- for(nIndex = 0; nIndex < dwSize; nIndex++)
- {
- Status = NtQueryObject((HANDLE)pmodule[nIndex].Handle, ObjectNameInformation, szName, 512, &dwFlags);
- if (!NT_SUCCESS(Status))
- {
- goto Exit0;
- }
- Status = NtQueryObject((HANDLE)pmodule[nIndex].Handle, ObjectTypeInformation, szType, 128, &dwFlags);
- if (!NT_SUCCESS(Status))
- {
- goto Exit0;
- }
- pNameInfo = (POBJECT_NAME_INFORMATION)szName;
- pNameType = (POBJECT_NAME_INFORMATION)szType;
- printf("%wZ %wZ\n", pNameType, pNameInfo);
- // 匹配是否为需要关闭的句柄名称
- if (0 == wcscmp((wchar_t *)pNameType->Name.Buffer, L"Mutant"))
- {
- if (wcsstr((wchar_t *)pNameInfo->Name.Buffer, CLOSEMUTEXNAME))
- {
- CloseHandle((HANDLE)pmodule[nIndex].Handle);
- goto Exit0;
- }
- }
- }
- Exit0:
- if (NULL != pbuffer)
- {
- VirtualFree(pbuffer, 0, MEM_RELEASE);
- }
- return 0;
- }