Files
tvbox_collect/jaychouqq/yingshi/py8/box.py
T
2026-06-29 03:41:14 +00:00

101 lines
3.6 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.
#!/usr/bin/env python3
import sys
import binascii
import re
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
def pad_end(key):
"""将密钥或IV填充至16字节"""
return (key + "0000000000000000")[:16]
def decrypt_cbc(data_hex):
"""模拟 FongMi Decoder.java 的 cbc 解密逻辑"""
try:
# 1. 将十六进制转换为字节并尝试解码为字符串以提取元数据
full_bytes = binascii.unhexlify(data_hex)
# 使用 latin-1 避免 utf-8 解码失败,因为密文部分不是合法的 utf-8
decode_str = full_bytes.decode('latin-1').lower()
# 2. 提取 Key (位于 $# 和 #$ 之间)
try:
start_idx = decode_str.index("$#") + 2
end_idx = decode_str.index("#$")
key_raw = decode_str[start_idx:end_idx]
key = pad_end(key_raw).encode('utf-8')
except ValueError:
return "错误: 未能在数据中找到 AES 密钥标记 ($#...#$)"
# 3. 提取 IV (最后 13 个字符)
iv_raw = decode_str[-13:]
iv = pad_end(iv_raw).encode('utf-8')
# 4. 提取加密主体 (位于 2324 [#$的hex] 之后,倒数第 26 个字符之前)
try:
# 在原始 hex 串中查找 #$ (2324)
content_start = data_hex.index("2324") + 4
content_end = len(data_hex) - 26
encrypted_hex = data_hex[content_start:content_end]
encrypted_bytes = binascii.unhexlify(encrypted_hex)
except ValueError:
return "错误: 未能在十六进制数据中定位密文标记 (2324)"
# 5. 执行 AES 解密
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted_bytes = unpad(cipher.decrypt(encrypted_bytes), AES.block_size)
return decrypted_bytes.decode('utf-8')
except Exception as e:
return f"AES 解密失败: {str(e)}"
def decrypt_base64(data):
"""模拟 FongMi Decoder.java 的 base64 解密逻辑"""
try:
# 正则匹配: 8位字母数字 + **
match = re.search(r'[A-Za-z0-9]{8}\*\*', data)
if match:
# 提取匹配项后 10 个字符之后的内容
start_pos = data.index(match.group()) + 10
base64_content = data[start_pos:]
return base64.b64decode(base64_content).decode('utf-8')
return "错误: 未能在数据中找到 Base64 标记 (8位字符+**)"
except Exception as e:
return f"Base64 解密失败: {str(e)}"
def main():
if len(sys.argv) < 2:
print("用法: python3 tvbox_decryptor.py <文件名>")
sys.exit(1)
file_path = sys.argv[1]
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read().strip()
except Exception as e:
print(f"读取文件失败: {e}")
sys.exit(1)
# 识别加密类型
if content.startswith("2423"):
print("[*] 识别为 AES/CBC 加密格式 (2423开头)")
# 移除所有空白字符(模拟 Java 的 replaceAll("\\s+", "")
cleaned_content = re.sub(r'\s+', '', content)
result = decrypt_cbc(cleaned_content)
elif "**" in content:
print("[*] 识别为 Base64 加密格式 (**标记)")
result = decrypt_base64(content)
elif content.startswith("{") or content.startswith("["):
print("[*] 数据似乎未加密")
result = content
else:
print("[!] 未知的数据格式,尝试直接输出前 100 字符:")
print(content[:100])
sys.exit(1)
print("\n--- 解密结果 ---")
print(result)
print("----------------")
if __name__ == "__main__":
main()