PyWxDump/pywxdump/wx_info/get_wx_info.py

167 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-#
# -------------------------------------------------------------------------------
# Name: getwxinfo.py
# Description:
# Author: xaoyaoo
# Date: 2023/08/21
# -------------------------------------------------------------------------------
import json
import ctypes
import pymem
from win32com.client import Dispatch
import psutil
ReadProcessMemory = ctypes.windll.kernel32.ReadProcessMemory
void_p = ctypes.c_void_p
# 读取内存中的字符串(非key部分)
def get_info_without_key(h_process, address, n_size=64):
array = ctypes.create_string_buffer(n_size)
if ReadProcessMemory(h_process, void_p(address), array, n_size, 0) == 0: return "None"
array = bytes(array).split(b"\x00")[0] if b"\x00" in array else bytes(array)
text = array.decode('utf-8', errors='ignore')
return text.strip() if text.strip() != "" else "None"
def pattern_scan_all(handle, pattern, *, return_multiple=False):
import sys
next_region = 0
found = []
user_space_limit = 0x7FFFFFFF0000 if sys.maxsize > 2 ** 32 else 0x7fff0000
while next_region < user_space_limit:
try:
next_region, page_found = pymem.pattern.scan_pattern_page(
handle,
next_region,
pattern,
return_multiple=return_multiple
)
except Exception as e:
print(e)
break
if not return_multiple and page_found:
return page_found
if page_found:
found += page_found
if not return_multiple:
return None
return found
def get_info_wxid(h_process, n_size=64):
pm = pymem.Pymem("WeChat.exe")
# addrs = pymem.pattern.pattern_scan_all(pm.process_handle, b'wxid_', return_multiple=True)
addrs = pattern_scan_all(pm.process_handle, b'wxid_', return_multiple=True)
for addr in addrs:
wxidtmp = get_info_without_key(h_process, addr, n_size)
if wxidtmp.startswith("wxid_") and r'\FileStorage\MsgAttach' in wxidtmp:
wxid = wxidtmp.split(r'\FileStorage\MsgAttach')[0]
return wxid
return "None"
# 读取内存中的key
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"
key_string = bytes(key).hex()
return key_string
# 读取微信信息(account,mobile,name,mail,wxid,key)
def read_info(version_list, is_logging=False):
wechat_process = []
result = []
error = ""
for process in psutil.process_iter(['name', 'exe', 'pid', 'cmdline']):
if process.name() == 'WeChat.exe':
wechat_process.append(process)
if len(wechat_process) == 0:
error = "[-] WeChat No Run"
if is_logging: print(error)
return error
for process in wechat_process:
tmp_rd = {}
tmp_rd['pid'] = process.pid
tmp_rd['version'] = Dispatch("Scripting.FileSystemObject").GetFileVersion(process.exe())
bias_list = version_list.get(tmp_rd['version'], None)
if not isinstance(bias_list, list):
error = f"[-] WeChat Current Version {tmp_rd['version']} Is Not Supported"
if is_logging: print(error)
return error
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)
break
if wechat_base_address == 0:
error = f"[-] WeChat WeChatWin.dll Not Found"
if is_logging: print(error)
return error
Handle = ctypes.windll.kernel32.OpenProcess(0x1F0FFF, False, process.pid)
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]
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, 64)
tmp_rd['key'] = get_key(Handle, key_baseaddr, addrLen) if bias_list[4] != 0 else "None"
result.append(tmp_rd)
if is_logging:
print("=" * 32)
if isinstance(result, str): # 输出报错
print(result)
else: # 输出结果
for i, rlt in enumerate(result):
for k, v in rlt.items():
print(f"[+] {k:>7}: {v}")
print(end="-" * 32 + "\n" if i != len(result) - 1 else "")
print("=" * 32)
return result
if __name__ == "__main__":
import argparse
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()
# 读取微信各版本偏移
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, True) # 读取微信信息