Python实现微信互拆体多开代码

admin 2025年3月10日09:33:27评论11 views字数 6129阅读20分25秒阅读模式
Python实现微信互拆体多开代码
代码
import os
import time
import ctypes
import psutil
import win32gui
import win32process
from ctypes import wintypes
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
advapi32 = ctypes.WinDLL('advapi32', use_last_error=True)
SECURITY_WORLD_SID_AUTHORITY = (0, 0, 0, 0, 0, 1)
SECURITY_WORLD_RID = 0
ACL_REVISION = 2
SE_KERNEL_OBJECT = 6
DACL_SECURITY_INFORMATION = 0x00000004
MUTEX_ALL_ACCESS = 0x1F0001
kernel32.CreateMutexW.argtypes = [wintypes.LPVOID, wintypes.BOOL, wintypes.LPCWSTR]
kernel32.CreateMutexW.restype = wintypes.HANDLE
advapi32.AllocateAndInitializeSid.argtypes = [
    ctypes.POINTER(ctypes.c_byte),
    ctypes.c_byte,
    ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong,
    ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong,
    ctypes.POINTER(ctypes.c_void_p)
]
advapi32.AllocateAndInitializeSid.restype = wintypes.BOOL
advapi32.InitializeAcl.argtypes = [wintypes.LPVOID, wintypes.DWORD, wintypes.DWORD]
advapi32.InitializeAcl.restype = wintypes.BOOL
advapi32.AddAccessDeniedAce.argtypes = [wintypes.LPVOID, wintypes.DWORD, wintypes.DWORD, wintypes.LPVOID]
advapi32.AddAccessDeniedAce.restype = wintypes.BOOL
advapi32.SetSecurityInfo.argtypes = [
    wintypes.HANDLE, wintypes.DWORD, wintypes.DWORD, wintypes.LPVOID, wintypes.LPVOID,
    wintypes.LPVOID, wintypes.LPVOID
]
advapi32.SetSecurityInfo.restype = wintypes.DWORD
def Create_wechat_Mutex():
    mutex_created = False
    try:
        h_mutex = kernel32.CreateMutexW(None, False, "_WeChat_App_Instance_Identity_Mutex_Name")
        if not h_mutex:
            raise ctypes.WinError(ctypes.get_last_error())
        sid_auth_world = (ctypes.c_byte * 6)(*SECURITY_WORLD_SID_AUTHORITY)
        p_everyone_sid = ctypes.c_void_p()
        if not advapi32.AllocateAndInitializeSid(
            ctypes.cast(ctypes.byref(sid_auth_world), ctypes.POINTER(ctypes.c_byte)),
            1,
            SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0,
            ctypes.byref(p_everyone_sid)
        ):
            raise ctypes.WinError(ctypes.get_last_error())
        sz_buffer = (ctypes.c_byte * 4096)()
        p_acl = ctypes.cast(sz_buffer, ctypes.POINTER(ctypes.c_byte))
        if not advapi32.InitializeAcl(p_acl, ctypes.sizeof(sz_buffer), ACL_REVISION):
            raise ctypes.WinError(ctypes.get_last_error())
        if not advapi32.AddAccessDeniedAce(p_acl, ACL_REVISION, MUTEX_ALL_ACCESS, p_everyone_sid):
            raise ctypes.WinError(ctypes.get_last_error())
        result = advapi32.SetSecurityInfo(
            h_mutex, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, None, None, p_acl, None
        )
        if result != 0:
            raise ctypes.WinError(result)
        mutex_created = True
        print("提示:互斥体创建成功,将尝试通过互斥体绕过微信单分身限制")
    except Exception as e:
        print(f"警告:互斥体创建失败 ({e}),将尝试直接启动多个分身进行多开")
    return mutex_created
def get_pid(process_name):
    pids = []
    for proc in psutil.process_iter(['pid', 'name']):
        if proc.info['name'] == process_name:
            pids.append(proc.info['pid'])
    return pids
def get_process_path(pid):
    try:
        process = psutil.Process(pid)
        return process.exe()
    except psutil.NoSuchProcess:
        return None
def get_hwnd_from_pid(pids):
    hwnds = []
    def callback(hwnd, extra):
        _, pid = win32process.GetWindowThreadProcessId(hwnd)
        window_title = win32gui.GetWindowText(hwnd)
        if pid in pids and win32gui.IsWindowVisible(hwnd) and window_title != "":
            hwnds.append(hwnd)
        return True
    win32gui.EnumWindows(callback, None)
    return hwnds
def get_screen_size():
    user32 = ctypes.windll.user32
    screen_width = user32.GetSystemMetrics(0)
    screen_height = user32.GetSystemMetrics(1)
    return screen_width, screen_height
