解除游戏多开限制,关闭互斥体句柄

news2024/12/25 10:21:12

游戏限制多开有很多种方法

比如说遍历窗口,遍历进程,配置文件,注册表,互斥体,mac地址,ip,公共文件,内存映射等等.方法很多.
但是绝大部分游戏限制多开都是采用的互斥体.
这节课我们来讲解一下关闭互斥体句柄来实现多开.例子为CQYH

 

(这里的防护建议是,增加多种多开限制的方法 以及 逻辑中增加多该互斥体的使用,这样可以避免直接被恶意关闭)

一.验证限制多开

首先我们打开游戏
然后再开第二个窗口
发现已经检测到我们开了一个窗口,只是没有进行限制

再开第三个窗口的时候出现了限制

很明显限制了多开,只能开2个

 

二.工具查看互斥体并关闭

我们可以使用工具来查看互斥体,大家可以用XT,PCH等等工具
也可以直接到公众号:任鸟飞逆向 里下载Pyark.zip
打开软件,找到我们的进程,右键查看句柄

出现了很多句柄, 找到Mutant类型的句柄

发现有很多,没有名字的可以不管
剩下有名字的句柄有20-30个
我们逐一关闭,看看关闭哪个之后就可以多开窗口了
发现关闭这个就可以了,名字是  AOD_Game

可以开3个窗口了

三,编写代码,关闭互斥体句柄

添加一个头文件"Mutex.h"
用作关闭互斥体句柄
 
#pragma once
#include <string.h>
#include <windows.h>
#include <winternl.h>
#include <TlHelp32.h>

// 定义需要的宏
#define STATUS_SUCCESS 0x00UL
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004

#define SystemHandleInformation 16
#define SE_DEBUG_PRIVILEGE 0x14

// 定义需要用到的结构体
typedef enum _OBJECT_INFORMATION_CLASSEX {
ObjBasicInformation = 0,
ObjNameInformation,
ObjTypeInformation,
} OBJECT_INFORMATION_CLASSEX;

typedef enum _PROCESSINFOCLASSEX
{
ProcessHandleInformation = 20,
}PROCESSINFOCLASSEX;

typedef struct _SYSTEM_HANDLE
{
ULONG ProcessId;
BYTE ObjectTypeNumber;
BYTE Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantAccess;
}SYSTEM_HANDLE;

typedef struct _SYSTEM_HANDLE_INFORMATION
{
DWORD HandleCount;
SYSTEM_HANDLE Handles[1];
}SYSTEM_HANDLE_INFORMATION;

typedef struct _OBJECT_NAME_INFORMATION
{
UNICODE_STRING ObjectName;
}OBJECT_NAME_INFORMATION;

// 声明未导出API
typedef NTSTATUS(WINAPI* ZwQueryInformationProcessProc)(HANDLE, PROCESSINFOCLASSEX, LPVOID, DWORD, PDWORD);
ZwQueryInformationProcessProc ZwQueryInformationProcess;

typedef NTSTATUS(WINAPI* ZwQuerySystemInformationProc)(DWORD, PVOID, DWORD, DWORD*);
ZwQuerySystemInformationProc ZwQuerySystemInformation;

typedef NTSTATUS(WINAPI* ZwQueryObjectProc)(HANDLE, OBJECT_INFORMATION_CLASSEX, PVOID, ULONG, PULONG);
ZwQueryObjectProc ZwQueryObject;

typedef NTSTATUS(WINAPI* RtlAdjustPrivilegeProc)(DWORD, BOOL, BOOL, PDWORD);
RtlAdjustPrivilegeProc RtlAdjustPrivilege;

typedef DWORD(WINAPI* ZwSuspendProcessProc)(HANDLE);
ZwSuspendProcessProc ZwSuspendProcess;

typedef DWORD(WINAPI* ZwResumeProcessProc)(HANDLE);
ZwResumeProcessProc ZwResumeProcess;

#pragma warning (disable: 6011) 
#pragma warning (disable: 6001) 
#pragma warning (disable: 6387) 
#include <stdio.h>

// 提升进程权限
BOOL ElevatePrivileges()
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
tkp.PrivilegeCount = 1;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return FALSE;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
{
return FALSE;
}

return TRUE;
}

