原文: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, //
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, //
SystemInvalidInfoClass3, //
SystemTimeZoneInformation, // 44 Y N
SystemLookasideInformation, // 45 Y N
SystemSetTimeSlipEvent, // 46 N Y
SystemCreateSession, // 47 N Y
SystemDeleteSession, // 48 N Y
SystemInvalidInfoClass4, //
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[];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
ULONG BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[];
VM_COUNTERS VmCounters;
IO_COUNTERSEX IoCounters; // Windows 2000 only
SYSTEM_THREADS Threads[];
} 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 = ;
PSYSTEM_HANDLE_INFORMATION pmodule = NULL;
POBJECT_NAME_INFORMATION pNameInfo;
POBJECT_NAME_INFORMATION pNameType;
PVOID pbuffer = NULL;
NTSTATUS Status;
int nIndex = ;
DWORD dwFlags = ;
char szType[] = {};
char szName[] = {}; 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, , MEM_RELEASE);
} if (dwSize* > 0x4000000) // MAXSIZE
{
goto Exit0;
} pbuffer = VirtualAlloc(NULL, dwSize*, MEM_COMMIT, PAGE_READWRITE); if(!pbuffer)
{
goto Exit0;
} Status = ZwQuerySystemInformation(SystemHandleInformation, pbuffer, dwSize*, NULL); if(!NT_SUCCESS(Status))
{
goto Exit0;
}
}
} pmodule = (PSYSTEM_HANDLE_INFORMATION)((PULONG)pbuffer+);
dwSize = *((PULONG)pbuffer); for(nIndex = ; nIndex < dwSize; nIndex++)
{ Status = NtQueryObject((HANDLE)pmodule[nIndex].Handle, ObjectNameInformation, szName, , &dwFlags); if (!NT_SUCCESS(Status))
{
goto Exit0;
} Status = NtQueryObject((HANDLE)pmodule[nIndex].Handle, ObjectTypeInformation, szType, , &dwFlags); if (!NT_SUCCESS(Status))
{
goto Exit0;
} pNameInfo = (POBJECT_NAME_INFORMATION)szName;
pNameType = (POBJECT_NAME_INFORMATION)szType; printf("%wZ %wZ\n", pNameType, pNameInfo); // 匹配是否为需要关闭的句柄名称
if ( == 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, , MEM_RELEASE);
} return ;
}

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

程序执行结果如下:

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

参考文章列表:

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

枚举进程句柄File,Section,Mutant,Timer关闭Mutex句柄实现游戏多开的更多相关文章

  1. R3 x64枚举进程句柄

    转载:https://blog.csdn.net/zhuhuibeishadiao/article/details/51292608 需要注意的是:在R3使用ZwQueryObject很容易锁死,需要 ...

  2. CloseHandle 函数--关闭一个句柄

    CloseHandle函数 来源:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx 作用 ...

  3. File.Create(path)未关闭遇到的一点点问题

    本人老菜鸟一枚,不是因为偶是菜鸟中的老手,而是偶是老了但是还是很菜的鸟╮(╯▽╰)╭,不过打今儿起偶想要腾飞…… 今天写文本文件编辑类时遇到一个小问题,下面先将问题描述一下: 1.写文本文件时都会习惯 ...

  4. [Inno Setup] 在 File Section 之前解压文件

    Prototype: procedure ExtractTemporaryFile(const FileName: String); Description: Extracts the specifi ...

  5. File类与FileInfo类

    File是一个静态类,常用于文件操作,读取,修改文件等等.File类的大部分方法最终都是转换为流(Stream)的操作,只不过是.net提取帮你封装好了这些常用的流.并且会自动清理占用的资源. 例如: ...

  6. C/C++文件输入输出操作——FILE*、fstream、windowsAPI

    基于C的文件操作在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O文件操作,下面就分别介绍之. 一.流式文件操作这种方式的文件操作有一个重要的结构FILE,FILE在头文件stdio. ...

  7. C/C++文件输入输出操作——FILE*、fstream、windowsAPI(转载)

    基于C的文件操作 在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O文件操作,下面就分别介绍之. 一.流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在头文件stdi ...

  8. Systm.IO.File.cs

    ylbtech-Systm.IO.File.cs 1.程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c5619 ...

  9. FILE文件流的中fopen、fread、fseek、fclose的使用

    FILE文件流用于对文件的快速操作,主要的操作函数有fopen.fseek.fread.fclose,在对文件结构比较清楚时使用这几个函数会比较快捷的得到文件中具体位置的数据,提取对我们有用的信息,满 ...

随机推荐

  1. PYTHON-模块-time&datetime-练习 +目录规范

    # 作业# 1.请写出规范目录# 并解释各文件夹的作用bin 可执行文件conf 配置文件core 主要业务逻辑db 数据文件lib 库(公共代码 第三方模块)log 日志文件 # 2.改造atm + ...

  2. Linux C 结构体初始化三种形式

    最近看linux代码时发现了结构体 struct 一种新的初始化方式,各方查找对比后总结如下: 1. 顺序初始化教科书上讲C语言结构体初始化是按照顺序方式来讲的,没有涉及到乱序的方式.顺序初始化str ...

  3. 搭建ssh框架项目(三)

    一.创建业务层 (1)创建业务层接口IElecTextService.java package com.cppdy.ssh.service; import com.cppdy.ssh.domain.E ...

  4. liunx centox ssh 配置

    https://www.cnblogs.com/xubing-613/p/6844564.html 一. 查看是否安装了ssh: rpm -qa | grep ssh 重启ssh  service s ...

  5. python 全栈开发,Day127(app端内容播放,web端的玩具,app通过websocket远程遥控玩具播放内容,玩具管理页面)

    昨日内容回顾 1. 小爬爬 内容采集 XMLY 的 儿童频道 requests 2. 登陆 注册 自动登陆 退出 mui.post("请求地址",{数据},function(){} ...

  6. oracle中计算某月的天数

    select add_months(to_date('201202', 'YYYYMM'),1)-to_date('201202', 'YYYYMM') from dual

  7. ERP产品采购申请管理(三十八)

    BLL层代码: public class BioPurchaseBLL { /// <summary> /// 购进申请添加 /// </summary> /// <pa ...

  8. CSP 地铁修建 Kruskal (最小生成树+并查集)

    问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n号枢纽间修建一条地铁. 地铁由很多段隧道组成,每段隧道连接两个交通枢纽.经过勘探,有m段隧道作为候选,两个交通 ...

  9. python全栈开发day45-DOM操作、对象、定时器

    一.昨日内容回顾 1.内置对象 Array String Date Math 2.DOM事件三要素:事件源.事件.事件驱动程序 事件源,事件,事件驱动程序 3.获取事件源的三种方式 var oDiv ...

  10. win10下安装scala

    win10安装scala详细步骤 1.下载安装JDK 2.配置Java环境变量 JAVA_HOME:jdk的安装目录 Path:%JAVA_HOME%\bin; Classpath:%JAVA_HOM ...