From ba4500867fbdad4e87b019a4a18e7ed55d969ee9 Mon Sep 17 00:00:00 2001 From: xaoyo Date: Wed, 11 Oct 2023 14:16:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Program/get_base_addr.py | 66 +++++++++++++++++++-------------------- Program/get_wx_info.py | 24 +++++--------- Program/version_list.json | 3 +- README.md | 6 ++-- 4 files changed, 46 insertions(+), 53 deletions(-) diff --git a/Program/get_base_addr.py b/Program/get_base_addr.py index bdc895c..ee1b848 100644 --- a/Program/get_base_addr.py +++ b/Program/get_base_addr.py @@ -17,7 +17,8 @@ import winreg import threading import psutil -import win32api +# import win32api +from win32com.client import Dispatch from pymem import Pymem import pymem import hmac @@ -66,12 +67,9 @@ class BaseAddr: return [base_addr + m.start() for m in re.finditer(re.escape(c), string)] def get_file_version(self, process_name): - for process in psutil.process_iter(['name', 'exe', 'pid', 'cmdline']): + for process in psutil.process_iter(['pid', 'name', 'exe']): if process.name() == process_name: - file_path = process.exe() - info = win32api.GetFileVersionInfo(file_path, "\\") - ms, ls = info['FileVersionMS'], info['FileVersionLS'] - file_version = f"{win32api.HIWORD(ms)}.{win32api.LOWORD(ms)}.{win32api.HIWORD(ls)}.{win32api.LOWORD(ls)}" + file_version = Dispatch("Scripting.FileSystemObject").GetFileVersion(process.exe()) return file_version self.islogin = False @@ -125,18 +123,6 @@ class BaseAddr: if not os.path.exists(wx_db_path): return False - def read_key(addr): - key = ctypes.create_string_buffer(35) - if ReadProcessMemory(pm.process_handle, void_p(addr - 1), key, 35, 0) == 0: - return b"" - - if b"\x00\x00" in key.raw[1:33]: - return b"" - - if b"\x00\x00" == key.raw[33:35] and b"\x90" == key.raw[0:1]: - return key.raw[1:33] - return b"" - def get_maybe_key(mem_data): maybe_key = [] for i in range(0, len(mem_data), 8): @@ -150,6 +136,18 @@ class BaseAddr: maybe_key.append([key, i]) return maybe_key + def read_key(addr): + key = ctypes.create_string_buffer(35) + if ReadProcessMemory(pm.process_handle, void_p(addr - 1), key, 35, 0) == 0: + return b"" + + if b"\x00\x00" in key.raw[1:33]: + return b"" + + if b"\x00\x00" == key.raw[33:35] and b"\x90" == key.raw[0:1]: + return key.raw[1:33] + return b"" + def verify_key(keys, wx_db_path): with open(wx_db_path, "rb") as file: blist = file.read(5000) @@ -171,14 +169,6 @@ class BaseAddr: start_addr = module.lpBaseOfDll size = module.SizeOfImage - min_addr = 0xffffffffffffffffffffffff - max_addr = 0 - for module1 in pm.list_modules(): - if module1.lpBaseOfDll < min_addr: - min_addr = module1.lpBaseOfDll - if module1.lpBaseOfDll > max_addr: - max_addr = module1.lpBaseOfDll - if account_bias > 1: maybe_key = [] for i in [0x24, 0x40]: @@ -187,9 +177,20 @@ class BaseAddr: key = read_key(int.from_bytes(mem_data, byteorder='little')) if key != b"": maybe_key.append([key, addr - start_addr]) - else: - mem_data = pm.read_bytes(start_addr, size) - maybe_key = get_maybe_key(mem_data) + key, bais = verify_key(maybe_key, wx_db_path) + if bais != 0: + return bais + + min_addr = 0xffffffffffffffffffffffff + max_addr = 0 + for module1 in pm.list_modules(): + if module1.lpBaseOfDll < min_addr: + min_addr = module1.lpBaseOfDll + if module1.lpBaseOfDll > max_addr: + max_addr = module1.lpBaseOfDll + module1.SizeOfImage + + mem_data = pm.read_bytes(start_addr, size) + maybe_key = get_maybe_key(mem_data) key, bais = verify_key(maybe_key, wx_db_path) return bais @@ -200,13 +201,14 @@ class BaseAddr: mobile_bias = self.search_memory_value(self.mobile) name_bias = self.search_memory_value(self.name) account_bias = self.search_memory_value(self.account) + version_bias = self.search_memory_value(self.version.encode("utf-8")) if self.key: key_bias = self.search_key(self.key) elif self.db_path: key_bias = self.get_key_bias(self.db_path, account_bias) else: key_bias = 0 - return {self.version: [name_bias, account_bias, mobile_bias, 0, key_bias]} + return {self.version: [name_bias, account_bias, mobile_bias, 0, key_bias, version_bias]} if __name__ == '__main__': @@ -230,13 +232,11 @@ if __name__ == '__main__': mobile = args.mobile name = args.name account = args.account - key = args.key + key = None # args.key db_path = args.db_path - st = time.time() # 调用 run 函数,并传入参数 rdata = BaseAddr(account, mobile, name, key, db_path).run() - print(f"耗时:{time.time() - st}") print(rdata) # 添加到version_list.json diff --git a/Program/get_wx_info.py b/Program/get_wx_info.py index 26bc6f7..2553876 100644 --- a/Program/get_wx_info.py +++ b/Program/get_wx_info.py @@ -5,10 +5,9 @@ # Author: xaoyaoo # Date: 2023/08/21 # ------------------------------------------------------------------------------- -import binascii import json import ctypes -import win32api +from win32com.client import Dispatch import psutil ReadProcessMemory = ctypes.windll.kernel32.ReadProcessMemory @@ -30,19 +29,12 @@ def get_key(h_process, address): if ReadProcessMemory(h_process, void_p(address), array, 8, 0) == 0: return "None" key = ctypes.create_string_buffer(32) address = int.from_bytes(array, byteorder='little') # 逆序转换为int地址(key地址) + print(hex(address)) if ReadProcessMemory(h_process, void_p(address), key, 32, 0) == 0: return "None" key_string = bytes(key).hex() return key_string -# 读取文件版本 -def get_file_version(file_path): - info = win32api.GetFileVersionInfo(file_path, "\\") - ms, ls = info['FileVersionMS'], info['FileVersionLS'] - file_version = f"{win32api.HIWORD(ms)}.{win32api.LOWORD(ms)}.{win32api.HIWORD(ls)}.{win32api.LOWORD(ls)}" - return file_version - - # 读取微信信息(key, name, account, mobile, mail) def read_info(version_list): wechat_process = [] @@ -57,21 +49,21 @@ def read_info(version_list): for process in wechat_process: tmp_rd = {} - support_list = None 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): + return f"[-] WeChat Current Version {tmp_rd['version']} Is Not Supported" + wechat_base_address = 0 for module in process.memory_maps(grouped=False): if module.path and 'WeChatWin.dll' in module.path: wechat_base_address = int(module.addr, 16) - tmp_rd['version'] = get_file_version(module.path) - support_list = version_list.get(tmp_rd['version'], None) break - if wechat_base_address == 0: return f"[-] WeChat WeChatWin.dll Not Found" - if not isinstance(support_list, list): - return f"[-] WeChat Current Version {tmp_rd['version']} Is Not Supported" Handle = ctypes.windll.kernel32.OpenProcess(0x1F0FFF, False, process.pid) diff --git a/Program/version_list.json b/Program/version_list.json index 9464729..195ced8 100644 --- a/Program/version_list.json +++ b/Program/version_list.json @@ -319,6 +319,7 @@ 63488320, 63486792, 0, - 63488256 + 63488256, + 56006136 ] } \ No newline at end of file diff --git a/README.md b/README.md index 8590642..9fafaa7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ * 更新日志(发现[version_list.json](./Program/version_list.json) 缺失或错误,请提交[issues](https://github.com/xaoyaoo/PyWxDump/issues)): - * 2023.10.11 添加"3.9.5.81"版本的偏移地址 感谢@**[sv3nbeast](https://github.com/sv3nbeast)** + * 2023.10.11 添加"3.9.5.81"版本的偏移地址[#10](https://github.com/xaoyaoo/PyWxDump/issues/10), 感谢@**[sv3nbeast](https://github.com/sv3nbeast)** * 2023.10.09 获取key基址偏移可以根据微信文件夹获取,不需要输入key * 2023.10.09 优化代码,删减没必要代码,重新修改获取基址代码,加快运行速度(需要安装新的库 pymem) * 2023.10.07 修改获取基址内存搜索方式,防止进入死循环 @@ -133,9 +133,9 @@ python get_base_addr.py --mobile 152***** --name **** --account *** --key ***** db_path = "****\WeChat Files\wxid_******" # 微信文件夹,通过微信客户端,设置-文件管理-微信文件的默认保存位置获取 -return:{'3.9.7.29': [63486984, 63488320, 63486792, 0, 63488256]} +return:{'3.9.7.29': [63486984, 63488320, 63486792, 0, 63488256, 56006136]} - (十进制)按顺序代表:微信昵称、微信账号、微信手机号、微信邮箱(默认0)、微信KEY + (十进制)按顺序代表:微信昵称、微信账号、微信手机号、微信邮箱(默认0)、微信KEY、版本信息 [注]:如果参数错误,得到的对应地址偏移为0,邮箱高版本失效,默认为0