def arrange_windows(windows):
    num_windows = len(windows)
    if num_windows == 0:
        print("警告:没有检测到新打开的微信窗口,可能启动失败")
        return
    screen_width, screen_height = get_screen_size()
    left, top, right, bottom = win32gui.GetWindowRect(windows[0])
    window_width = right - left
    window_height = bottom - top
    spacing = 10
    rows = 2
    if num_windows <= 2:
        rows = 1
    elif num_windows >= 3:
        rows = 2
    windows_per_row = []
    if rows == 1:
        windows_per_row = [num_windows]
    else:
        windows_per_row = [num_windows // 2 + num_windows % 2, num_windows // 2]
    start_y = (screen_height - rows * (window_height + spacing)) // 2
    index = 0
    for row in range(rows):
        current_cols = windows_per_row[row]
        total_width = current_cols * window_width + (current_cols - 1) * spacing
        start_x = (screen_width - total_width) // 2
        for col in range(current_cols):
            if index >= num_windows:
                break
            x = start_x + col * (window_width + spacing)
            y = start_y + row * (window_height + spacing)
            win32gui.MoveWindow(windows[index], x, y, window_width, window_height, True)
            index += 1
print("微信公众号:蓝胖子之家")
print("微信多开工具,正在初始化...")
mutex_success = Create_wechat_Mutex()
last_pids = get_pid("WeChat.exe")
initial_count = len(last_pids)
print(f"检测结果:当前运行的微信进程数为 {initial_count}")
if len(last_pids) > 0:
    path = get_process_path(last_pids[0])
    print(f"提示:检测到微信路径为 {path},将使用此路径启动新分身")
else:
    default_path = r"C:\Program Files (x86)\Tencent\WeChat\WeChat.exe"
    if os.path.exists(default_path):
        path = default_path
        print(f"提示:未检测到运行中的微信,将使用默认路径 {path} 启动")
    else:
        print("错误:未检测到运行中的微信,且默认路径 {default_path} 无效")
        print("操作指引:请先手动打开一个微信(无需登录),然后重新运行此脚本")
        print("注意:如果微信安装路径不是默认值,请修改脚本中的 default_path 变量")
        exit(1)
open_wx_num = 3
print(f"提示:即将启动 {open_wx_num} 个新的微信分身,请稍候...")
for i in range(open_wx_num):
    try:
        os.startfile(path)
        print(f"状态:已启动第 {i+1}/{open_wx_num} 个微信分身")
    except Exception as e:
        print(f"错误:启动第 {i+1} 个分身失败 ({e}),请检查路径或微信版本")
print("提示:等待新分身加载,可能需要几秒钟...")
time.sleep(2)
now_pids = get_pid("WeChat.exe")
pids = list(set(now_pids) - set(last_pids))
new_count = len(now_pids)
print(f"检测结果:启动后微信进程数为 {new_count}")
print(f"检测结果:新增微信进程数为 {len(pids)}")
if new_count > initial_count:
    if mutex_success:
        print(f"成功:通过互斥体操作实现多开,新增 {len(pids)} 个分身")
    else:
        print(f"成功:通过直接启动多个分身实现多开,新增 {len(pids)} 个分身")
else:
    print("失败:无法启动新的微信分身")
    print("可能原因:1. 微信版本限制了多开;2. 路径错误;3. 系统权限不足")
    print("解决方法:1. 尝试以管理员权限运行脚本;2. 检查微信路径;3. 使用旧版微信")
    exit(1)
wechat_windows = get_hwnd_from_pid(pids)
print("提示:正在排列微信窗口,请稍候...")
time.sleep(1)
arrange_windows(wechat_windows)
print(f"完成:窗口排列成功,共排列 {len(wechat_windows)} 个微信窗口")
print("提示:多开完成,您可以开始登录不同的微信账号")

启动数量: 修改 open_wx_num 的值,例如改为 3

open_wx_num = 3

绕过微信单实例限制

微信默认通过一个名为_WeChat_App_Instance_Identity_Mutex_Name的互斥体(Mutex)限制多开。代码主要实现方法是创建并修改这个互斥体的权限,或者直接启动多个进程并规避限制。

1. 创建并修改互斥体权限

函数 Create_wechat_Mutex() 是实现多开的核心:

  • 创建互斥体
    :使用kernel32.CreateMutexW创建名为 _WeChat_App_Instance_Identity_Mutex_Name 的互斥体。这是微信用于检测是否已运行实例的关键。
  • 修改访问权限
    • 通过 advapi32.AllocateAndInitializeSid 创建一个“Everyone”安全标识符(SID),代表所有用户。
    • 使用 advapi32.InitializeAcl 初始化一个访问控制列表(ACL),然后通过 advapi32.AddAccessDeniedAce 添加拒绝访问规则,禁止其他进程访问这个互斥体。
    • 最后调用 advapi32.SetSecurityInfo 将修改后的ACL应用到互斥体上。

检测和启动微信进程

  • 获取进程信息
    :函数 get_pid("WeChat.exe") 使用 psutil 检测当前运行的微信进程数量,记录初始状态。
  • 确定路径
:get_process_path 获取运行中微信的可执行文件路径,若无则使用默认路径(如 C:Program Files (x86)TencentWeChatWeChat.exe)。
  • 启动新实例
    :通过 os.startfile(path) 循环启动指定数量的微信进程(默认3个)。

原文始发于微信公众号(蓝胖子之家):Python实现微信互拆体多开代码

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年3月10日09:33:27
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Python实现微信互拆体多开代码https://cn-sec.com/archives/3819956.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息