欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ 微信多開的實現(xiàn)

 更新時間:2022年02月16日 09:25:52   作者:喬安生  
本文主要介紹了C++ 微信多開的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

應(yīng)用是如何判斷多開

一、通過查找窗口標(biāo)題或者類名來判斷程序是否正在運行。

二、通過互斥對象確定程序是否運行,大多數(shù)軟件都是使用CreateMutexW 判斷多開的。

三、內(nèi)存映射物理文件,控制多開。

微信是使用 CreateMutexW 函數(shù)判斷多開的。

CreateMutexW 是如何判斷多開的。

微軟 MSDN 文檔

CreateMutexW 這個函數(shù)就是根據(jù)變量創(chuàng)建一個鎖,下回再用相同的變量調(diào)用CreateMutexW 的時候就可以控制是否允許多開。

如何找到微信中的 CreateMutexW 方法和互斥體

使用 procexp.exe 尋找互斥體,這個軟件是微軟官方出的 微軟官網(wǎng)下載地址

登陸微信后

打開 Process Explorer

找到微信的進(jìn)程 WeChat.exe

CTRL + L 查看微信這個進(jìn)程占用的各種資源

根據(jù)這個字符串的名字判斷出來的_WeChat_App_Instance_Identity_Mutex_Name 這個字符串就是微信的互斥體

找到 CreateMutexW 這個函數(shù)

使用 OD 直接在內(nèi)存中找 CreateMutexW 方法,并調(diào)試 CreateMutexW 方法,手動修改互斥體,啟動多個微信實例。

使用 OD 打開微信

CTRL + G 搜索 CreateMutexW 方法

跳轉(zhuǎn)到 CreateMutexW 方法后,在這個位置打一個斷點 F2

打完斷點之后繼續(xù)運行

在堆棧窗口可以看到 CreateMutexW 方法傳遞的三個參數(shù)

第一個參數(shù):NULL

第二個參數(shù):FALSE

第三個參數(shù):_WeChat_App_Instance_Identity_Mutex_Name

獲取到 _WeChat_App_Instance_Identity_Mutex_Name 這個互斥體在內(nèi)存中的地址 02BBB198

使用 CE 修改 _WeChat_App_Instance_Identity_Mutex_Name 這個字符串

打開CE后選擇進(jìn)程

選擇當(dāng)前進(jìn)程

選擇微信進(jìn)程

打開

點擊 手動添加地址

輸入互斥體的內(nèi)存地址

選擇字符串

字符串長度設(shè)置成110

勾選 Unicode

選擇數(shù)值這列,雙擊 _WeChat_App_Instance_Identity_Mutex_Name

在彈框中修改一下這個字符串

內(nèi)存修改完成,回到 OD

F2 取消斷點

繼續(xù)運行,直到打開一個微信

這個微信他身上的互斥體就是手動修改的那個字符串

通過正常途徑在啟動一個微信

正常啟動

正常登陸

代碼思路

思路
PC:啟動微信到登陸頁面(那個頁面都行,只要微信進(jìn)程起來就可以了)
代碼:
一、提升當(dāng)前進(jìn)程權(quán)限,提升到最大
二、獲取當(dāng)前操作系統(tǒng)中指定的所有進(jìn)程(多開的時候會有多個微信進(jìn)程,進(jìn)程名字是一模一樣的)
三、獲取到系統(tǒng)中所有資源(內(nèi)存中的資源,包含 文件,路徑,鎖,事件,線程等等)
四、通過指定的進(jìn)程和已找到的資源,匹配到防多開的那個互斥體
4.1 干掉這個互斥體
PC:可以正常啟動下一個微信

使用
啟動微信后,如果想在啟動一個微信,執(zhí)行一遍代碼就可以正常啟動了
微信版本:3.4.5.27
已在三臺電腦上測試(物理機)
理論上應(yīng)該是所有版本的微信都能用 (只要這個互斥體的字符串不變)

缺點:直接修改了微信進(jìn)程中的資源