// 初始化未导出API
BOOL GetUnDocumentAPI()
{
ZwSuspendProcess = (ZwSuspendProcessProc)
GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwSuspendProcess");

ZwQuerySystemInformation = (ZwQuerySystemInformationProc)
GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwQuerySystemInformation");

ZwQueryObject = (ZwQueryObjectProc)
GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwQueryObject");

ZwResumeProcess = (ZwResumeProcessProc)
GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwResumeProcess");

ZwQueryInformationProcess = (ZwQueryInformationProcessProc)
GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwQueryInformationProcess");

if ((ZwSuspendProcess == NULL) || \
(ZwQuerySystemInformation == NULL) || \
(ZwQueryObject == NULL) || \
(ZwResumeProcess == NULL) || \
(ZwQueryInformationProcess == NULL))
return FALSE;

return TRUE;
}

// 关闭指定Mutex 有问题关注公众号 任鸟飞逆向
BOOL closeMutexHandle(UINT Proc_id, const wchar_t* Mutex_name)
{
HANDLE duplicateHnd, sourceHnd = 0;
DWORD procHndNum;
SYSTEM_HANDLE* currnetHnd;
DWORD buffLen = 0x1000;
NTSTATUS status;
SYSTEM_HANDLE_INFORMATION* buff = (SYSTEM_HANDLE_INFORMATION*)malloc(buffLen);
UINT count = 0;
if ((ElevatePrivileges() == FALSE) || (GetUnDocumentAPI() == FALSE))
return FALSE;

do
{
status = ZwQuerySystemInformation(SystemHandleInformation, buff, buffLen, &buffLen);
if (status == STATUS_INFO_LENGTH_MISMATCH)
{
free(buff);
buff = (SYSTEM_HANDLE_INFORMATION*)malloc(buffLen);
}
else
break;

} while (1);

OBJECT_NAME_INFORMATION* objNameInfo = (OBJECT_NAME_INFORMATION*)malloc(0x1000);
OBJECT_NAME_INFORMATION* objTypeInfo = (OBJECT_NAME_INFORMATION*)malloc(0x1000);

for (int idx = 0; idx < (int)buff->HandleCount; idx++)
{
currnetHnd = &(buff->Handles[idx]);

if (currnetHnd->ProcessId == Proc_id)
{
sourceHnd = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_DUP_HANDLE | PROCESS_SUSPEND_RESUME, FALSE, Proc_id);
(ZwSuspendProcess)(sourceHnd);
(ZwQueryInformationProcess)(sourceHnd, ProcessHandleInformation, &procHndNum, sizeof(DWORD), NULL);
//进程有效句柄从4开始,每次以4递增
unsigned short hndNum = 4;
for (int idx = 0; idx < (int)procHndNum; hndNum += 4)
{
//判断是否为有效句柄,返回TRUE,就是有效句柄
if (!DuplicateHandle(sourceHnd,
(HANDLE)hndNum,
GetCurrentProcess(),
&duplicateHnd, 0, FALSE, DUPLICATE_SAME_ACCESS))
{
continue;
}
else
{
memset(objNameInfo, 0, 0x1000);
memset(objTypeInfo, 0, 0x1000);

ZwQueryObject((HANDLE)duplicateHnd, ObjNameInformation, objNameInfo, 0x1000, NULL);
ZwQueryObject((HANDLE)duplicateHnd, ObjTypeInformation, objTypeInfo, 0x1000, NULL);

//找到互斥体 比较名字
if (wcscmp(objTypeInfo->ObjectName.Buffer, L"Mutant") == 0)
{
if (objNameInfo->ObjectName.Length != 0 && wcsstr(objNameInfo->ObjectName.Buffer, Mutex_name) != 0)
{
printf("%ws\n", objNameInfo->ObjectName.Buffer);
CloseHandle(duplicateHnd);

if (DuplicateHandle(sourceHnd,
(HANDLE)hndNum,
GetCurrentProcess(),
&duplicateHnd, 0, FALSE, DUPLICATE_CLOSE_SOURCE))
{
CloseHandle(duplicateHnd);
(ZwResumeProcess)(sourceHnd);
return TRUE;
}
}
count++;
if (count == 20) { return FALSE; }
}

CloseHandle(duplicateHnd);
idx++;
}
}
}
}
return FALSE;

