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 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# 读取内存中的keydef 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): wechat_process = [] result = [] for process in psutil.process_iter(['name', 'exe', 'pid', 'cmdline']): if process.name() == 'WeChat.exe': wechat_process.append(process) if len(wechat_process) == 0: return "[-] WeChat No Run" 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): 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) break if wechat_base_address == 0: return f"[-] WeChat WeChatWin.dll Not Found" Handle = ctypes.windll.kernel32.OpenProcess(0x1F0FFF, False, process.pid) account__baseaddr = wechat_base_address + bias_list[1] tmp_rd['account'] = get_info_without_key(Handle, account__baseaddr, 32) if bias_list[1] != 0 else "None" result.append(tmp_rd) return result
def decrypt(key: str, db_path, out_path): if not os.path.exists(db_path): return f"[-] db_path:'{db_path}' File not found!" if not os.path.exists(os.path.dirname(out_path)): return f"[-] out_path:'{out_path}' File not found!" if len(key) != 64: return f"[-] key:'{key}' Error!" password = bytes.fromhex(key.strip()) with open(db_path, "rb") as file: blist = file.read() salt = blist[:16] byteKey = hashlib.pbkdf2_hmac("sha1", password, salt, DEFAULT_ITER, KEY_SIZE) first = blist[16:DEFAULT_PAGESIZE] mac_salt = bytes([(salt[i] ^ 58) for i in range(16)]) mac_key = hashlib.pbkdf2_hmac("sha1", byteKey, mac_salt, 2, KEY_SIZE) hash_mac = hmac.new(mac_key, first[:-32], hashlib.sha1) hash_mac.update(b'\x01\x00\x00\x00') if hash_mac.digest() != first[-32:-12]: return f"[-] Password Error! (key:'{key}'; db_path:'{db_path}'; out_path:'{out_path}' )" newblist = [blist[i:i + DEFAULT_PAGESIZE] for i in range(DEFAULT_PAGESIZE, len(blist), DEFAULT_PAGESIZE)] with open(out_path, "wb") as deFile: deFile.write(SQLITE_FILE_HEADER.encode()) t = AES.new(byteKey, AES.MODE_CBC, first[-48:-32]) decrypted = t.decrypt(first[:-48]) deFile.write(decrypted) deFile.write(first[-48:]) for i in newblist: t = AES.new(byteKey, AES.MODE_CBC, i[-48:-32]) decrypted = t.decrypt(i[:-48]) deFile.write(decrypted) deFile.write(i[-48:]) return [True, db_path, out_path, key]def batch_decrypt(key: str, db_path: Union[str, List[str]], out_path: str): if not isinstance(key, str) or not isinstance(out_path, str) or not os.path.exists(out_path) or len(key) != 64: return f"[-] (key:'{key}' or out_path:'{out_path}') Error!" process_list = [] if isinstance(db_path, str): if not os.path.exists(db_path): return f"[-] db_path:'{db_path}' not found!" if os.path.isfile(db_path): inpath = db_path outpath = os.path.join(out_path, 'de_' + os.path.basename(db_path)) process_list.append([key, inpath, outpath]) elif os.path.isdir(db_path): for root, dirs, files in os.walk(db_path): for file in files: inpath = os.path.join(root, file) rel = os.path.relpath(root, db_path) outpath = os.path.join(out_path, rel, 'de_' + file) if not os.path.exists(os.path.dirname(outpath)): os.makedirs(os.path.dirname(outpath)) process_list.append([key, inpath, outpath]) else: return f"[-] db_path:'{db_path}' Error " elif isinstance(db_path, list): rt_path = os.path.commonprefix(db_path) if not os.path.exists(rt_path): rt_path = os.path.dirname(rt_path) for inpath in db_path: if not os.path.exists(inpath): return f"[-] db_path:'{db_path}' not found!" inpath = os.path.normpath(inpath) rel = os.path.relpath(os.path.dirname(inpath), rt_path) outpath = os.path.join(out_path, rel, 'de_' + os.path.basename(inpath)) if not os.path.exists(os.path.dirname(outpath)): os.makedirs(os.path.dirname(outpath)) process_list.append([key, inpath, outpath]) else: return f"[-] db_path:'{db_path}' Error " result = [] for i in process_list: result.append(decrypt(*i)) # 解密 # 删除空文件夹 for root, dirs, files in os.walk(out_path, topdown=False): for dir in dirs: if not os.listdir(os.path.join(root, dir)): os.rmdir(os.path.join(root, dir)) return result
Telegram
Telegram session劫持探索 - 出海跨境王007出海
GitHub - ntqbit/tdesktop-decrypter: Telegram Desktop tdata folder decrypter written in python