zoukankan      html  css  js  c++  java
  • 枚举进程句柄File,Section,Mutant,Timer关闭Mutex句柄实现游戏多开

    原文: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
    ", 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;
    }

    CLOSEMUTEXNAME 为互斥的句柄名称,需要为宽字节;

    程序执行结果如下:

    为了测试方便直接把程序写入了main函数中,大家使用的时候稍微修改便可, 不过!得理解程序意思才行啊。 copy代码不做思考的程序员不是好裁缝!

    参考文章列表:

    ZwQuerySystemInformation枚举内核模块及简单应用 http://hi.baidu.com/_achillis/item/8b33ead8ccac28ea3cc2cb17

  • 相关阅读:
    Freemarker
    加解密算法、消息摘要、消息认证技术、数字签名与公钥证书
    Jenkins入门
    kafka实战
    多线程文件下载
    Excel操作报表
    @Pointcut 使用@annotation 带参数
    博客园设置
    Windows下 tensorboard显示No graph definition files were found的问题解决
    通过GitHub Desktop 上传代码到github 远程仓库
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/3909003.html
Copyright © 2011-2022 走看看