然后我们调用
 
closeMutexHandle(sm[i].pid,L"AOD_Game");

四,调整窗口位置进行多开
然后我们进行窗口布局

好的,我们的效果实现了.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/418103.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

系统安全与应用【上】

文章目录1.账号安全控制1.1 系统账号清理1.2 密码安全控制1.3 命令历史限制1.4 终端自动注销2.系统引导和登录控制2.1 使用su命令切换用户2.2 限制使用su命令的用户3.可插拔式认证模块PAM3.1 linux中的PAM安全认证3.2 PAM认证原理3.3 PAM认证的构成3.4 PAM安全认证流程3.5 使用…

(八)【软件设计师】计算机系统—浮点数

浮点数 浮点数。当机器字长为n时&#xff0c;定点数的补码和移码可表示2的n方个数&#xff0c;而其原码和反码只能表示2"-1个数&#xff08;0的表示占用了两个编码)&#xff0c;因此&#xff0c;定点数所能表示的数值范围比较小&#xff0c;在运算中很容易因结果超出范围而…

实力爆表,日日新成为AI领航者

目录正式发布自建算力SenseChat编程能力图像生成后言上周五&#xff0c;阿里发布大模型通义千问&#xff0c;正式开始邀请内测。本周一&#xff0c;人工智能巨头商汤科技正式发布“日日新”大模型体系&#xff0c;全面丰富的产品体系&#xff0c;多个功能表现超预期&#xff0c…

MobTech MobPush|不同手机厂商推送问题

配置了华为厂商推送&#xff0c;为什么有的华为设备无法接收离线消息 首先&#xff0c;排查配置的华为厂商参数是否正确&#xff1b; 其次&#xff0c;检查华为设备EMUI版本&#xff0c;低于5.0可能不支持&#xff0c;如果低于5.0&#xff0c;可以尝试升级设备里的‘华为移动服…

Google代码覆盖率最佳实践

软件质量保障: 所寫即所思&#xff5c;一个阿里质量人对测试的所感所悟。谷歌一直倡导的领域之一是使用代码覆盖率数据评估风险并识别测试中的真空。然而&#xff0c;代码覆盖率的价值一直是个争议的话题。每次聊到代码覆盖率时&#xff0c;似乎都会引发无尽的争论。由于大家固…

微信小程序开发 | 小程序开发框架

小程序开发框架7.1 小程序模块化开发7.1.1 模块7.1.2 模板7.1.3 自定义组件7.1.4插件7.2 小程序基础样式库—WeUI7.2.1 初识WeUI7.2.2【案例】电影信息展示7.3 使用vue.js开发小程序7.3.1 初识mpvue7.3.2 开发工具7.3.3 项目结构7.3.4【案例】计数器7.4 小程序组件化开发框架7.…

Ztree树状的处理

1.用一个div进行包裹ztree结构&#xff0c;引用相关的js代码和css样式&#xff0c;这里用的样式是awesome.css 所引用的js文件&#xff0c;css文件可以在网上下载&#xff08;这里所用到的jquery-ztree文件放在网盘了&#xff09; <ul id"tree" class"ztre…

企业即时通讯软件开发基本功能有哪些?

即时通讯是基于互联网技术的新型交流沟通方式&#xff0c;是目前最流行的通讯方式&#xff0c;广泛的应用市场使得各种各样的即时通讯软件系统也层出不穷&#xff0c;企业即时通讯就是其中的一种延伸。是一种面向企业终端使用者的网络营销、网络沟通和内容管理的工具服务&#…

mysql基础安装以及问题

mysql 基础安装以及问题安装MySQL8.0的安装&#xff1a;MySQL5.7 版本的安装、配置卸载服务的启动与停止图形化工具推荐安装 官网&#xff1a;https://www.mysql.com MySQL8.0的安装&#xff1a; 这里是写你直接要安装的目录&#xff1a; 之后配置mysql8.0 注意&#x…

不会注册ChatGPT?4个国内网站让你尽情体验

最近火出圈的科技新词非“ChatGPT”莫属了。 但是由于ChatGPT注册起来比较困难&#xff0c;我到现在都还学不会如何注册.... 但是&#xff01;世上无难事&#xff01;只要有心人&#xff01; 我千辛万苦终于找到几个ChatGPT平替的网站了。 AI中文智能对话 地址&#xff1a;…

