修复3.9.2.*版本无法正常运行

This commit is contained in:
xaoyo 2023-10-31 18:04:04 +08:00
parent 71f10d4561
commit fbc4086e07
5 changed files with 75 additions and 42 deletions

View File

@ -57,9 +57,18 @@ class BiasAddr:
self.pm = Pymem("WeChat.exe")
self.bits = self.get_osbits()
self.version = self.get_file_version(self.process_name)
self.address_len = self.get_addr_len()
self.islogin = True
def get_addr_len(self):
version_nums = list(map(int, self.version.split("."))) # 将版本号拆分为数字列表
if version_nums[0] <= 3 and version_nums[1] <= 9 and version_nums[2] <= 2:
return 4
else:
return 8
def find_all(self, c: bytes, string: bytes, base_addr=0):
"""
查找字符串中所有子串的位置
@ -92,14 +101,15 @@ class BiasAddr:
return result
def search_key(self, key: bytes):
byteLen = 4 if self.bits == 32 else 8 # 4字节或8字节
byteLen = self.address_len # if self.bits == 32 else 8 # 4字节或8字节
key = re.escape(key) # 转义特殊字符
key_addr = self.pm.pattern_scan_all(key, return_multiple=True)[-1] if len(key) > 0 else 0
key = key_addr.to_bytes(byteLen, byteorder='little', signed=True)
result = self.search_memory_value(key, self.module_name)
return result
def get_key_bias_test(self):
byteLen = 4 if self.bits == 32 else 8 # 4字节或8字节
byteLen = self.address_len # 4 if self.bits == 32 else 8 # 4字节或8字节
keyLenOffset = 0x8c if self.bits == 32 else 0xd0
keyWindllOffset = 0x90 if self.bits == 32 else 0xd8
@ -129,7 +139,7 @@ class BiasAddr:
return keyWinAddr - module.lpBaseOfDll
def get_wxid_bias(self):
byteLen = 4 if self.bits == 32 else 8 # 4字节或8字节
byteLen = self.address_len # 4 if self.bits == 32 else 8 # 4字节或8字节
keyLenOffset = 0x8c if self.bits == 32 else 0xd0
keyWindllOffset = 0x90 if self.bits == 32 else 0xd8
@ -178,8 +188,8 @@ class BiasAddr:
def get_maybe_key(mem_data):
maybe_key = []
for i in range(0, len(mem_data), 8):
addr = mem_data[i:i + 8]
for i in range(0, len(mem_data), self.address_len):
addr = mem_data[i:i + self.address_len]
addr = int.from_bytes(addr, byteorder='little')
# 去掉不可能的地址
if min_addr < addr < max_addr:
@ -226,7 +236,7 @@ class BiasAddr:
maybe_key = []
for i in [0x24, 0x40]:
addr = start_addr + account_bias - i
mem_data = pm.read_bytes(addr, 8)
mem_data = pm.read_bytes(addr, self.address_len)
key = read_key(int.from_bytes(mem_data, byteorder='little'))
if key != b"":
maybe_key.append([key, addr - start_addr])
@ -256,15 +266,16 @@ class BiasAddr:
account_bias = self.search_memory_value(self.account)
# version_bias = self.search_memory_value(self.version.encode("utf-8"))
try:
key_bias = self.get_key_bias_test()
except:
key_bias = 0
try:
wxid_bias = self.get_wxid_bias()
except:
wxid_bias = 0
try:
key_bias = self.get_key_bias_test()
except:
key_bias = 0
if key_bias <= 0:
if self.key:
key_bias = self.search_key(self.key)
@ -281,8 +292,8 @@ if __name__ == '__main__':
parser.add_argument("--mobile", type=str, help="手机号", required=True)
parser.add_argument("--name", type=str, help="微信昵称", required=True)
parser.add_argument("--account", type=str, help="微信账号", required=True)
parser.add_argument("--key", type=str, help="密钥")
parser.add_argument("--db_path", type=str, help="微信文件夹(已经登录微信)路径")
parser.add_argument("--key", type=str, help="(可选)密钥")
parser.add_argument("--db_path", type=str, help="(可选)已登录账号的微信文件夹路径")
# 解析命令行参数
args = parser.parse_args()
@ -290,8 +301,7 @@ if __name__ == '__main__':
# 检查是否缺少必要参数,并抛出错误
if not args.mobile or not args.name or not args.account:
raise ValueError("缺少必要的命令行参数!请提供手机号、微信昵称、微信账号。")
if not args.key and not args.db_path:
raise ValueError("缺少必要的命令行参数!请提供密钥或微信文件夹(已经登录微信)路径。")
# 从命令行参数获取值
mobile = args.mobile
name = args.name
@ -301,6 +311,7 @@ if __name__ == '__main__':
# 调用 run 函数,并传入参数
rdata = BiasAddr(account, mobile, name, key, db_path).run()
print("{版本:昵称,账号,手机号,邮箱,KEY,原始ID(wxid_******)}")
print(rdata)
# 添加到version_list.json

View File

@ -22,8 +22,8 @@ class MainBiasAddr():
sb_bias_addr.add_argument("--mobile", type=str, help="手机号", required=True)
sb_bias_addr.add_argument("--name", type=str, help="微信昵称", required=True)
sb_bias_addr.add_argument("--account", type=str, help="微信账号", required=True)
sb_bias_addr.add_argument("--key", type=str, help="(与db_path二选一)密钥")
sb_bias_addr.add_argument("--db_path", type=str, help="(与key二选一)已登录账号的微信文件夹路径")
sb_bias_addr.add_argument("--key", type=str, help="(可选)密钥")
sb_bias_addr.add_argument("--db_path", type=str, help="(可选)已登录账号的微信文件夹路径")
sb_bias_addr.add_argument("-vlp", type=str, help="(可选)微信版本偏移文件路径,如有,则自动更新",
default=None)
self.sb_bias_addr = sb_bias_addr
@ -43,6 +43,7 @@ class MainBiasAddr():
vlp = args.vlp
# 调用 run 函数,并传入参数
rdata = BiasAddr(account, mobile, name, key, db_path).run()
print("{版本:微信昵称,微信账号,微信手机号,微信邮箱,微信KEY,微信原始ID(wxid_******)}")
print(rdata)
if vlp is not None:

View File

@ -309,7 +309,7 @@
50320640,
38986104,
50321676,
0
50592864
],
"3.9.2.26": [
50329040,
@ -372,7 +372,7 @@
63488320,
63486792,
0,
63488256,
0,
63488352
]
}

View File

@ -5,6 +5,7 @@
# Author: xaoyaoo
# Date: 2023/08/21
# -------------------------------------------------------------------------------
import argparse
import json
import ctypes
from win32com.client import Dispatch
@ -23,18 +24,19 @@ def get_info_without_key(h_process, address, n_size=64):
return text.strip() if text.strip() != "" else "None"
def get_info_wxid(h_process, address, n_size=32):
array = ctypes.create_string_buffer(8)
if ReadProcessMemory(h_process, void_p(address), array, 8, 0) == 0: return "None"
def get_info_wxid(h_process, address, n_size=32, address_len=8):
array = ctypes.create_string_buffer(address_len)
if ReadProcessMemory(h_process, void_p(address), array, address_len, 0) == 0: return "None"
address = int.from_bytes(array, byteorder='little') # 逆序转换为int地址key地址
wxid = get_info_without_key(h_process, address, n_size)
if not wxid.startswith("wxid_"): wxid = "None"
return wxid
# 读取内存中的key
def get_key(h_process, address):
array = ctypes.create_string_buffer(8)
if ReadProcessMemory(h_process, void_p(address), array, 8, 0) == 0: return "None"
def get_key(h_process, address, address_len=8):
array = ctypes.create_string_buffer(address_len)
if ReadProcessMemory(h_process, void_p(address), array, address_len, 0) == 0: return "None"
address = int.from_bytes(array, byteorder='little') # 逆序转换为int地址key地址
key = ctypes.create_string_buffer(32)
if ReadProcessMemory(h_process, void_p(address), key, 32, 0) == 0: return "None"
@ -60,8 +62,8 @@ def read_info(version_list):
tmp_rd['pid'] = process.pid
tmp_rd['version'] = Dispatch("Scripting.FileSystemObject").GetFileVersion(process.exe())
support_list = version_list.get(tmp_rd['version'], None)
if not isinstance(support_list, list):
bias_list = version_list.get(tmp_rd['version'], None)
if not isinstance(bias_list, list):
return f"[-] WeChat Current Version {tmp_rd['version']} Is Not Supported"
wechat_base_address = 0
@ -74,29 +76,48 @@ def read_info(version_list):
Handle = ctypes.windll.kernel32.OpenProcess(0x1F0FFF, False, process.pid)
name_baseaddr = wechat_base_address + support_list[0]
account__baseaddr = wechat_base_address + support_list[1]
mobile_baseaddr = wechat_base_address + support_list[2]
mail_baseaddr = wechat_base_address + support_list[3]
key_baseaddr = wechat_base_address + support_list[4]
wxid_baseaddr = wechat_base_address + support_list[5]
name_baseaddr = wechat_base_address + bias_list[0]
account__baseaddr = wechat_base_address + bias_list[1]
mobile_baseaddr = wechat_base_address + bias_list[2]
mail_baseaddr = wechat_base_address + bias_list[3]
key_baseaddr = wechat_base_address + bias_list[4]
wxid_baseaddr = wechat_base_address + bias_list[5]
tmp_rd['account'] = get_info_without_key(Handle, account__baseaddr, 32)
tmp_rd['mobile'] = get_info_without_key(Handle, mobile_baseaddr, 64)
tmp_rd['name'] = get_info_without_key(Handle, name_baseaddr, 64)
tmp_rd['mail'] = get_info_without_key(Handle, mail_baseaddr, 64) if support_list[3] != 0 else "None"
tmp_rd['wxid'] = get_info_wxid(Handle, wxid_baseaddr, 24) if support_list[5] != 0 else "None"
if not tmp_rd['wxid'].startswith("wxid_"): tmp_rd['wxid'] = "None"
tmp_rd['key'] = get_key(Handle, key_baseaddr)
addrLen = 4 if tmp_rd['version'] in ["3.9.2.23", "3.9.2.26"] else 8
tmp_rd['account'] = get_info_without_key(Handle, account__baseaddr, 32) if bias_list[1] != 0 else "None"
tmp_rd['mobile'] = get_info_without_key(Handle, mobile_baseaddr, 64) if bias_list[2] != 0 else "None"
tmp_rd['name'] = get_info_without_key(Handle, name_baseaddr, 64) if bias_list[0] != 0 else "None"
tmp_rd['mail'] = get_info_without_key(Handle, mail_baseaddr, 64) if bias_list[3] != 0 else "None"
tmp_rd['wxid'] = get_info_wxid(Handle, wxid_baseaddr, 24, addrLen) if bias_list[5] != 0 else "None"
tmp_rd['key'] = get_key(Handle, key_baseaddr, addrLen) if bias_list[4] != 0 else "None"
result.append(tmp_rd)
return result
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--vlfile", type=str, help="手机号", required=False)
parser.add_argument("--vldict", type=str, help="微信昵称", required=False)
args = parser.parse_args()
# 读取微信各版本偏移
version_list = json.load(open("../version_list.json", "r", encoding="utf-8"))
result = read_info(version_list) # 读取微信信息
if args.vlfile:
VERSION_LIST_PATH = args.vlfile
with open(VERSION_LIST_PATH, "r", encoding="utf-8") as f:
VERSION_LIST = json.load(f)
if args.vldict:
VERSION_LIST = json.loads(args.vldict)
if not args.vlfile and not args.vldict:
VERSION_LIST_PATH = "../version_list.json"
with open(VERSION_LIST_PATH, "r", encoding="utf-8") as f:
VERSION_LIST = json.load(f)
result = read_info(VERSION_LIST) # 读取微信信息
print("=" * 32)
if isinstance(result, str): # 输出报错

View File

@ -3,7 +3,7 @@ from setuptools import setup, find_packages
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
version = "2.1.7"
version = "2.1.9"
setup(
name="pywxdump",
author="xaoyaoo",