/*
    processName 微信進(jìn)程名稱
    nutexName 微信互斥體字符串
*/
void CloseMutex(const WCHAR* processName, const WCHAR* nutexName) {
    // 提升當(dāng)前進(jìn)程的訪問權(quán)限
    ElevatePrivileges();
    // 找到所有的指定的進(jìn)程 (多開的情況下會有多個)
    vector<DWORD> pidList;
    pidList = GetProcessIdsByName((WCHAR*)processName);
    if (pidList.size() == 0)
    {
        // 沒有開啟或者沒有找到指定的進(jìn)程
        return;
    }
    // 獲取到操作系統(tǒng)所有進(jìn)程的資源
    LPVOID lp = GetSystemProcessHandleInfo();
    // 遍歷所有的指定進(jìn)程
    for (int i = 0; i < pidList.size(); i++)
    {
        // 遍歷從系統(tǒng)中獲取到的所有進(jìn)程 與 指定進(jìn)程進(jìn)行匹配
        // 遍歷指定進(jìn)程中的資源
        // 找到互斥體
        // 直接干掉這個互斥體
        // 完成,后面就可以繼續(xù)打開PC端微信了
        EnumObjInfo(lp, pidList[i], processName);
    }
}

提升權(quán)限

bool ElevatePrivileges() {
    HANDLE hToken = NULL;
    //打開當(dāng)前進(jìn)程的訪問令牌
    int hRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
    if (hRet)
    {
        TOKEN_PRIVILEGES tp;
        tp.PrivilegeCount = 1;
        //取得描述權(quán)限的LUID
        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        //調(diào)整訪問令牌的權(quán)限
        AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
        CloseHandle(hToken);
    }
    return TRUE;
}

根據(jù)進(jìn)程名字,獲取到系統(tǒng)中全部的進(jìn)程信息

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;
}

獲取系統(tǒng)中的所有資源

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);
                            };
                        }
                    }
                }
            }
        }
    }
}

 到此這篇關(guān)于C++ 微信多開的實現(xiàn)的文章就介紹到這了,更多相關(guān)C++ 微信多開內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實現(xiàn)LeetCode(133.克隆無向圖)

    C++實現(xiàn)LeetCode(133.克隆無向圖)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(133.克隆無向圖),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 淺談Qt QGraphics體系及刷新機制介紹

    淺談Qt QGraphics體系及刷新機制介紹

    這篇文章主要介紹了淺談Qt QGraphics體系及刷新機制介紹,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • 基于Qt實現(xiàn)電子木魚小游戲

    基于Qt實現(xiàn)電子木魚小游戲

    今年最火爆的解壓小游戲電子木魚,現(xiàn)在許多軟件都上架了這個小程序。我在網(wǎng)上看了一下基本上都是用py和Java寫的,所以我用QT重新寫了一下,作為小白練手項目非常適合,快跟隨小編一起學(xué)習(xí)一下吧
    2023-01-01
  • C語言編程題楊氏矩陣算法快速上手示例詳解

    C語言編程題楊氏矩陣算法快速上手示例詳解

    這篇文章主要為大家介紹了C語言編程題楊氏矩陣算法快速上手的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-10-10
  • 基于C++編寫一個文章生成器

    基于C++編寫一個文章生成器

    這篇文章主要為大家介紹一個有趣的小程序,就是利用C++編寫一個文章生成器,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下
    2023-03-03
  • C語言使用strcmp()函數(shù)比較兩個字符串的實現(xiàn)

    C語言使用strcmp()函數(shù)比較兩個字符串的實現(xiàn)

    這篇文章主要介紹了C語言使用strcmp()函數(shù)比較兩個字符串的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 淺析string類字符串和C風(fēng)格字符串之間的區(qū)別

    淺析string類字符串和C風(fēng)格字符串之間的區(qū)別

    string類是標(biāo)準(zhǔn)庫的類,并不是內(nèi)置類型,標(biāo)準(zhǔn)庫就像是我們自己定義的類差不多的,string類型對象沒有標(biāo)配'\0'結(jié)尾的
    2013-09-09
  • 詳解C++中stoi/stol/stoll函數(shù)的用法

    詳解C++中stoi/stol/stoll函數(shù)的用法

    這篇文章主要為大家詳細(xì)介紹了C++中stoi、stol、stoll函數(shù)的具體用法,文中的示例代碼講解詳細(xì),對我們學(xué)校C++有一點的幫助,需要的可以參考一下
    2023-03-03
  • C/C++哈希表優(yōu)化LeetCode題解997找到小鎮(zhèn)的法官

    C/C++哈希表優(yōu)化LeetCode題解997找到小鎮(zhèn)的法官

    這篇文章主要為大家介紹了C/C++哈希表優(yōu)化題解997找到小鎮(zhèn)的法官示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • C++實現(xiàn)LeetCode(60.序列排序)

    C++實現(xiàn)LeetCode(60.序列排序)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(60.序列排序),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07

最新評論