微信双开代码实现
互斥量是一个很好玩的东西,可以实现进程的单例。WeChat也是用的Mutant技术实现的防止多开。无事练习下Win32 API编程,于是便有了此贴。实现双开的原理就是跨进程关闭互斥量句柄。各位看官可以自行完善下面代码实现多开。
#include<Windows.h>
#include<TlHelp32.h>
#include<stdio.h>
#include<memory>
#pragma comment(lib,"ntdll")
#define NT_SUCCESS(status) (status>=0)
#define STATUS_INFO_LENGTH_MISMATCH((NTSTATUS)0xC0000004L)
enum PROCESSINFOCLASS {
ProcessHandleInformation = 51
};
typedef struct _PROCESS_HANDLE_TABLE_ENTRY_INFO {
HANDLE HandleValue;
ULONG_PTR HandleCount;
ULONG_PTR PointerCount;
ULONG GrantedAccess;
ULONG ObjectTypeIndex;
ULONG HandleAttributes;
ULONG Reserved;
}PROCESS_HANDLE_TABLE_ENTRY_INFO,*PROCESS_HANDLE_TABLE_ENTRY;
// private
typedef struct _PROCESS_HANDLE_SNAPSHOT_INFORMATION {
ULONG_PTR NumberOfHandles;
ULONG_PTR Reserved;
PROCESS_HANDLE_TABLE_ENTRY_INFO Handles;
}PROCESS_HANDLE_SNAPSHOT_INFORMATION, *PROCESS_HANDLE_SNAPSHOT;
extern "C" NTSTATUS NTAPI NtQueryInformationProcess(
_In_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASS ProcessInformationClass,
_In_ _Out_writes_bytes_(ProcessInformationLength) PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength);
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectNameInformation = 1
} OBJECT_INFORMATION_CLASS;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTRBuffer;
} UNICODE_STRING;
typedef struct _OBJECT_NAME_INFORMATION {
UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
extern "C" NTSTATUS NTAPI NtQueryObject(
_In_opt_ HANDLE Handle,
_In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,
_Out_writes_bytes_opt_(ObjectInformationLength) PVOID ObjectInformation,
_In_ ULONG ObjectInformationLength,
_Out_opt_ PULONG ReturnLength);
DWORD FindWeChat() {
HANDLE hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return 0;
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
// skip the idle process
::Process32First(hSnapshot, &pe);
DWORD pid = 0;
while (::Process32Next(hSnapshot, &pe)) {
if (::_wcsicmp(pe.szExeFile, L"WeChat.exe") == 0) {
// found it
pid = pe.th32ProcessID;
break;
}
}
::CloseHandle(hSnapshot);
return pid;
}
int main() {
DWORD pid = FindWeChat();
if (pid == 0) {
printf("Failed to locate WeChat\n");
return 1;
}
printf("Located WeChat : PID=%u\n", pid);
HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE,
FALSE, pid);
if (!hProcess) {
printf("Failed to open WeChat process handle (error=%u)\n",
GetLastError());
return 1;
}
ULONG size = 1 << 10;
std::unique_ptr<BYTE[]> buffer;
for (;;) {
buffer = std::make_unique<BYTE[]>(size);
auto status = ::NtQueryInformationProcess(hProcess, ProcessHandleInformation,
buffer.get(), size, &size);
if (NT_SUCCESS(status))
break;
if (status == STATUS_INFO_LENGTH_MISMATCH) {
size += 1 << 10;
continue;
}
printf("Error enumerating handles\n");
return 1;
}
WCHAR targetName;
DWORD sessionId;
::ProcessIdToSessionId(pid, &sessionId);
::swprintf_s(targetName,
L"\\Sessions\\%u\\BaseNamedObjects\\_WeChat_App_Instance_Identity_Mutex_Name",
sessionId);
auto len = ::wcslen(targetName);
WCHAR targetName2;
::swprintf_s(targetName2,
L"\\Sessions\\%u\\BaseNamedObjects\\WeChat_GlobalConfig_Multi_Process_Mutex",
sessionId);
auto len2 = ::wcslen(targetName2);
auto info = reinterpret_cast<PROCESS_HANDLE_SNAPSHOT_INFORMATION*>(buffer.get());
for (ULONG i = 0; i < info->NumberOfHandles; i++) {
HANDLE h = info->Handles.HandleValue;
HANDLE hTarget;
if (!::DuplicateHandle(hProcess, h, ::GetCurrentProcess(), &hTarget,
0, FALSE, DUPLICATE_SAME_ACCESS)) {
continue; // move to next handle
}
BYTE nameBuffer;
auto status = ::NtQueryObject(hTarget, ObjectNameInformation,
nameBuffer, sizeof(nameBuffer), nullptr);
auto name = reinterpret_cast<UNICODE_STRING*>(nameBuffer);
if (name->Buffer&&::wcsnicmp(name->Buffer, targetName, len) == 0) {
// found it!
::DuplicateHandle(hProcess, h, ::GetCurrentProcess(), &h,
0, false, DUPLICATE_CLOSE_SOURCE);
printf("Found it! and closed it!\n");
}
if (name->Buffer&&::wcsnicmp(name->Buffer, targetName2, len2) == 0) {
// found it!
::DuplicateHandle(hProcess, h, ::GetCurrentProcess(), &h,
0, false, DUPLICATE_CLOSE_SOURCE);
printf("Found it! and closed it!\n");
}
}
return 0;
}
最终效果:
VIPAccount 发表于 2020-3-23 00:04
楼主牛逼!从代码角度解析了如何双卡,牛!
这里插个楼,也可以用bat实现双开,下面代码保存成.bat文件, ...
还可以在weichat文件夹里放一个bat
start WeChat.exe ""
%0
能开几个就看电脑性能了 楼主牛逼!从代码角度解析了如何双卡,牛!
这里插个楼,也可以用bat实现双开,下面代码保存成.bat文件,双击也可以打开两个微信:
PATH E:\Program Files (x86)\Tencent\WeChat
start WeChat.exe&WeChat.exe
第一行路径为微信安装的跟路径,第二行不变。 虽然看不懂,但是我电脑微信双开的时候,就是用鼠标快速点击微信图标,能点几次就点几次,最后至少会出现3个登陆界面,我电脑是win7系统,微信是最新版本,多开屡试不爽,大家可以试试 虽然看不懂,但是我喜欢用下面的代码start D:\微信\WeChat\WeChat.exe
start D:\微信\WeChat\WeChat.exe 666 原来是文件锁
希望这个锁只有这一个用途 希望只有这一个用途 感谢大佬分享感谢 使用沙箱貌似也可以吧? 跟着大神又学习了 感谢分享{:1_927:} 厉害了。