<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
一、通過查詢視窗標題或者類名來判斷程式是否正在執行。
二、通過互斥物件確定程式是否執行,大多數軟體都是使用CreateMutexW 判斷多開的。
三、記憶體對映物理檔案,控制多開。
微信是使用 CreateMutexW 函數判斷多開的。
CreateMutexW 是如何判斷多開的。
微軟 MSDN 檔案
CreateMutexW 這個函數就是根據變數建立一個鎖,下回再用相同的變數呼叫CreateMutexW 的時候就可以控制是否允許多開。
如何找到微信中的 CreateMutexW 方法和互斥體
使用 procexp.exe 尋找互斥體,這個軟體是微軟官方出的 微軟官網下載地址
登陸微信後
開啟 Process Explorer
找到微信的程序 WeChat.exe
CTRL + L 檢視微信這個程序佔用的各種資源
根據這個字串的名字判斷出來的_WeChat_App_Instance_Identity_Mutex_Name 這個字串就是微信的互斥體
找到 CreateMutexW 這個函數
使用 OD 直接在記憶體中找 CreateMutexW 方法,並偵錯 CreateMutexW 方法,手動修改互斥體,啟動多個微信範例。
使用 OD 開啟微信
CTRL + G 搜尋 CreateMutexW 方法
跳轉到 CreateMutexW 方法後,在這個位置打一個斷點 F2
打完斷點之後繼續執行
在堆疊視窗可以看到 CreateMutexW 方法傳遞的三個引數
第一個引數:NULL
第二個引數:FALSE
第三個引數:_WeChat_App_Instance_Identity_Mutex_Name
獲取到 _WeChat_App_Instance_Identity_Mutex_Name 這個互斥體在記憶體中的地址 02BBB198
使用 CE 修改 _WeChat_App_Instance_Identity_Mutex_Name 這個字串
開啟CE後選擇程序
選擇當前程序
選擇微信程序
開啟
點選 手動新增地址
輸入互斥體的記憶體地址
選擇字串
字串長度設定成110
勾選 Unicode
選擇數值這列,雙擊 _WeChat_App_Instance_Identity_Mutex_Name
在彈框中修改一下這個字串
記憶體修改完成,回到 OD
F2 取消斷點
繼續執行,直到開啟一個微信
這個微信他身上的互斥體就是手動修改的那個字串
通過正常途徑在啟動一個微信
正常啟動
正常登陸
程式碼思路
思路
PC:啟動微信到登陸頁面(那個頁面都行,只要微信程序起來就可以了)
程式碼:
一、提升當前程序許可權,提升到最大
二、獲取當前作業系統中指定的所有程序(多開的時候會有多個微信程序,程序名字是一模一樣的)
三、獲取到系統中所有資源(記憶體中的資源,包含 檔案,路徑,鎖,事件,執行緒等等)
四、通過指定的程序和已找到的資源,匹配到防多開的那個互斥體
4.1 幹掉這個互斥體
PC:可以正常啟動下一個微信使用
啟動微信後,如果想在啟動一個微信,執行一遍程式碼就可以正常啟動了
微信版本:3.4.5.27
已在三臺電腦上測試(物理機)
理論上應該是所有版本的微信都能用 (只要這個互斥體的字串不變)缺點:直接修改了微信程序中的資源
/* processName 微信程序名稱 nutexName 微信互斥體字串 */ void CloseMutex(const WCHAR* processName, const WCHAR* nutexName) { // 提升當前程序的存取許可權 ElevatePrivileges(); // 找到所有的指定的程序 (多開的情況下會有多個) vector<DWORD> pidList; pidList = GetProcessIdsByName((WCHAR*)processName); if (pidList.size() == 0) { // 沒有開啟或者沒有找到指定的程序 return; } // 獲取到作業系統所有程序的資源 LPVOID lp = GetSystemProcessHandleInfo(); // 遍歷所有的指定程序 for (int i = 0; i < pidList.size(); i++) { // 遍歷從系統中獲取到的所有程序 與 指定程序進行匹配 // 遍歷指定程序中的資源 // 找到互斥體 // 直接幹掉這個互斥體 // 完成,後面就可以繼續開啟PC端微信了 EnumObjInfo(lp, pidList[i], processName); } }
提升許可權
bool ElevatePrivileges() { HANDLE hToken = NULL; //開啟當前程序的存取令牌 int hRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken); if (hRet) { TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; //取得描述許可權的LUID LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //調整存取令牌的許可權 AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); CloseHandle(hToken); } return TRUE; }
根據程序名字,獲取到系統中全部的程序資訊
vector<DWORD> GetProcessIdsByName(WCHAR* processName) { vector<DWORD> pidList; //HANDLE HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == FALSE) { return pidList; } PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); BOOL bRet = Process32First(hProcessSnap, &pe32); while (bRet) { if (wcscmp(pe32.szExeFile, processName) == 0) { pidList.push_back(pe32.th32ProcessID); } bRet = Process32Next(hProcessSnap, &pe32); } CloseHandle(hProcessSnap); return pidList; }
獲取系統中的所有資源
LPVOID GetSystemProcessHandleInfo() { ULONG cbBuffer = 0x4000; LPVOID pBuffer = NULL; NTSTATUS sts; do { pBuffer = malloc(cbBuffer); if (pBuffer == NULL) { return NULL; } memset(pBuffer, 0, cbBuffer); hNtDLL = GetModuleHandle(TEXT("ntdll.dll")); if (!hNtDLL) return 0; ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION) GetProcAddress(hNtDLL, "ZwQuerySystemInformation"); sts = ZwQuerySystemInformation(SystemHandleInformation, pBuffer, cbBuffer, NULL); if (sts == STATUS_INFO_LENGTH_MISMATCH) { free(pBuffer); pBuffer = NULL; cbBuffer = cbBuffer + 0x4000; // 初始分配的空間不足+4000h } } while (sts == STATUS_INFO_LENGTH_MISMATCH); return pBuffer; }
匹配到互斥體,並幹掉他
void EnumObjInfo(LPVOID pBuffer, DWORD pid, const WCHAR* processName) { char szType[128] = { 0 }; char szName[512] = { 0 }; DWORD dwFlags = 0; POBJECT_NAME_INFORMATION pNameInfo; POBJECT_NAME_INFORMATION pNameType; PSYSTEM_HANDLE_INFORMATION_EX pInfo = (PSYSTEM_HANDLE_INFORMATION_EX)pBuffer; ULONG OldPID = 0; for (DWORD i = 0; i < pInfo->NumberOfHandles; i++) { if (OldPID != pInfo->Information[i].ProcessId) { if (pInfo->Information[i].ProcessId == pid) { HANDLE newHandle; NtQueryObject p_NtQueryObject = (NtQueryObject)GetProcAddress(hNtDLL, "NtQueryObject"); if (p_NtQueryObject == NULL) { return; } DuplicateHandle(OpenProcess(PROCESS_ALL_ACCESS, FALSE, pInfo->Information[i].ProcessId), (HANDLE)pInfo->Information[i].Handle, GetCurrentProcess(), &newHandle, DUPLICATE_SAME_ACCESS, FALSE, DUPLICATE_SAME_ACCESS); NTSTATUS status1 = p_NtQueryObject(newHandle, ObjectNameInformation, szName, 512, &dwFlags); NTSTATUS status2 = p_NtQueryObject(newHandle, ObjectTypeInformation, szType, 128, &dwFlags); pNameInfo = (POBJECT_NAME_INFORMATION)szName; pNameType = (POBJECT_NAME_INFORMATION)szType; if (strcmp(szName, "") && strcmp(szType, "") && status1 != 0xc0000008 && status2 != 0xc0000008) { if (wcsstr(pNameType->Name.Buffer, L"Mutant")) { pNameInfo = (POBJECT_NAME_INFORMATION)szName; pNameType = (POBJECT_NAME_INFORMATION)szType; if (wcsstr(pNameInfo->Name.Buffer, L"_WeChat_App_Instance_Identity_Mutex_Name")) { if (DuplicateHandle(OpenProcess(PROCESS_ALL_ACCESS, FALSE, pInfo->Information[i].ProcessId), (HANDLE)pInfo->Information[i].Handle, GetCurrentProcess(), &newHandle, 0, FALSE, DUPLICATE_CLOSE_SOURCE)) { CloseHandle(newHandle); }; } } } } } } }
到此這篇關於C++ 微信多開的實現的文章就介紹到這了,更多相關C++ 微信多開內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45