Compare commits
12
Commits
f328046500
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a854ac9bf | ||
|
|
aacec14d3e | ||
|
|
45d16cfcde | ||
|
|
697e7175e8 | ||
|
|
ef8d1e1e5d | ||
|
|
74c34aec27 | ||
|
|
4f2cdfbb1e | ||
|
|
b9f0c785d8 | ||
|
|
2625b666f6 | ||
|
|
d00677c68b | ||
|
|
e3d2a08f55 | ||
|
|
c85a91c472 |
@@ -0,0 +1,5 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.bak
|
||||
bandizip_license.txt
|
||||
.DS_Store
|
||||
@@ -1,2 +1,72 @@
|
||||
# Bandzip-Patched
|
||||
# Bandizip Professional 补丁器 & 注册机
|
||||
|
||||
> Bandizip 专业版一键补丁工具与注册码生成器。
|
||||
|
||||
[](https://www.python.org/)
|
||||
[](https://zh.wikipedia.org/wiki/Microsoft_Windows)
|
||||
[](LICENSE)
|
||||
|
||||
## 简介
|
||||
|
||||
一键修补 Bandizip 主程序,激活专业版功能。自动检测安装路径,支持备份恢复,附带注册码生成器。纯 Python 实现,零依赖。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- **自动检测** Bandizip 安装路径
|
||||
- **一键修补** — 自动备份、应用补丁、验证结果
|
||||
- **安全恢复** — 随时还原为原始文件
|
||||
- **状态检查** — 查看当前补丁状态
|
||||
- **注册机** — 根据任意邮箱生成产品密钥
|
||||
- **零依赖** — 纯 Python,无需安装第三方包
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
# 1. 应用补丁(需管理员权限)
|
||||
python bandizip_patcher.py patch
|
||||
|
||||
# 2. 生成注册码
|
||||
python bandizip_keygen.py your@email.com
|
||||
|
||||
# 3. 打开 Bandizip → 帮助 → 注册
|
||||
# 输入第 2 步生成的邮箱和注册码
|
||||
```
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 补丁器
|
||||
|
||||
```bash
|
||||
python bandizip_patcher.py # 交互模式
|
||||
python bandizip_patcher.py patch # 应用补丁
|
||||
python bandizip_patcher.py restore # 恢复原始文件
|
||||
python bandizip_patcher.py status # 查看当前状态
|
||||
```
|
||||
|
||||
如果自动检测失败,可手动指定安装路径:
|
||||
|
||||
```bash
|
||||
set BANDIZIP_DIR=C:\Program Files\Bandizip
|
||||
python bandizip_patcher.py patch
|
||||
```
|
||||
|
||||
### 注册机
|
||||
|
||||
```bash
|
||||
python bandizip_keygen.py your@email.com # 指定邮箱生成注册码
|
||||
python bandizip_keygen.py # 交互模式
|
||||
```
|
||||
|
||||
## 环境要求
|
||||
|
||||
- **Python** 3.10+
|
||||
- **Windows** 系统(修补需管理员权限)
|
||||
- 已安装 **Bandizip**
|
||||
|
||||
## 免责声明
|
||||
|
||||
本工具仅供学习交流和个人使用。建议通过购买正版许可证支持软件开发者。使用者需自行承担因使用本工具产生的任何法律责任,作者不对任何滥用行为负责。
|
||||
|
||||
## 许可证
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Bandizip Professional Keygen
|
||||
=============================
|
||||
生成 Bandizip Professional 注册码。
|
||||
|
||||
注意:需要配合 patch 后的 Bandizip.exe 使用。
|
||||
Patch 内容:
|
||||
- sub_1400D18F0 (在线验证) -> return 1
|
||||
- sub_1400CF980 (写注册表) -> return 1
|
||||
- sub_1400CF470 (读 Edition) -> return 1
|
||||
- 4x NOP (注册码格式检查)
|
||||
- 版本号默认值 0x98 -> 0x3D4 (Standard -> Professional)
|
||||
|
||||
使用方法:
|
||||
python bandizip_keygen.py
|
||||
python bandizip_keygen.py user@example.com
|
||||
"""
|
||||
|
||||
import random
|
||||
import string
|
||||
import hashlib
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
# ============ 注册码格式 ============
|
||||
# Bandizip 注册码格式: XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX
|
||||
# 每段 8 个十六进制字符,共 4 段
|
||||
# 原始验证流程已被 patch,任意格式均可通过
|
||||
|
||||
def generate_product_key(seed=None):
|
||||
"""
|
||||
生成 Bandizip 产品密钥
|
||||
格式: XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX
|
||||
"""
|
||||
if seed:
|
||||
# 使用种子生成确定性密钥
|
||||
rng = random.Random(seed)
|
||||
else:
|
||||
rng = random.Random()
|
||||
|
||||
segments = []
|
||||
for _ in range(4):
|
||||
seg = ''.join(rng.choices('0123456789ABCDEF', k=8))
|
||||
segments.append(seg)
|
||||
|
||||
return '-'.join(segments)
|
||||
|
||||
|
||||
def generate_license_data(email):
|
||||
"""
|
||||
生成完整的许可证数据
|
||||
"""
|
||||
# 基于 email 生成种子
|
||||
seed = int(hashlib.md5(email.encode()).hexdigest()[:8], 16)
|
||||
|
||||
# 生成产品密钥
|
||||
product_key = generate_product_key(seed)
|
||||
|
||||
# 生成 GUID(模拟服务器返回的)
|
||||
guid = '%08X-%04X-%04X-%04X-%012X' % (
|
||||
seed & 0xFFFFFFFF,
|
||||
(seed >> 8) & 0xFFFF,
|
||||
(seed >> 16) & 0xFFFF,
|
||||
(seed >> 24) & 0xFFFF,
|
||||
seed & 0xFFFFFFFFFFFF
|
||||
)
|
||||
|
||||
# 生成硬件 ID(模拟)
|
||||
hid = '%08X' % (seed ^ 0xDEADBEEF)
|
||||
|
||||
# 产品 ID (1000 = Professional)
|
||||
product_id = 1000
|
||||
|
||||
return {
|
||||
'email': email,
|
||||
'productKey': product_key,
|
||||
'guid': guid,
|
||||
'hid': hid,
|
||||
'productID': product_id,
|
||||
'edition': 'PRO',
|
||||
'timestamp': seed % 0x7FFFFFFF, # 稳定值,基于 email 种子
|
||||
}
|
||||
|
||||
|
||||
def format_license(data):
|
||||
"""
|
||||
格式化许可证信息
|
||||
"""
|
||||
lines = [
|
||||
'==================================================',
|
||||
' Bandizip Professional License ',
|
||||
'==================================================',
|
||||
f' Email: {data["email"]}',
|
||||
f' Product Key: {data["productKey"]}',
|
||||
f' Edition: {data["edition"]}',
|
||||
f' Product ID: {data["productID"]}',
|
||||
f' GUID: {data["guid"]}',
|
||||
f' HID: {data["hid"]}',
|
||||
'==================================================',
|
||||
]
|
||||
return '\n'.join(lines)
|
||||
|
||||
|
||||
def write_registry(data):
|
||||
"""
|
||||
写入 Windows 注册表(需要管理员权限)
|
||||
"""
|
||||
try:
|
||||
import winreg
|
||||
except ImportError:
|
||||
print(' [!] 非 Windows 系统,跳过注册表写入')
|
||||
return False
|
||||
|
||||
key_path = r'SOFTWARE\Bandizip'
|
||||
|
||||
try:
|
||||
# 写入 Edition
|
||||
with winreg.CreateKeyEx(winreg.HKEY_LOCAL_MACHINE, key_path, 0, winreg.KEY_SET_VALUE) as key:
|
||||
winreg.SetValueEx(key, 'Edition', 0, winreg.REG_SZ, data['edition'])
|
||||
|
||||
print(f' [OK] Edition = {data["edition"]}')
|
||||
return True
|
||||
except PermissionError:
|
||||
print(' [!] 需要管理员权限写入注册表')
|
||||
print(f' 请手动执行:')
|
||||
print(f' reg add "HKLM\\{key_path}" /v Edition /t REG_SZ /d "{data["edition"]}" /f')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f' [!] 注册表写入失败: {e}')
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
print('==================================================')
|
||||
print(' Bandizip Professional Keygen v1.0 ')
|
||||
print('==================================================')
|
||||
print()
|
||||
|
||||
# 获取 email
|
||||
if len(sys.argv) > 1:
|
||||
email = sys.argv[1]
|
||||
else:
|
||||
email = input('请输入邮箱地址: ').strip()
|
||||
if not email:
|
||||
email = 'user@bandizip.local'
|
||||
|
||||
print(f'\n[Email] {email}')
|
||||
print(f'[Keygen] 生成注册码...\n')
|
||||
|
||||
# 生成许可证数据
|
||||
data = generate_license_data(email)
|
||||
|
||||
# 显示许可证
|
||||
print(format_license(data))
|
||||
print()
|
||||
|
||||
# 询问是否写入注册表
|
||||
if sys.platform == 'win32':
|
||||
print('是否写入注册表? (y/n): ', end='')
|
||||
try:
|
||||
choice = input().strip().lower()
|
||||
if choice == 'y':
|
||||
write_registry(data)
|
||||
except EOFError:
|
||||
pass
|
||||
|
||||
print(f'\n[Steps] Registration:')
|
||||
print(f' 1. Open Bandizip')
|
||||
print(f' 2. Menu -> Help -> Register')
|
||||
print(f' 3. Email: {data["email"]}')
|
||||
print(f' 4. Product Key: {data["productKey"]}')
|
||||
print(f' 5. Click Register')
|
||||
print()
|
||||
|
||||
# 保存到文件
|
||||
license_file = os.path.join(os.path.dirname(__file__), 'bandizip_license.txt')
|
||||
with open(license_file, 'w', encoding='utf-8') as f:
|
||||
f.write(format_license(data) + '\n')
|
||||
f.write(f'\nEmail: {data["email"]}\n')
|
||||
f.write(f'Product Key: {data["productKey"]}\n')
|
||||
f.write(f'Edition: {data["edition"]}\n')
|
||||
f.write(f'Product ID: {data["productID"]}\n')
|
||||
f.write(f'GUID: {data["guid"]}\n')
|
||||
f.write(f'HID: {data["hid"]}\n')
|
||||
f.write(f'Timestamp: {data["timestamp"]}\n')
|
||||
|
||||
print(f' [Save] 许可证已保存到: {license_file}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,371 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Bandizip Professional Patcher
|
||||
=============================
|
||||
一键补丁器:备份、patch、验证、恢复。
|
||||
|
||||
Patch 内容(共 8 处,35 字节):
|
||||
1. sub_1400D18F0 @ 0xD0CF0 -> B0 01 C3 (mov al,1; ret) 在线验证跳过
|
||||
2. sub_1400CF980 @ 0xCED80 -> B0 01 C3 (mov al,1; ret) 写注册表跳过
|
||||
3. sub_1400CF470 @ 0xCE870 -> B0 01 C3 (mov al,1; ret) Edition 检查返回 true
|
||||
4. sub_140133648 @ 0x132A48 -> 90*6 (NOP) 注册码长度检查跳过
|
||||
5. sub_140133655 @ 0x132A55 -> 90*6 (NOP) 数据有效性检查跳过
|
||||
6. sub_14013366A @ 0x132A6A -> 90*6 (NOP) @ 符号检查跳过
|
||||
7. sub_140133678 @ 0x132A78 -> 90*6 (NOP) @ 位置检查跳过
|
||||
8. sub_14013180B @ 0x130C0B -> D4 03 00 00 版本号 Standard->Professional
|
||||
|
||||
使用方法:
|
||||
python bandizip_patcher.py # 交互模式
|
||||
python bandizip_patcher.py patch # 直接 patch
|
||||
python bandizip_patcher.py restore # 恢复原始
|
||||
python bandizip_patcher.py status # 检查状态
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import winreg
|
||||
|
||||
# ============ 配置 ============
|
||||
REG_KEY = r'SOFTWARE\Bandizip'
|
||||
REG_VALUE = 'Edition'
|
||||
REG_DATA = 'PRO'
|
||||
|
||||
|
||||
def find_bandizip_dir():
|
||||
"""自动查找 Bandizip 安装目录"""
|
||||
# 方法1: 注册表 HKLM\SOFTWARE\Bandizip\ProgramFolder
|
||||
try:
|
||||
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, REG_KEY) as key:
|
||||
path, _ = winreg.QueryValueEx(key, 'ProgramFolder')
|
||||
if path and os.path.exists(os.path.join(path, 'Bandizip.exe')):
|
||||
return path.rstrip('\\')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 方法2: 注册表卸载信息
|
||||
for subkey in [r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Bandizip',
|
||||
r'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Bandizip']:
|
||||
try:
|
||||
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, subkey) as key:
|
||||
loc, _ = winreg.QueryValueEx(key, 'InstallLocation')
|
||||
if loc and os.path.exists(os.path.join(loc, 'Bandizip.exe')):
|
||||
return loc.rstrip('\\')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 方法3: 常见安装路径
|
||||
common_paths = [
|
||||
os.path.join(os.environ.get('ProgramFiles', r'C:\Program Files'), 'Bandizip'),
|
||||
os.path.join(os.environ.get('ProgramFiles(x86)', r'C:\Program Files (x86)'), 'Bandizip'),
|
||||
os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Programs', 'Bandizip'),
|
||||
r'D:\Apps\Bandizip',
|
||||
r'D:\Program Files\Bandizip',
|
||||
]
|
||||
for p in common_paths:
|
||||
if os.path.exists(os.path.join(p, 'Bandizip.exe')):
|
||||
return p
|
||||
|
||||
return None
|
||||
|
||||
|
||||
# 启动时自动检测(可通过环境变量 BANDIZIP_DIR 手动覆盖)
|
||||
BANDIZIP_DIR = os.environ.get('BANDIZIP_DIR') or find_bandizip_dir()
|
||||
EXE_PATH = os.path.join(BANDIZIP_DIR, 'Bandizip.exe') if BANDIZIP_DIR else None
|
||||
BACKUP_PATH = (EXE_PATH + '.bak') if EXE_PATH else None
|
||||
|
||||
# Patch 定义: (文件偏移, 原始字节, 补丁字节, 描述)
|
||||
PATCHES = [
|
||||
(0xD0CF0, b'\x48\x89\x5C\x24\x08\x55', b'\xB0\x01\xC3',
|
||||
'sub_1400D18F0 (online verify -> return 1)'),
|
||||
(0xCED80, b'\x48\x89\x5C\x24\x18\x55', b'\xB0\x01\xC3',
|
||||
'sub_1400CF980 (registry write -> return 1)'),
|
||||
(0xCE870, b'\x4C\x8B\xDC\x49\x89\x5B', b'\xB0\x01\xC3',
|
||||
'sub_1400CF470 (Edition check -> return 1)'),
|
||||
(0x132A48, b'\x0F\x85\x4B\x06\x00\x00', b'\x90\x90\x90\x90\x90\x90',
|
||||
'NOP: register code length check'),
|
||||
(0x132A55, b'\x0F\x8C\x3E\x06\x00\x00', b'\x90\x90\x90\x90\x90\x90',
|
||||
'NOP: data validity check'),
|
||||
(0x132A6A, b'\x0F\x84\x29\x06\x00\x00', b'\x90\x90\x90\x90\x90\x90',
|
||||
'NOP: @ symbol check'),
|
||||
(0x132A78, b'\x0F\x8E\x1B\x06\x00\x00', b'\x90\x90\x90\x90\x90\x90',
|
||||
'NOP: @ position check'),
|
||||
(0x130C0B, b'\x98\x00\x00\x00', b'\xD4\x03\x00\x00',
|
||||
'Version: Standard(0x98) -> Professional(0x3D4)'),
|
||||
]
|
||||
|
||||
|
||||
def is_patched():
|
||||
"""检查是否已 patch"""
|
||||
if not os.path.exists(EXE_PATH):
|
||||
return False
|
||||
with open(EXE_PATH, 'rb') as f:
|
||||
for offset, orig, patch, desc in PATCHES:
|
||||
f.seek(offset)
|
||||
current = f.read(len(patch))
|
||||
if current != patch:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def is_backup_exists():
|
||||
"""检查备份是否存在"""
|
||||
return os.path.exists(BACKUP_PATH)
|
||||
|
||||
|
||||
def is_bandizip_running():
|
||||
"""检查 Bandizip 是否正在运行"""
|
||||
try:
|
||||
import subprocess
|
||||
result = subprocess.run(['tasklist', '/FI', 'IMAGENAME eq Bandizip.exe'],
|
||||
capture_output=True, text=True, timeout=5)
|
||||
return 'Bandizip.exe' in result.stdout
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def kill_bandizip():
|
||||
"""关闭 Bandizip 进程"""
|
||||
try:
|
||||
import subprocess
|
||||
subprocess.run(['taskkill', '/F', '/IM', 'Bandizip.exe'],
|
||||
capture_output=True, timeout=5)
|
||||
import time
|
||||
time.sleep(2)
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def backup():
|
||||
"""备份原始文件"""
|
||||
if is_backup_exists():
|
||||
print(' [OK] Backup already exists: ' + BACKUP_PATH)
|
||||
return True
|
||||
try:
|
||||
shutil.copy2(EXE_PATH, BACKUP_PATH)
|
||||
print(' [OK] Backup created: ' + BACKUP_PATH)
|
||||
return True
|
||||
except PermissionError:
|
||||
print(' [!] Permission denied. Run as Administrator.')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(' [!] Backup failed: ' + str(e))
|
||||
return False
|
||||
|
||||
|
||||
def apply_patches():
|
||||
"""应用所有 patch"""
|
||||
try:
|
||||
with open(EXE_PATH, 'r+b') as f:
|
||||
for offset, orig, patch, desc in PATCHES:
|
||||
f.seek(offset)
|
||||
current = f.read(len(patch))
|
||||
if current == patch:
|
||||
print(' [SKIP] Already patched: ' + desc)
|
||||
continue
|
||||
f.seek(offset)
|
||||
f.write(patch)
|
||||
print(' [OK] ' + desc)
|
||||
return True
|
||||
except PermissionError:
|
||||
print(' [!] Permission denied. Close Bandizip and run as Administrator.')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(' [!] Patch failed: ' + str(e))
|
||||
return False
|
||||
|
||||
|
||||
def restore():
|
||||
"""恢复原始文件"""
|
||||
if not is_backup_exists():
|
||||
print(' [!] No backup found: ' + BACKUP_PATH)
|
||||
return False
|
||||
try:
|
||||
shutil.copy2(BACKUP_PATH, EXE_PATH)
|
||||
print(' [OK] Restored from backup: ' + EXE_PATH)
|
||||
return True
|
||||
except PermissionError:
|
||||
print(' [!] Permission denied. Close Bandizip and run as Administrator.')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(' [!] Restore failed: ' + str(e))
|
||||
return False
|
||||
|
||||
|
||||
def set_registry():
|
||||
"""设置注册表 Edition = PRO"""
|
||||
try:
|
||||
with winreg.CreateKeyEx(winreg.HKEY_LOCAL_MACHINE, REG_KEY, 0,
|
||||
winreg.KEY_SET_VALUE) as key:
|
||||
winreg.SetValueEx(key, REG_VALUE, 0, winreg.REG_SZ, REG_DATA)
|
||||
print(' [OK] Registry: HKLM\\' + REG_KEY + '\\' + REG_VALUE + ' = ' + REG_DATA)
|
||||
return True
|
||||
except PermissionError:
|
||||
print(' [!] Registry write denied. Run as Administrator.')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(' [!] Registry write failed: ' + str(e))
|
||||
return False
|
||||
|
||||
|
||||
def check_status():
|
||||
"""检查当前状态"""
|
||||
print('=' * 50)
|
||||
print(' Bandizip Patcher - Status')
|
||||
print('=' * 50)
|
||||
|
||||
# 文件存在
|
||||
if EXE_PATH and os.path.exists(EXE_PATH):
|
||||
print(' [OK] Bandizip.exe found: ' + EXE_PATH)
|
||||
else:
|
||||
print(' [!] Bandizip.exe not found!')
|
||||
print(' [!] Tried registry, uninstall info, and common paths.')
|
||||
print(' [!] Please pass install dir manually:')
|
||||
print(' [!] set BANDIZIP_DIR=C:\\path\\to\\Bandizip')
|
||||
return
|
||||
|
||||
# 备份状态
|
||||
if is_backup_exists():
|
||||
print(' [OK] Backup exists')
|
||||
else:
|
||||
print(' [!] No backup')
|
||||
|
||||
# Patch 状态
|
||||
patched_count = 0
|
||||
total = len(PATCHES)
|
||||
if os.path.exists(EXE_PATH):
|
||||
with open(EXE_PATH, 'rb') as f:
|
||||
for offset, orig, patch, desc in PATCHES:
|
||||
f.seek(offset)
|
||||
current = f.read(len(patch))
|
||||
if current == patch:
|
||||
patched_count += 1
|
||||
status = '[PATCHED]'
|
||||
elif current == orig:
|
||||
status = '[ORIGINAL]'
|
||||
else:
|
||||
status = '[UNKNOWN]'
|
||||
print(' ' + status + ' 0x{:06X}: '.format(offset) + desc)
|
||||
|
||||
print('')
|
||||
print(' Patched: ' + str(patched_count) + '/' + str(total))
|
||||
|
||||
# 注册表状态
|
||||
try:
|
||||
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, REG_KEY) as key:
|
||||
val, _ = winreg.QueryValueEx(key, REG_VALUE)
|
||||
print(' [Registry] Edition = ' + val)
|
||||
except Exception:
|
||||
print(' [Registry] Edition not set')
|
||||
|
||||
# 进程状态
|
||||
if is_bandizip_running():
|
||||
print(' [WARNING] Bandizip is running! Close it before patching.')
|
||||
else:
|
||||
print(' [OK] Bandizip is not running')
|
||||
|
||||
print('=' * 50)
|
||||
|
||||
|
||||
def do_patch():
|
||||
"""执行完整 patch 流程"""
|
||||
print('=' * 50)
|
||||
print(' Bandizip Patcher - Apply')
|
||||
print('=' * 50)
|
||||
|
||||
if not EXE_PATH or not os.path.exists(EXE_PATH):
|
||||
print(' [!] Bandizip.exe not found!')
|
||||
return False
|
||||
|
||||
if is_bandizip_running():
|
||||
print(' [..] Bandizip is running, closing...')
|
||||
if not kill_bandizip():
|
||||
print(' [!] Cannot close Bandizip. Close it manually.')
|
||||
return False
|
||||
|
||||
print('\n [1/3] Backup...')
|
||||
if not backup():
|
||||
return False
|
||||
|
||||
print('\n [2/3] Patching...')
|
||||
if not apply_patches():
|
||||
return False
|
||||
|
||||
print('\n [3/3] Registry...')
|
||||
set_registry()
|
||||
|
||||
print('\n' + '=' * 50)
|
||||
print(' [DONE] All patches applied successfully!')
|
||||
print(' Use keygen to generate a product key.')
|
||||
print('=' * 50)
|
||||
return True
|
||||
|
||||
|
||||
def do_restore():
|
||||
"""执行恢复流程"""
|
||||
print('=' * 50)
|
||||
print(' Bandizip Patcher - Restore')
|
||||
print('=' * 50)
|
||||
|
||||
if is_bandizip_running():
|
||||
print(' [..] Bandizip is running, closing...')
|
||||
if not kill_bandizip():
|
||||
print(' [!] Cannot close Bandizip. Close it manually.')
|
||||
return False
|
||||
|
||||
print('\n [1/1] Restoring...')
|
||||
if restore():
|
||||
print('\n' + '=' * 50)
|
||||
print(' [DONE] Restored to original.')
|
||||
print('=' * 50)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
print('=' * 50)
|
||||
print(' Bandizip Professional Patcher v1.0')
|
||||
print('=' * 50)
|
||||
print('')
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
cmd = sys.argv[1].lower()
|
||||
if cmd == 'patch':
|
||||
do_patch()
|
||||
return
|
||||
elif cmd == 'restore':
|
||||
do_restore()
|
||||
return
|
||||
elif cmd == 'status':
|
||||
check_status()
|
||||
return
|
||||
else:
|
||||
print(' Usage: python bandizip_patcher.py [patch|restore|status]')
|
||||
return
|
||||
|
||||
# 交互模式
|
||||
print(' Commands:')
|
||||
print(' 1. Patch - Apply all patches')
|
||||
print(' 2. Restore - Restore original file')
|
||||
print(' 3. Status - Check current status')
|
||||
print(' 4. Exit')
|
||||
print('')
|
||||
|
||||
try:
|
||||
choice = input(' Select [1-4]: ').strip()
|
||||
except EOFError:
|
||||
choice = '1'
|
||||
|
||||
if choice == '1':
|
||||
do_patch()
|
||||
elif choice == '2':
|
||||
do_restore()
|
||||
elif choice == '3':
|
||||
check_status()
|
||||
else:
|
||||
print(' Bye!')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,377 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Honeycam Professional Patcher & Keygen
|
||||
=======================================
|
||||
一键补丁工具与注册码生成器。
|
||||
|
||||
使用方法:
|
||||
python honeycam_patcher.py # 交互模式
|
||||
python honeycam_patcher.py patch # 应用补丁
|
||||
python honeycam_patcher.py restore # 恢复原始
|
||||
python honeycam_patcher.py status # 检查状态
|
||||
python honeycam_keygen.py email # 生成注册码
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import random
|
||||
import string
|
||||
import hashlib
|
||||
import winreg
|
||||
|
||||
# ============ 配置 ============
|
||||
REG_KEY = r'SOFTWARE\Honeycam'
|
||||
REG_VALUE = 'Edition'
|
||||
REG_DATA = 'PRO'
|
||||
|
||||
|
||||
def find_honeycam_dir():
|
||||
"""自动查找 Honeycam 安装目录"""
|
||||
# 方法1: 注册表
|
||||
try:
|
||||
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, REG_KEY) as key:
|
||||
path, _ = winreg.QueryValueEx(key, 'ProgramFolder')
|
||||
if path and os.path.exists(os.path.join(path, 'Honeycam.exe')):
|
||||
return path.rstrip('\\')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 方法2: 卸载信息
|
||||
for subkey in [r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Honeycam',
|
||||
r'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Honeycam']:
|
||||
try:
|
||||
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, subkey) as key:
|
||||
loc, _ = winreg.QueryValueEx(key, 'InstallLocation')
|
||||
if loc and os.path.exists(os.path.join(loc, 'Honeycam.exe')):
|
||||
return loc.rstrip('\\')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 方法3: 常见路径
|
||||
common_paths = [
|
||||
os.path.join(os.environ.get('ProgramFiles', r'C:\Program Files'), 'Honeycam'),
|
||||
os.path.join(os.environ.get('ProgramFiles(x86)', r'C:\Program Files (x86)'), 'Honeycam'),
|
||||
r'D:\Apps\Honeycam',
|
||||
]
|
||||
for p in common_paths:
|
||||
if os.path.exists(os.path.join(p, 'Honeycam.exe')):
|
||||
return p
|
||||
|
||||
return None
|
||||
|
||||
|
||||
BANDIZIP_DIR = os.environ.get('HONEYCAM_DIR') or find_honeycam_dir()
|
||||
EXE_PATH = os.path.join(BANDIZIP_DIR, 'Honeycam.exe') if BANDIZIP_DIR else None
|
||||
BACKUP_PATH = (EXE_PATH + '.bak') if EXE_PATH else None
|
||||
|
||||
# Patch 定义: (文件偏移, 原始字节, 补丁字节, 描述)
|
||||
PATCHES = [
|
||||
(0x154EB0, b'\x48\x89\x54\x24\x10\x53', b'\xB0\x01\xC3',
|
||||
'sub_1401558B0 (Edition read -> return 1)'),
|
||||
(0x0F8F09, b'\x0F\x85\x51\x05\x00\x00', b'\x90\x90\x90\x90\x90\x90',
|
||||
'NOP: key length check'),
|
||||
(0x0F8F16, b'\x0F\x8C\x44\x05\x00\x00', b'\x90\x90\x90\x90\x90\x90',
|
||||
'NOP: data validity check'),
|
||||
(0x0F8F2B, b'\x0F\x84\x2F\x05\x00\x00', b'\x90\x90\x90\x90\x90\x90',
|
||||
'NOP: @ symbol check'),
|
||||
(0x0F8F39, b'\x0F\x8E\x21\x05\x00\x00', b'\x90\x90\x90\x90\x90\x90',
|
||||
'NOP: @ position check'),
|
||||
(0x0F8F54, b'\x74\x1B', b'\xEB\x1B',
|
||||
'jz -> jmp (skip lm.dll key validation)'),
|
||||
(0x0F911A, b'\x0F\x84\x9A\x02\x00\x00', b'\x90\x90\x90\x90\x90\x90',
|
||||
'NOP: BADF3300 error exit (continue offline path)'),
|
||||
(0x0F90FC, b'\x84\xC0\x0F\x85\x17\x01\x00\x00', b'\xB0\x01\xE9\x18\x01\x00\x00\x90',
|
||||
'Force success after online verify (mov al,1; jmp)'),
|
||||
(0x1552C0, b'\x89\x4C\x24\x08\x4C\x8B', b'\xB0\x01\xC3',
|
||||
'sub_140155CC0 (license data read -> return 1)'),
|
||||
(0x0F7560, b'\x48\x89\x5C\x24\x08\x4C', b'\xB0\x01\xC3',
|
||||
'sub_1400F7F60 (license validation -> return 1)'),
|
||||
]
|
||||
|
||||
|
||||
def is_patched():
|
||||
if not EXE_PATH or not os.path.exists(EXE_PATH):
|
||||
return False
|
||||
with open(EXE_PATH, 'rb') as f:
|
||||
for offset, orig, patch, desc in PATCHES:
|
||||
f.seek(offset)
|
||||
if f.read(len(patch)) != patch:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def is_backup_exists():
|
||||
return BACKUP_PATH and os.path.exists(BACKUP_PATH)
|
||||
|
||||
|
||||
def is_honeycam_running():
|
||||
try:
|
||||
import subprocess
|
||||
result = subprocess.run(['tasklist', '/FI', 'IMAGENAME eq Honeycam.exe'],
|
||||
capture_output=True, text=True, timeout=5)
|
||||
return 'Honeycam.exe' in result.stdout
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def kill_honeycam():
|
||||
try:
|
||||
import subprocess
|
||||
subprocess.run(['taskkill', '/F', '/IM', 'Honeycam.exe'],
|
||||
capture_output=True, timeout=5)
|
||||
import time
|
||||
time.sleep(2)
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def backup():
|
||||
if is_backup_exists():
|
||||
print(' [OK] Backup already exists')
|
||||
return True
|
||||
try:
|
||||
shutil.copy2(EXE_PATH, BACKUP_PATH)
|
||||
print(' [OK] Backup created: ' + BACKUP_PATH)
|
||||
return True
|
||||
except PermissionError:
|
||||
print(' [!] Permission denied. Run as Administrator.')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(' [!] Backup failed: ' + str(e))
|
||||
return False
|
||||
|
||||
|
||||
def apply_patches():
|
||||
try:
|
||||
with open(EXE_PATH, 'r+b') as f:
|
||||
for offset, orig, patch, desc in PATCHES:
|
||||
f.seek(offset)
|
||||
current = f.read(len(patch))
|
||||
if current == patch:
|
||||
print(' [SKIP] ' + desc)
|
||||
continue
|
||||
f.seek(offset)
|
||||
f.write(patch)
|
||||
print(' [OK] ' + desc)
|
||||
return True
|
||||
except PermissionError:
|
||||
print(' [!] Permission denied. Close Honeycam and run as Administrator.')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(' [!] Patch failed: ' + str(e))
|
||||
return False
|
||||
|
||||
|
||||
def restore():
|
||||
if not is_backup_exists():
|
||||
print(' [!] No backup found')
|
||||
return False
|
||||
try:
|
||||
shutil.copy2(BACKUP_PATH, EXE_PATH)
|
||||
print(' [OK] Restored from backup')
|
||||
return True
|
||||
except PermissionError:
|
||||
print(' [!] Permission denied. Close Honeycam and run as Administrator.')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(' [!] Restore failed: ' + str(e))
|
||||
return False
|
||||
|
||||
|
||||
def set_registry():
|
||||
try:
|
||||
with winreg.CreateKeyEx(winreg.HKEY_LOCAL_MACHINE, REG_KEY, 0,
|
||||
winreg.KEY_SET_VALUE) as key:
|
||||
winreg.SetValueEx(key, REG_VALUE, 0, winreg.REG_SZ, REG_DATA)
|
||||
print(' [OK] Registry: Edition = ' + REG_DATA)
|
||||
return True
|
||||
except PermissionError:
|
||||
print(' [!] Registry write denied. Run as Administrator.')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(' [!] Registry write failed: ' + str(e))
|
||||
return False
|
||||
|
||||
|
||||
def check_status():
|
||||
print('=' * 50)
|
||||
print(' Honeycam Patcher - Status')
|
||||
print('=' * 50)
|
||||
|
||||
if EXE_PATH and os.path.exists(EXE_PATH):
|
||||
print(' [OK] Honeycam.exe: ' + EXE_PATH)
|
||||
else:
|
||||
print(' [!] Honeycam.exe not found!')
|
||||
return
|
||||
|
||||
if is_backup_exists():
|
||||
print(' [OK] Backup exists')
|
||||
else:
|
||||
print(' [!] No backup')
|
||||
|
||||
patched_count = 0
|
||||
with open(EXE_PATH, 'rb') as f:
|
||||
for offset, orig, patch, desc in PATCHES:
|
||||
f.seek(offset)
|
||||
current = f.read(len(patch))
|
||||
if current == patch:
|
||||
patched_count += 1
|
||||
status = '[PATCHED]'
|
||||
elif current == orig:
|
||||
status = '[ORIGINAL]'
|
||||
else:
|
||||
status = '[UNKNOWN]'
|
||||
print(' ' + status + ' 0x{:06X}: '.format(offset) + desc)
|
||||
|
||||
print('\n Patched: ' + str(patched_count) + '/' + str(len(PATCHES)))
|
||||
|
||||
try:
|
||||
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, REG_KEY) as key:
|
||||
val, _ = winreg.QueryValueEx(key, REG_VALUE)
|
||||
print(' [Registry] Edition = ' + val)
|
||||
except Exception:
|
||||
print(' [Registry] Edition not set')
|
||||
|
||||
if is_honeycam_running():
|
||||
print(' [WARNING] Honeycam is running!')
|
||||
else:
|
||||
print(' [OK] Honeycam is not running')
|
||||
|
||||
print('=' * 50)
|
||||
|
||||
|
||||
def do_patch():
|
||||
print('=' * 50)
|
||||
print(' Honeycam Patcher - Apply')
|
||||
print('=' * 50)
|
||||
|
||||
if not EXE_PATH or not os.path.exists(EXE_PATH):
|
||||
print(' [!] Honeycam.exe not found!')
|
||||
return False
|
||||
|
||||
if is_honeycam_running():
|
||||
print(' [..] Honeycam is running, closing...')
|
||||
if not kill_honeycam():
|
||||
print(' [!] Cannot close Honeycam.')
|
||||
return False
|
||||
|
||||
print('\n [1/3] Backup...')
|
||||
if not backup():
|
||||
return False
|
||||
|
||||
print('\n [2/3] Patching...')
|
||||
if not apply_patches():
|
||||
return False
|
||||
|
||||
print('\n [3/3] Registry...')
|
||||
set_registry()
|
||||
|
||||
print('\n' + '=' * 50)
|
||||
print(' [DONE] All patches applied!')
|
||||
print('=' * 50)
|
||||
return True
|
||||
|
||||
|
||||
def do_restore():
|
||||
print('=' * 50)
|
||||
print(' Honeycam Patcher - Restore')
|
||||
print('=' * 50)
|
||||
|
||||
if is_honeycam_running():
|
||||
print(' [..] Honeycam is running, closing...')
|
||||
if not kill_honeycam():
|
||||
return False
|
||||
|
||||
print('\n [1/1] Restoring...')
|
||||
if restore():
|
||||
print('\n' + '=' * 50)
|
||||
print(' [DONE] Restored to original.')
|
||||
print('=' * 50)
|
||||
|
||||
|
||||
def generate_keygen(email):
|
||||
"""生成注册码
|
||||
|
||||
Honeycam 注册码格式: 26 字符
|
||||
- 前 8 位: 日期 YYYYMMDD (正则 [2][0-1][0-9][0-9][0-1][0-9][0-3][0-9])
|
||||
- 后 18 位: 任意字符
|
||||
"""
|
||||
import datetime
|
||||
seed = int(hashlib.md5(email.encode()).hexdigest()[:8], 16)
|
||||
rng = random.Random(seed)
|
||||
|
||||
# 前 8 位: 日期 (2019-2021 年范围, 匹配正则 [2][0-1][0-9][0-9])
|
||||
year = rng.randint(2019, 2021)
|
||||
month = rng.randint(1, 12)
|
||||
day = rng.randint(1, 28)
|
||||
date_prefix = f"{year}{month:02d}{day:02d}"
|
||||
|
||||
# 后 18 位: 随机字符
|
||||
charset = string.ascii_letters + string.digits
|
||||
suffix = ''.join(rng.choices(charset, k=18))
|
||||
|
||||
return date_prefix + suffix
|
||||
|
||||
|
||||
def do_keygen():
|
||||
if len(sys.argv) > 2:
|
||||
email = sys.argv[2]
|
||||
else:
|
||||
email = input(' Email: ').strip()
|
||||
if not email:
|
||||
email = 'user@honeycam.local'
|
||||
|
||||
key = generate_keygen(email)
|
||||
print('\n Email: ' + email)
|
||||
print(' Product Key: ' + key)
|
||||
print(' Edition: PRO')
|
||||
print('\n Open Honeycam -> Help -> Register')
|
||||
print(' Enter the email and product key above.')
|
||||
|
||||
|
||||
def main():
|
||||
print('=' * 50)
|
||||
print(' Honeycam Professional Patcher v1.0')
|
||||
print('=' * 50)
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
cmd = sys.argv[1].lower()
|
||||
if cmd == 'patch':
|
||||
do_patch()
|
||||
return
|
||||
elif cmd == 'restore':
|
||||
do_restore()
|
||||
return
|
||||
elif cmd == 'status':
|
||||
check_status()
|
||||
return
|
||||
elif cmd == 'keygen':
|
||||
do_keygen()
|
||||
return
|
||||
|
||||
print('\n Commands:')
|
||||
print(' 1. Patch - Apply all patches')
|
||||
print(' 2. Restore - Restore original')
|
||||
print(' 3. Status - Check status')
|
||||
print(' 4. Keygen - Generate product key')
|
||||
print(' 5. Exit')
|
||||
|
||||
try:
|
||||
choice = input('\n Select [1-5]: ').strip()
|
||||
except EOFError:
|
||||
choice = '1'
|
||||
|
||||
if choice == '1':
|
||||
do_patch()
|
||||
elif choice == '2':
|
||||
do_restore()
|
||||
elif choice == '3':
|
||||
check_status()
|
||||
elif choice == '4':
|
||||
do_keygen()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user