Files
Yangmao_Script/Cash_Based/S_SKmfxs_loader.py

283 lines
9.3 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.
# cron: 22 1 * * *
# new Env("速看免费小说")
"""
本工具仅用于学习 Python 加密与逆向工程技术,供研究和教学用途。
请勿将其用于任何非法用途,包括但不限于: 加密恶意脚本 | 逃避安全审计 | 攻击他人系统 | 商业软件加壳绕过
任何使用本工具所造成的直接或间接后果,包括但不限于法律责任、安全问题、数据损失,均由使用者自行承担,作者不对此承担任何责任。
如果您不同意此免责声明,请立即停止使用并删除本文件。
Developed by Python Vorto加密系统
所需要的变量名称及格式,请运行脚本查看!
"""
import os
import sys
import hashlib
import json
import importlib.util
from pathlib import Path
from typing import Optional, Dict, Any
# 配置(请勿修改)
PROJECT_ID = "ad31d28c-ab54-4692-8471-80bb1ba04a61"
BASE_URL = "https://auth.vzvv.de"
SO_FILENAME = "S_SUKAN"
SO_DIR = "S_SOFILE"
VERSION_FILE = os.path.join(SO_DIR, ".{0}_version.json".format("S_SUKAN"))
ENTRY_FUNCTION = "main"
# 确保SO文件目录存在
if not os.path.exists(SO_DIR):
os.makedirs(SO_DIR)
def get_python_version() -> str:
return "{0}.{1}".format(sys.version_info.major, sys.version_info.minor)
def calculate_md5(file_path: str) -> str:
"""计算文件的MD5哈希值"""
md5_hash = hashlib.md5()
try:
with open(file_path, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
md5_hash.update(chunk)
return md5_hash.hexdigest()
except Exception as ex:
print("计算MD5失败: {0}".format(ex))
return ""
def load_local_version() -> Optional[Dict[str, Any]]:
"""加载本地版本信息"""
if not os.path.exists(VERSION_FILE):
return None
try:
with open(VERSION_FILE, 'r', encoding='utf-8') as f:
return json.load(f)
except Exception as ex:
print("读取本地版本信息失败: {0}".format(ex))
return None
def save_local_version(version_info: Dict[str, Any]):
"""保存本地版本信息"""
try:
with open(VERSION_FILE, 'w', encoding='utf-8') as f:
json.dump(version_info, f, indent=2, ensure_ascii=False)
except Exception as ex:
print("保存版本信息失败: {0}".format(ex))
def check_server_version() -> Optional[Dict[str, Any]]:
"""检查服务器上的活跃版本信息"""
try:
import urllib.request
import urllib.error
url = "{0}/api/version/{1}".format(BASE_URL, PROJECT_ID)
try:
with urllib.request.urlopen(url, timeout=10) as response:
data = response.read()
return json.loads(data.decode('utf-8'))
except urllib.error.HTTPError as ex:
if ex.code == 404:
print("项目不存在或没有活跃版本")
else:
print("查询版本失败 (HTTP {0}): {1}".format(ex.code, ex.reason))
return None
except urllib.error.URLError as ex:
print("网络连接失败: {0}".format(ex.reason))
return None
except ImportError:
print("urllib模块不可用无法检查更新")
return None
except Exception as ex:
print("检查服务器版本失败: {0}".format(ex))
return None
def fetch_changelog(version_id: str) -> Optional[str]:
"""获取指定版本的更新描述"""
try:
import urllib.request
import urllib.error
url = "{0}/api/changelog/{1}".format(BASE_URL, PROJECT_ID)
try:
with urllib.request.urlopen(url, timeout=10) as response:
data = response.read()
changelog_data = json.loads(data.decode('utf-8'))
# 查找匹配版本的描述
for item in changelog_data.get('changelog', []):
if item.get('version_id') == version_id:
return item.get('description', '')
return None
except Exception:
return None
except Exception:
return None
def print_update_info(version_info: Dict[str, Any]):
"""打印更新信息"""
print("=" * 50)
print("【更新日志】版本 {0}".format(version_info['version_number']))
print("-" * 50)
# 尝试获取版本描述
desc = fetch_changelog(version_info['version_id'])
if desc:
print(desc)
else:
print("(无更新说明)")
print("-" * 50)
print("查看更多更新日志: {0}/changelog/{1}".format(BASE_URL, PROJECT_ID))
print("=" * 50)
def download_so_file(version_info: Dict[str, Any]) -> bool:
"""下载SO文件"""
try:
import urllib.request
python_ver = get_python_version()
version_id = version_info['version_id']
# 构建下载URL
url = "{0}/api/download/{1}/{2}/{3}".format(BASE_URL, PROJECT_ID, version_id, python_ver)
# 确定SO文件名包含Python版本保存到SO_DIR目录
so_file = os.path.join(SO_DIR, "{0}_{1}.so".format(SO_FILENAME, python_ver.replace('.', '')))
print("正在下载版本 {0}...".format(version_info['version_number']))
# 下载文件
urllib.request.urlretrieve(url, so_file)
# 验证文件完整性使用对应Python版本的MD5
md5_hashes = version_info.get('md5_hashes', {})
expected_md5 = md5_hashes.get(python_ver)
if expected_md5:
local_md5 = calculate_md5(so_file)
if local_md5 != expected_md5:
print("警告: 文件MD5校验失败")
print(" 期望: {0}".format(expected_md5))
print(" 实际: {0}".format(local_md5))
os.remove(so_file)
return False
print("MD5校验通过")
# 保存版本信息
save_local_version(version_info)
print("下载完成: {0}".format(so_file))
# 显示更新日志
print_update_info(version_info)
return True
except Exception as ex:
print("下载SO文件失败: {0}".format(ex))
return False
def need_update(local_version: Optional[Dict[str, Any]], server_version: Optional[Dict[str, Any]]) -> bool:
"""判断是否需要更新"""
if server_version is None:
# 服务器没有活跃版本
return False
if local_version is None:
# 本地没有版本信息
return True
# 比较version_id
if local_version.get('version_id') != server_version.get('version_id'):
return True
# 检查SO文件是否存在
python_ver = get_python_version()
so_file = os.path.join(SO_DIR, "{0}_{1}.so".format(SO_FILENAME, python_ver.replace('.', '')))
if not os.path.exists(so_file):
return True
return False
def load_so_module():
"""加载SO模块"""
python_ver = get_python_version()
so_file = os.path.join(SO_DIR, "{0}_{1}.so".format(SO_FILENAME, python_ver.replace('.', '')))
# 检查本地版本
local_version = load_local_version()
# 检查服务器版本
server_version = check_server_version()
# 判断是否需要更新
if need_update(local_version, server_version):
if server_version:
print("发现新版本: {0}".format(server_version['version_number']))
if not download_so_file(server_version):
if not os.path.exists(so_file):
raise RuntimeError("SO文件不存在且下载失败: {0}".format(so_file))
print("下载失败,使用本地版本")
else:
if not os.path.exists(so_file):
raise RuntimeError("SO文件不存在或暂无可用版本: {0}".format(so_file))
else:
if local_version:
print("使用本地版本: {0}".format(local_version['version_number']))
# 检查SO文件是否存在
if not os.path.exists(so_file):
raise RuntimeError("SO文件不存在: {0}".format(so_file))
# 加载SO模块
try:
spec = importlib.util.spec_from_file_location("encrypted_module", so_file)
if spec is None or spec.loader is None:
raise RuntimeError("无法加载SO模块: {0}".format(so_file))
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
except Exception as ex:
raise RuntimeError("加载SO模块失败: {0}".format(ex))
# 自动加载模块并执行
try:
_module = load_so_module()
# 导出入口函数
if hasattr(_module, ENTRY_FUNCTION):
entry_func = getattr(_module, ENTRY_FUNCTION)
globals()[ENTRY_FUNCTION] = entry_func
# 如果作为主程序运行,自动执行入口函数
if __name__ == "__main__":
result = entry_func()
if result is not None:
print("返回值:", result)
else:
print("警告: SO模块中未找到入口函数 '{0}'".format(ENTRY_FUNCTION))
# 导出模块本身,允许用户手动访问
encrypted_module = _module
except Exception as ex:
print("加载器初始化失败: {0}".format(ex))
raise