目标检测入门:发展历史

预备知识 分类classification 输出:物体的类别 评估方法:准确率 定位location 输出:方框在图片中的位置(x,y,w,h) 评估方法:交并比IOU 定位的解决思路: 思路一:看做回归问题 看做回归问题,我们需要预测出(x,y,w,h)四个参数的值,从而得出方框的位置 成为class…

数字证书的相关专业名词(下)---OCSP及其java中的应用

一、前言 上篇文章我们了解了根证书和校验证书有效性中的一个比较重要的渠道–CRL&#xff0c;但是CRL有着时间延迟&#xff0c;网络带宽消耗等缺点&#xff0c;本篇文章我们了解另一种更高效也是目前被广泛应用的校验证书有效性的另一种方式–OCSP&#xff0c;并且我会结合ja…

4年测试工程师经历,下一步转开发还是继续测试?

​测试四年&#xff0c;没有积累编程脚本能力和自动化经验&#xff0c;找工作时都要求语言能力&#xff0c;自动化框架。感觉开发同事积累的经历容易找工作。下一步&#xff0c;想办法转开发岗还是继续测试&#xff1f;&#xff1f;&#xff1f;正常情况下&#xff0c;有了四年…

matlab图像处理系列:图片圈数识别+编号标记位置

matlab图像处理系列&#xff1a;图片圈数识别编号标记位置一、app界面介绍二、实现过程step1图像二值化step2 图像close 做差step3 像素阈值处理step4 清除小区域step5 识别联通区域 并在原图上标记三、项目分享一、app界面介绍 读取图片按钮&#xff1a;使用ui交互工具&#x…

单词管理系统【GUI/Swing+MySQL】(Java课设)

系统类型 Swing窗口类型Mysql数据库存储数据 使用范围 适合作为Java课设&#xff01;&#xff01;&#xff01; 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址&#xff1a;https://download.csdn.net/download/qq_50954361/87682568 更多系统资源库…

Prometheus - Grafana 监控 MysqlD Linux服务器 详细版

readme 其实上一篇文章已经把如何操作&#xff0c;基本上是写全了&#xff08;因为是从本文精炼出来的&#xff09;本文可能更多的是补充一些关于 Prometheus 和 Grafana 的理论 &#xff0c;关系等。 操作 标签&#xff1a;是必看&#xff0c;要操作的。 非必要看 标签&…

DP7416国产192K数字音频接收芯片兼容替代CS8416

目录192K 数字音频应用DP7416简介芯片特性192K 数字音频应用 采样率192khz&#xff0c;能将192,000hz以下的频率都录下来&#xff0c;而且对声波每秒连续采样192,000次。在回放的时候&#xff0c;这192,000个采样点按顺序播放&#xff0c;从而还原原来的声音。   过采样技术除…

微信小程序开发 | 综合项目-点餐系统

综合项目-点餐系统8.1 开发前准备8.1.1 项目展示8.1.2 项目分析8.1.3 项目初始化8.1.4 封装网络请求8.2 【任务1】商家首页8.2.1 任务分析8.2.2 焦点图切换8.2.3 中间区域单击跳转到菜单列表8.2.4 底部商品展示8.3 【任务2】菜单列表8.3.1 任务分析8.3.2 折扣信息区8.3.3 设计菜…

关系数据库及其设计

目录 一、关系数据库 二、关系数据库设计 1、需求分析 2&#xff0e;概念结构设计 3&#xff0e;逻辑结构设计 4&#xff0e;数据库表的优化与规范化 5、规范化的大学数据库 6、数据库中表间关系 三、关系数据库的完整性 1&#xff0e;实体完整性约束&#xff08;PRI…

51电动车报警器.md

1.项目接线 接线示意图和实物图 示意图&#xff1a; 实物图&#xff1a; 信号传输路线 路线1&#xff1a; 433遥控信号 ——> 433接收模块D0引脚以及D1引脚 ——> 单片机P1^2引脚以及P1^3引脚 ——> 单片机P1^1引脚 ——> 继电器IN引脚 ——> 继电器COM口和NO口…