修复3.9.2.*版本无法正常运行
This commit is contained in:
parent
71f10d4561
commit
fbc4086e07
@ -57,9 +57,18 @@ class BiasAddr:
|
|||||||
self.pm = Pymem("WeChat.exe")
|
self.pm = Pymem("WeChat.exe")
|
||||||
|
|
||||||
self.bits = self.get_osbits()
|
self.bits = self.get_osbits()
|
||||||
|
self.version = self.get_file_version(self.process_name)
|
||||||
|
self.address_len = self.get_addr_len()
|
||||||
|
|
||||||
self.islogin = True
|
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):
|
def find_all(self, c: bytes, string: bytes, base_addr=0):
|
||||||
"""
|
"""
|
||||||
查找字符串中所有子串的位置
|
查找字符串中所有子串的位置
|
||||||
@ -92,14 +101,15 @@ class BiasAddr:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def search_key(self, key: bytes):
|
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_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)
|
key = key_addr.to_bytes(byteLen, byteorder='little', signed=True)
|
||||||
result = self.search_memory_value(key, self.module_name)
|
result = self.search_memory_value(key, self.module_name)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_key_bias_test(self):
|
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
|
keyLenOffset = 0x8c if self.bits == 32 else 0xd0
|
||||||
keyWindllOffset = 0x90 if self.bits == 32 else 0xd8
|
keyWindllOffset = 0x90 if self.bits == 32 else 0xd8
|
||||||
|
|
||||||
@ -129,7 +139,7 @@ class BiasAddr:
|
|||||||
return keyWinAddr - module.lpBaseOfDll
|
return keyWinAddr - module.lpBaseOfDll
|
||||||
|
|
||||||
def get_wxid_bias(self):
|
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
|
keyLenOffset = 0x8c if self.bits == 32 else 0xd0
|
||||||
keyWindllOffset = 0x90 if self.bits == 32 else 0xd8
|
keyWindllOffset = 0x90 if self.bits == 32 else 0xd8
|
||||||
|
|
||||||
@ -178,8 +188,8 @@ class BiasAddr:
|
|||||||
|
|
||||||
def get_maybe_key(mem_data):
|
def get_maybe_key(mem_data):
|
||||||
maybe_key = []
|
maybe_key = []
|
||||||
for i in range(0, len(mem_data), 8):
|
for i in range(0, len(mem_data), self.address_len):
|
||||||
addr = mem_data[i:i + 8]
|
addr = mem_data[i:i + self.address_len]
|
||||||
addr = int.from_bytes(addr, byteorder='little')
|
addr = int.from_bytes(addr, byteorder='little')
|
||||||
# 去掉不可能的地址
|
# 去掉不可能的地址
|
||||||
if min_addr < addr < max_addr:
|
if min_addr < addr < max_addr:
|
||||||
@ -226,7 +236,7 @@ class BiasAddr:
|
|||||||
maybe_key = []
|
maybe_key = []
|
||||||
for i in [0x24, 0x40]:
|
for i in [0x24, 0x40]:
|
||||||
addr = start_addr + account_bias - i
|
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'))
|
key = read_key(int.from_bytes(mem_data, byteorder='little'))
|
||||||
if key != b"":
|
if key != b"":
|
||||||
maybe_key.append([key, addr - start_addr])
|
maybe_key.append([key, addr - start_addr])
|
||||||
@ -256,15 +266,16 @@ class BiasAddr:
|
|||||||
account_bias = self.search_memory_value(self.account)
|
account_bias = self.search_memory_value(self.account)
|
||||||
# version_bias = self.search_memory_value(self.version.encode("utf-8"))
|
# version_bias = self.search_memory_value(self.version.encode("utf-8"))
|
||||||
|
|
||||||
try:
|
|
||||||
key_bias = self.get_key_bias_test()
|
|
||||||
except:
|
|
||||||
key_bias = 0
|
|
||||||
try:
|
try:
|
||||||
wxid_bias = self.get_wxid_bias()
|
wxid_bias = self.get_wxid_bias()
|
||||||
except:
|
except:
|
||||||
wxid_bias = 0
|
wxid_bias = 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
key_bias = self.get_key_bias_test()
|
||||||
|
except:
|
||||||
|
key_bias = 0
|
||||||
|
|
||||||
if key_bias <= 0:
|
if key_bias <= 0:
|
||||||
if self.key:
|
if self.key:
|
||||||
key_bias = self.search_key(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("--mobile", type=str, help="手机号", required=True)
|
||||||
parser.add_argument("--name", 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("--account", type=str, help="微信账号", required=True)
|
||||||
parser.add_argument("--key", type=str, help="密钥")
|
parser.add_argument("--key", type=str, help="(可选)密钥")
|
||||||
parser.add_argument("--db_path", type=str, help="微信文件夹(已经登录微信)路径")
|
parser.add_argument("--db_path", type=str, help="(可选)已登录账号的微信文件夹路径")
|
||||||
|
|
||||||
# 解析命令行参数
|
# 解析命令行参数
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
@ -290,8 +301,7 @@ if __name__ == '__main__':
|
|||||||
# 检查是否缺少必要参数,并抛出错误
|
# 检查是否缺少必要参数,并抛出错误
|
||||||
if not args.mobile or not args.name or not args.account:
|
if not args.mobile or not args.name or not args.account:
|
||||||
raise ValueError("缺少必要的命令行参数!请提供手机号、微信昵称、微信账号。")
|
raise ValueError("缺少必要的命令行参数!请提供手机号、微信昵称、微信账号。")
|
||||||
if not args.key and not args.db_path:
|
|
||||||
raise ValueError("缺少必要的命令行参数!请提供密钥或微信文件夹(已经登录微信)路径。")
|
|
||||||
# 从命令行参数获取值
|
# 从命令行参数获取值
|
||||||
mobile = args.mobile
|
mobile = args.mobile
|
||||||
name = args.name
|
name = args.name
|
||||||
@ -301,6 +311,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
# 调用 run 函数,并传入参数
|
# 调用 run 函数,并传入参数
|
||||||
rdata = BiasAddr(account, mobile, name, key, db_path).run()
|
rdata = BiasAddr(account, mobile, name, key, db_path).run()
|
||||||
|
print("{版本:昵称,账号,手机号,邮箱,KEY,原始ID(wxid_******)}")
|
||||||
print(rdata)
|
print(rdata)
|
||||||
|
|
||||||
# 添加到version_list.json
|
# 添加到version_list.json
|
||||||
|
@ -22,8 +22,8 @@ class MainBiasAddr():
|
|||||||
sb_bias_addr.add_argument("--mobile", type=str, help="手机号", required=True)
|
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("--name", type=str, help="微信昵称", required=True)
|
||||||
sb_bias_addr.add_argument("--account", 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("--key", type=str, help="(可选)密钥")
|
||||||
sb_bias_addr.add_argument("--db_path", type=str, help="(与key二选一)已登录账号的微信文件夹路径")
|
sb_bias_addr.add_argument("--db_path", type=str, help="(可选)已登录账号的微信文件夹路径")
|
||||||
sb_bias_addr.add_argument("-vlp", type=str, help="(可选)微信版本偏移文件路径,如有,则自动更新",
|
sb_bias_addr.add_argument("-vlp", type=str, help="(可选)微信版本偏移文件路径,如有,则自动更新",
|
||||||
default=None)
|
default=None)
|
||||||
self.sb_bias_addr = sb_bias_addr
|
self.sb_bias_addr = sb_bias_addr
|
||||||
@ -43,6 +43,7 @@ class MainBiasAddr():
|
|||||||
vlp = args.vlp
|
vlp = args.vlp
|
||||||
# 调用 run 函数,并传入参数
|
# 调用 run 函数,并传入参数
|
||||||
rdata = BiasAddr(account, mobile, name, key, db_path).run()
|
rdata = BiasAddr(account, mobile, name, key, db_path).run()
|
||||||
|
print("{版本:微信昵称,微信账号,微信手机号,微信邮箱,微信KEY,微信原始ID(wxid_******)}")
|
||||||
print(rdata)
|
print(rdata)
|
||||||
|
|
||||||
if vlp is not None:
|
if vlp is not None:
|
||||||
|
@ -309,7 +309,7 @@
|
|||||||
50320640,
|
50320640,
|
||||||
38986104,
|
38986104,
|
||||||
50321676,
|
50321676,
|
||||||
0
|
50592864
|
||||||
],
|
],
|
||||||
"3.9.2.26": [
|
"3.9.2.26": [
|
||||||
50329040,
|
50329040,
|
||||||
@ -372,7 +372,7 @@
|
|||||||
63488320,
|
63488320,
|
||||||
63486792,
|
63486792,
|
||||||
0,
|
0,
|
||||||
63488256,
|
0,
|
||||||
63488352
|
63488352
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -5,6 +5,7 @@
|
|||||||
# Author: xaoyaoo
|
# Author: xaoyaoo
|
||||||
# Date: 2023/08/21
|
# Date: 2023/08/21
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
|
import argparse
|
||||||
import json
|
import json
|
||||||
import ctypes
|
import ctypes
|
||||||
from win32com.client import Dispatch
|
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"
|
return text.strip() if text.strip() != "" else "None"
|
||||||
|
|
||||||
|
|
||||||
def get_info_wxid(h_process, address, n_size=32):
|
def get_info_wxid(h_process, address, n_size=32, address_len=8):
|
||||||
array = ctypes.create_string_buffer(8)
|
array = ctypes.create_string_buffer(address_len)
|
||||||
if ReadProcessMemory(h_process, void_p(address), array, 8, 0) == 0: return "None"
|
if ReadProcessMemory(h_process, void_p(address), array, address_len, 0) == 0: return "None"
|
||||||
address = int.from_bytes(array, byteorder='little') # 逆序转换为int地址(key地址)
|
address = int.from_bytes(array, byteorder='little') # 逆序转换为int地址(key地址)
|
||||||
wxid = get_info_without_key(h_process, address, n_size)
|
wxid = get_info_without_key(h_process, address, n_size)
|
||||||
|
if not wxid.startswith("wxid_"): wxid = "None"
|
||||||
return wxid
|
return wxid
|
||||||
|
|
||||||
|
|
||||||
# 读取内存中的key
|
# 读取内存中的key
|
||||||
def get_key(h_process, address):
|
def get_key(h_process, address, address_len=8):
|
||||||
array = ctypes.create_string_buffer(8)
|
array = ctypes.create_string_buffer(address_len)
|
||||||
if ReadProcessMemory(h_process, void_p(address), array, 8, 0) == 0: return "None"
|
if ReadProcessMemory(h_process, void_p(address), array, address_len, 0) == 0: return "None"
|
||||||
address = int.from_bytes(array, byteorder='little') # 逆序转换为int地址(key地址)
|
address = int.from_bytes(array, byteorder='little') # 逆序转换为int地址(key地址)
|
||||||
key = ctypes.create_string_buffer(32)
|
key = ctypes.create_string_buffer(32)
|
||||||
if ReadProcessMemory(h_process, void_p(address), key, 32, 0) == 0: return "None"
|
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['pid'] = process.pid
|
||||||
tmp_rd['version'] = Dispatch("Scripting.FileSystemObject").GetFileVersion(process.exe())
|
tmp_rd['version'] = Dispatch("Scripting.FileSystemObject").GetFileVersion(process.exe())
|
||||||
|
|
||||||
support_list = version_list.get(tmp_rd['version'], None)
|
bias_list = version_list.get(tmp_rd['version'], None)
|
||||||
if not isinstance(support_list, list):
|
if not isinstance(bias_list, list):
|
||||||
return f"[-] WeChat Current Version {tmp_rd['version']} Is Not Supported"
|
return f"[-] WeChat Current Version {tmp_rd['version']} Is Not Supported"
|
||||||
|
|
||||||
wechat_base_address = 0
|
wechat_base_address = 0
|
||||||
@ -74,29 +76,48 @@ def read_info(version_list):
|
|||||||
|
|
||||||
Handle = ctypes.windll.kernel32.OpenProcess(0x1F0FFF, False, process.pid)
|
Handle = ctypes.windll.kernel32.OpenProcess(0x1F0FFF, False, process.pid)
|
||||||
|
|
||||||
name_baseaddr = wechat_base_address + support_list[0]
|
name_baseaddr = wechat_base_address + bias_list[0]
|
||||||
account__baseaddr = wechat_base_address + support_list[1]
|
account__baseaddr = wechat_base_address + bias_list[1]
|
||||||
mobile_baseaddr = wechat_base_address + support_list[2]
|
mobile_baseaddr = wechat_base_address + bias_list[2]
|
||||||
mail_baseaddr = wechat_base_address + support_list[3]
|
mail_baseaddr = wechat_base_address + bias_list[3]
|
||||||
key_baseaddr = wechat_base_address + support_list[4]
|
key_baseaddr = wechat_base_address + bias_list[4]
|
||||||
wxid_baseaddr = wechat_base_address + support_list[5]
|
wxid_baseaddr = wechat_base_address + bias_list[5]
|
||||||
|
|
||||||
tmp_rd['account'] = get_info_without_key(Handle, account__baseaddr, 32)
|
addrLen = 4 if tmp_rd['version'] in ["3.9.2.23", "3.9.2.26"] else 8
|
||||||
tmp_rd['mobile'] = get_info_without_key(Handle, mobile_baseaddr, 64)
|
|
||||||
tmp_rd['name'] = get_info_without_key(Handle, name_baseaddr, 64)
|
tmp_rd['account'] = get_info_without_key(Handle, account__baseaddr, 32) if bias_list[1] != 0 else "None"
|
||||||
tmp_rd['mail'] = get_info_without_key(Handle, mail_baseaddr, 64) if support_list[3] != 0 else "None"
|
tmp_rd['mobile'] = get_info_without_key(Handle, mobile_baseaddr, 64) if bias_list[2] != 0 else "None"
|
||||||
tmp_rd['wxid'] = get_info_wxid(Handle, wxid_baseaddr, 24) if support_list[5] != 0 else "None"
|
tmp_rd['name'] = get_info_without_key(Handle, name_baseaddr, 64) if bias_list[0] != 0 else "None"
|
||||||
if not tmp_rd['wxid'].startswith("wxid_"): tmp_rd['wxid'] = "None"
|
tmp_rd['mail'] = get_info_without_key(Handle, mail_baseaddr, 64) if bias_list[3] != 0 else "None"
|
||||||
tmp_rd['key'] = get_key(Handle, key_baseaddr)
|
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)
|
result.append(tmp_rd)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
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"))
|
if args.vlfile:
|
||||||
result = read_info(version_list) # 读取微信信息
|
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)
|
print("=" * 32)
|
||||||
if isinstance(result, str): # 输出报错
|
if isinstance(result, str): # 输出报错
|
||||||
|
2
setup.py
2
setup.py
@ -3,7 +3,7 @@ from setuptools import setup, find_packages
|
|||||||
with open("README.md", "r", encoding="utf-8") as fh:
|
with open("README.md", "r", encoding="utf-8") as fh:
|
||||||
long_description = fh.read()
|
long_description = fh.read()
|
||||||
|
|
||||||
version = "2.1.7"
|
version = "2.1.9"
|
||||||
setup(
|
setup(
|
||||||
name="pywxdump",
|
name="pywxdump",
|
||||||
author="xaoyaoo",
|
author="xaoyaoo",
|
||||||
|
Loading…
Reference in New Issue
Block a user