mirror of
https://github.com/violettoolssite/CFspider.git
synced 2026-04-05 03:09:01 +08:00
feat(x27cn): v1.4.0 添加一键保护和反爬功能
This commit is contained in:
122
x27cn/README.md
122
x27cn/README.md
@@ -352,6 +352,120 @@ x27cn encrypt secret.txt --password="mypassword"
|
||||
x27cn decrypt secret.txt.enc --password="mypassword"
|
||||
```
|
||||
|
||||
## 反爬虫保护(v1.4.0 新增)
|
||||
|
||||
X27CN 现在提供一键式代码保护,包含反调试、反爬虫、域名锁定等功能。
|
||||
|
||||
### 一键保护(推荐)
|
||||
|
||||
```python
|
||||
import x27cn
|
||||
|
||||
# 一键完整保护(混淆 + 反爬)
|
||||
protected = x27cn.full_obfuscate(js_code, level=2)
|
||||
|
||||
# 保护级别:
|
||||
# level=1: 基础 - 压缩 + 变量重命名
|
||||
# level=2: 中等 - 基础 + 字符串加密 + 死代码
|
||||
# level=3: 高级 - 中等 + 反调试 + 禁用快捷键
|
||||
|
||||
# 快速保护(一行代码)
|
||||
protected = x27cn.quick_protect(js_code)
|
||||
|
||||
# 保护文件
|
||||
x27cn.obfuscate_file_full('app.js', level=3, anti_crawl=True)
|
||||
```
|
||||
|
||||
### 反调试保护
|
||||
|
||||
```python
|
||||
import x27cn
|
||||
|
||||
# 生成反调试代码(无限 debugger + 时间检测 + 控制台检测)
|
||||
anti_debug = x27cn.generate_anti_debug()
|
||||
|
||||
# 生成禁用快捷键代码(F12, Ctrl+Shift+I, 右键等)
|
||||
disable_shortcuts = x27cn.generate_disable_shortcuts()
|
||||
|
||||
# 控制台清除和警告
|
||||
console_clear = x27cn.generate_console_clear()
|
||||
|
||||
# 组合完整保护
|
||||
protection = x27cn.generate_full_protection(
|
||||
anti_debug=True,
|
||||
disable_shortcuts=True,
|
||||
console_clear=True
|
||||
)
|
||||
|
||||
# 注入保护到代码
|
||||
protected_code = x27cn.inject_protection(js_code, anti_debug=True)
|
||||
```
|
||||
|
||||
### 域名锁定
|
||||
|
||||
```python
|
||||
# 限制代码只能在指定域名运行
|
||||
domain_lock = x27cn.generate_domain_lock(['example.com', 'test.com'])
|
||||
|
||||
# 或使用 full_obfuscate
|
||||
protected = x27cn.full_obfuscate(js_code, domain_lock=['example.com'])
|
||||
```
|
||||
|
||||
### 时间限制(许可证过期)
|
||||
|
||||
```python
|
||||
# 代码在指定日期后失效
|
||||
time_bomb = x27cn.generate_time_bomb('2025-12-31')
|
||||
```
|
||||
|
||||
### 命令行
|
||||
|
||||
```bash
|
||||
# 一键保护(推荐)
|
||||
x27cn protect app.js
|
||||
|
||||
# 指定保护级别
|
||||
x27cn protect app.js --level=3
|
||||
|
||||
# 域名锁定
|
||||
x27cn protect app.js --domain=example.com --domain=test.com
|
||||
|
||||
# 设置过期日期
|
||||
x27cn protect app.js --expire=2025-12-31
|
||||
|
||||
# 不添加反爬
|
||||
x27cn protect app.js --no-anti-crawl
|
||||
|
||||
# 仅生成反调试代码
|
||||
x27cn anti-debug
|
||||
|
||||
# 生成带禁用快捷键的反调试代码
|
||||
x27cn anti-debug --disable-shortcuts --console-clear
|
||||
```
|
||||
|
||||
### 保护效果
|
||||
|
||||
**原始代码:**
|
||||
```javascript
|
||||
function getSecret() {
|
||||
return "API_KEY_12345";
|
||||
}
|
||||
```
|
||||
|
||||
**level=3 保护后:**
|
||||
```javascript
|
||||
(function(){var _$a=function(){var _$b=new Date().getTime();debugger;...})();
|
||||
var _$k=[120,50,...];var _$a=[[65,83,...]];var _$s=function(i){...};
|
||||
var _$0=function(){return _$s(0)};...
|
||||
```
|
||||
|
||||
反调试特性:
|
||||
- 无限 debugger 断点
|
||||
- 检测 DevTools 打开
|
||||
- 时间检测(调试暂停时触发)
|
||||
- 禁用 F12 / Ctrl+Shift+I / 右键
|
||||
- 控制台定期清除
|
||||
|
||||
## 安全说明
|
||||
|
||||
X27CN 提供两种安全级别:
|
||||
@@ -398,6 +512,14 @@ X27CN 提供两种安全级别:
|
||||
| `encrypt_with_password(data, pwd)` | 密码加密数据 |
|
||||
| `decrypt_with_password(data, pwd)` | 密码解密数据 |
|
||||
| `md5(text)` / `sha256(text)` | 快速哈希 |
|
||||
| `full_obfuscate(code, level)` | 一键完整混淆 |
|
||||
| `quick_protect(code)` | 快速保护代码 |
|
||||
| `obfuscate_file_full(path, level)` | 一键保护文件 |
|
||||
| `generate_anti_debug()` | 生成反调试代码 |
|
||||
| `generate_disable_shortcuts()` | 生成禁用快捷键代码 |
|
||||
| `generate_domain_lock(domains)` | 生成域名锁定代码 |
|
||||
| `generate_time_bomb(date)` | 生成时间限制代码 |
|
||||
| `inject_protection(code, ...)` | 注入保护到代码 |
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "x27cn"
|
||||
version = "1.3.0"
|
||||
description = "X27CN 代码混淆加密库 - Code obfuscation and encryption library"
|
||||
version = "1.4.0"
|
||||
description = "X27CN - Advanced code obfuscation, encryption and anti-crawl protection"
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
requires-python = ">=3.7"
|
||||
@@ -19,8 +19,9 @@ keywords = [
|
||||
"encoding",
|
||||
"html",
|
||||
"javascript",
|
||||
"加密",
|
||||
"混淆"
|
||||
"anti-debug",
|
||||
"anti-crawl",
|
||||
"code-protection"
|
||||
]
|
||||
classifiers = [
|
||||
"Development Status :: 4 - Beta",
|
||||
|
||||
@@ -68,7 +68,26 @@ from .password import (
|
||||
sha512,
|
||||
)
|
||||
|
||||
__version__ = '1.3.0'
|
||||
from .anti_crawl import (
|
||||
generate_anti_debug,
|
||||
generate_disable_shortcuts,
|
||||
generate_console_clear,
|
||||
generate_code_integrity_check,
|
||||
generate_domain_lock,
|
||||
generate_time_bomb,
|
||||
generate_full_protection,
|
||||
inject_protection,
|
||||
)
|
||||
|
||||
from .advanced import (
|
||||
encrypt_strings,
|
||||
advanced_obfuscate,
|
||||
full_obfuscate,
|
||||
obfuscate_file_full,
|
||||
quick_protect,
|
||||
)
|
||||
|
||||
__version__ = '1.4.0'
|
||||
__author__ = 'CFspider'
|
||||
__all__ = [
|
||||
# 核心加密
|
||||
@@ -111,5 +130,20 @@ __all__ = [
|
||||
'md5',
|
||||
'sha256',
|
||||
'sha512',
|
||||
# 反爬虫保护
|
||||
'generate_anti_debug',
|
||||
'generate_disable_shortcuts',
|
||||
'generate_console_clear',
|
||||
'generate_code_integrity_check',
|
||||
'generate_domain_lock',
|
||||
'generate_time_bomb',
|
||||
'generate_full_protection',
|
||||
'inject_protection',
|
||||
# 高级混淆(一键式)
|
||||
'encrypt_strings',
|
||||
'advanced_obfuscate',
|
||||
'full_obfuscate',
|
||||
'obfuscate_file_full',
|
||||
'quick_protect',
|
||||
]
|
||||
|
||||
|
||||
290
x27cn/x27cn/advanced.py
Normal file
290
x27cn/x27cn/advanced.py
Normal file
@@ -0,0 +1,290 @@
|
||||
"""
|
||||
X27CN 高级混淆加密模块
|
||||
|
||||
提供一键式代码混淆和保护:
|
||||
- 字符串加密
|
||||
- 变量名混淆
|
||||
- 控制流扁平化
|
||||
- 死代码注入
|
||||
- 反调试保护
|
||||
"""
|
||||
|
||||
import re
|
||||
import random
|
||||
import string
|
||||
from typing import Optional
|
||||
from .core import encrypt, DEFAULT_KEY
|
||||
from .minify import minify_js, obfuscate_identifiers, add_dead_code
|
||||
from .anti_crawl import generate_full_protection, inject_protection
|
||||
|
||||
|
||||
def encrypt_strings(js_code: str, key: str = DEFAULT_KEY) -> str:
|
||||
"""
|
||||
加密 JavaScript 代码中的字符串
|
||||
|
||||
将所有字符串字面量替换为运行时解密调用。
|
||||
|
||||
Args:
|
||||
js_code: JavaScript 代码
|
||||
key: 加密密钥
|
||||
|
||||
Returns:
|
||||
字符串加密后的代码
|
||||
"""
|
||||
# 收集所有字符串
|
||||
strings = []
|
||||
|
||||
def collect_string(match):
|
||||
quote = match.group(1)
|
||||
content = match.group(2)
|
||||
if content and len(content) > 2: # 只加密较长的字符串
|
||||
idx = len(strings)
|
||||
strings.append(content)
|
||||
return f'_$s({idx})'
|
||||
return match.group(0)
|
||||
|
||||
# 匹配字符串(简化版,可能有边缘情况)
|
||||
pattern = r'(["\'])([^"\'\\]*(?:\\.[^"\'\\]*)*)\1'
|
||||
processed = re.sub(pattern, collect_string, js_code)
|
||||
|
||||
if not strings:
|
||||
return js_code
|
||||
|
||||
# 生成解密器和字符串数组
|
||||
key_bytes = key.encode('utf-8')
|
||||
key_array = ','.join(str(b) for b in key_bytes)
|
||||
|
||||
# 简单的 XOR 加密
|
||||
encrypted_strings = []
|
||||
for s in strings:
|
||||
encrypted = []
|
||||
for i, c in enumerate(s):
|
||||
encrypted.append(ord(c) ^ key_bytes[i % len(key_bytes)])
|
||||
encrypted_strings.append(','.join(str(b) for b in encrypted))
|
||||
|
||||
strings_array = ';'.join(f'[{s}]' for s in encrypted_strings)
|
||||
|
||||
decoder = f'''
|
||||
var _$k=[{key_array}];
|
||||
var _$a=[{strings_array}];
|
||||
var _$s=function(i){{var a=_$a[i],r='';for(var j=0;j<a.length;j++)r+=String.fromCharCode(a[j]^_$k[j%_$k.length]);return r}};
|
||||
'''
|
||||
|
||||
return decoder + processed
|
||||
|
||||
|
||||
def advanced_obfuscate(
|
||||
js_code: str,
|
||||
key: str = DEFAULT_KEY,
|
||||
encrypt_strings_: bool = True,
|
||||
rename_vars: bool = True,
|
||||
dead_code: bool = True,
|
||||
anti_debug: bool = False,
|
||||
disable_shortcuts: bool = False,
|
||||
domain_lock: list = None,
|
||||
expire_date: str = None
|
||||
) -> str:
|
||||
"""
|
||||
高级代码混淆
|
||||
|
||||
应用多层混淆保护。
|
||||
|
||||
Args:
|
||||
js_code: JavaScript 代码
|
||||
key: 加密密钥
|
||||
encrypt_strings_: 加密字符串
|
||||
rename_vars: 重命名变量
|
||||
dead_code: 添加死代码
|
||||
anti_debug: 添加反调试
|
||||
disable_shortcuts: 禁用快捷键
|
||||
domain_lock: 域名锁定
|
||||
expire_date: 过期日期
|
||||
|
||||
Returns:
|
||||
混淆后的代码
|
||||
"""
|
||||
result = js_code
|
||||
|
||||
# 1. 变量重命名
|
||||
if rename_vars:
|
||||
result = obfuscate_identifiers(result)
|
||||
|
||||
# 2. 添加死代码
|
||||
if dead_code:
|
||||
result = add_dead_code(result)
|
||||
|
||||
# 3. 字符串加密
|
||||
if encrypt_strings_:
|
||||
result = encrypt_strings(result, key)
|
||||
|
||||
# 4. 添加保护代码
|
||||
if anti_debug or disable_shortcuts or domain_lock or expire_date:
|
||||
result = inject_protection(
|
||||
result,
|
||||
anti_debug=anti_debug,
|
||||
disable_shortcuts=disable_shortcuts,
|
||||
console_clear=anti_debug,
|
||||
domain_lock=domain_lock,
|
||||
expire_date=expire_date
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def full_obfuscate(
|
||||
code: str,
|
||||
file_type: str = 'js',
|
||||
key: str = DEFAULT_KEY,
|
||||
level: int = 2,
|
||||
anti_crawl: bool = True
|
||||
) -> str:
|
||||
"""
|
||||
一键完整混淆
|
||||
|
||||
根据保护级别应用不同程度的混淆。
|
||||
|
||||
Args:
|
||||
code: 源代码
|
||||
file_type: 文件类型 ('js', 'html', 'css')
|
||||
key: 加密密钥
|
||||
level: 混淆级别 (1-3)
|
||||
1: 基础 - 压缩 + 变量重命名
|
||||
2: 中等 - 基础 + 字符串加密 + 死代码
|
||||
3: 高级 - 中等 + 反调试 + 禁用快捷键
|
||||
anti_crawl: 添加反爬保护
|
||||
|
||||
Returns:
|
||||
混淆后的代码
|
||||
"""
|
||||
if file_type == 'html':
|
||||
return _obfuscate_html_full(code, key, level, anti_crawl)
|
||||
elif file_type == 'css':
|
||||
return _obfuscate_css_full(code, key)
|
||||
else:
|
||||
return _obfuscate_js_full(code, key, level, anti_crawl)
|
||||
|
||||
|
||||
def _obfuscate_js_full(code: str, key: str, level: int, anti_crawl: bool) -> str:
|
||||
"""完整混淆 JavaScript"""
|
||||
# Level 1: 基础
|
||||
result = minify_js(code)
|
||||
result = obfuscate_identifiers(result)
|
||||
|
||||
if level >= 2:
|
||||
# Level 2: 中等
|
||||
result = encrypt_strings(result, key)
|
||||
result = add_dead_code(result)
|
||||
|
||||
if level >= 3:
|
||||
# Level 3: 高级
|
||||
result = inject_protection(
|
||||
result,
|
||||
anti_debug=True,
|
||||
disable_shortcuts=True,
|
||||
console_clear=True
|
||||
)
|
||||
elif anti_crawl:
|
||||
# 仅反爬(无反调试)
|
||||
result = inject_protection(
|
||||
result,
|
||||
anti_debug=False,
|
||||
disable_shortcuts=True,
|
||||
console_clear=False
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _obfuscate_html_full(code: str, key: str, level: int, anti_crawl: bool) -> str:
|
||||
"""完整混淆 HTML"""
|
||||
from .obfuscate import obfuscate_html, obfuscate_inline_js
|
||||
|
||||
# 先混淆内联 JS
|
||||
result = obfuscate_inline_js(code, key)
|
||||
|
||||
if level >= 2:
|
||||
# 加密整个 HTML
|
||||
result = obfuscate_html(result, key)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _obfuscate_css_full(code: str, key: str) -> str:
|
||||
"""完整混淆 CSS"""
|
||||
from .obfuscate import obfuscate_css
|
||||
from .minify import minify_css
|
||||
|
||||
# 压缩并加密
|
||||
result = minify_css(code)
|
||||
result = obfuscate_css(result, key)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def obfuscate_file_full(
|
||||
input_path: str,
|
||||
output_path: Optional[str] = None,
|
||||
key: str = DEFAULT_KEY,
|
||||
level: int = 2,
|
||||
anti_crawl: bool = True
|
||||
) -> str:
|
||||
"""
|
||||
一键混淆文件
|
||||
|
||||
Args:
|
||||
input_path: 输入文件路径
|
||||
output_path: 输出文件路径(可选)
|
||||
key: 加密密钥
|
||||
level: 混淆级别 (1-3)
|
||||
anti_crawl: 添加反爬保护
|
||||
|
||||
Returns:
|
||||
输出文件路径
|
||||
"""
|
||||
import os
|
||||
|
||||
# 读取文件
|
||||
with open(input_path, 'r', encoding='utf-8') as f:
|
||||
code = f.read()
|
||||
|
||||
# 确定文件类型
|
||||
ext = os.path.splitext(input_path)[1].lower()
|
||||
if ext in ('.html', '.htm'):
|
||||
file_type = 'html'
|
||||
elif ext == '.css':
|
||||
file_type = 'css'
|
||||
else:
|
||||
file_type = 'js'
|
||||
|
||||
# 混淆
|
||||
result = full_obfuscate(code, file_type, key, level, anti_crawl)
|
||||
|
||||
# 确定输出路径
|
||||
if output_path is None:
|
||||
base, ext = os.path.splitext(input_path)
|
||||
output_path = f"{base}.protected{ext}"
|
||||
|
||||
# 写入
|
||||
with open(output_path, 'w', encoding='utf-8') as f:
|
||||
f.write(result)
|
||||
|
||||
return output_path
|
||||
|
||||
|
||||
def quick_protect(js_code: str) -> str:
|
||||
"""
|
||||
快速保护 JavaScript 代码
|
||||
|
||||
一行代码完成混淆 + 反爬保护。
|
||||
|
||||
Args:
|
||||
js_code: JavaScript 代码
|
||||
|
||||
Returns:
|
||||
保护后的代码
|
||||
|
||||
Example:
|
||||
>>> protected = x27cn.quick_protect('alert("Hello")')
|
||||
"""
|
||||
return full_obfuscate(js_code, 'js', DEFAULT_KEY, level=2, anti_crawl=True)
|
||||
|
||||
298
x27cn/x27cn/anti_crawl.py
Normal file
298
x27cn/x27cn/anti_crawl.py
Normal file
@@ -0,0 +1,298 @@
|
||||
"""
|
||||
X27CN 反爬虫保护模块
|
||||
|
||||
提供多种反爬虫和反调试保护机制:
|
||||
- 无限 debugger 断点
|
||||
- 控制台检测
|
||||
- 时间检测(检测调试暂停)
|
||||
- 窗口大小检测(检测 DevTools)
|
||||
- 禁用右键和快捷键
|
||||
- 代码自检(检测篡改)
|
||||
"""
|
||||
|
||||
import random
|
||||
import string
|
||||
import hashlib
|
||||
|
||||
|
||||
def generate_anti_debug() -> str:
|
||||
"""
|
||||
生成反调试代码
|
||||
|
||||
包含多层反调试保护:
|
||||
1. 无限 debugger 断点
|
||||
2. 时间检测
|
||||
3. 控制台检测
|
||||
4. 窗口尺寸检测
|
||||
|
||||
Returns:
|
||||
反调试 JavaScript 代码
|
||||
"""
|
||||
# 随机变量名
|
||||
vars = _random_vars(10)
|
||||
|
||||
return f'''
|
||||
(function() {{
|
||||
var {vars[0]} = function() {{
|
||||
var {vars[1]} = new Date().getTime();
|
||||
debugger;
|
||||
var {vars[2]} = new Date().getTime();
|
||||
if ({vars[2]} - {vars[1]} > 100) {{
|
||||
{vars[3]}();
|
||||
}}
|
||||
}};
|
||||
|
||||
var {vars[3]} = function() {{
|
||||
while(true) {{
|
||||
debugger;
|
||||
{vars[0]}();
|
||||
}}
|
||||
}};
|
||||
|
||||
var {vars[4]} = function() {{
|
||||
var {vars[5]} = /./;
|
||||
{vars[5]}.toString = function() {{
|
||||
{vars[3]}();
|
||||
return '';
|
||||
}};
|
||||
console.log('%c', {vars[5]});
|
||||
}};
|
||||
|
||||
var {vars[6]} = function() {{
|
||||
var {vars[7]} = window.outerWidth - window.innerWidth > 160;
|
||||
var {vars[8]} = window.outerHeight - window.innerHeight > 160;
|
||||
if ({vars[7]} || {vars[8]}) {{
|
||||
{vars[3]}();
|
||||
}}
|
||||
}};
|
||||
|
||||
setInterval({vars[0]}, 1000);
|
||||
setInterval({vars[4]}, 2000);
|
||||
setInterval({vars[6]}, 1500);
|
||||
{vars[0]}();
|
||||
}})();
|
||||
'''
|
||||
|
||||
|
||||
def generate_disable_shortcuts() -> str:
|
||||
"""
|
||||
生成禁用快捷键代码
|
||||
|
||||
禁用常用的开发者工具快捷键:
|
||||
- F12
|
||||
- Ctrl+Shift+I/J/C
|
||||
- Ctrl+U (查看源代码)
|
||||
- 右键菜单
|
||||
|
||||
Returns:
|
||||
禁用快捷键 JavaScript 代码
|
||||
"""
|
||||
vars = _random_vars(5)
|
||||
|
||||
return f'''
|
||||
(function() {{
|
||||
document.addEventListener('keydown', function({vars[0]}) {{
|
||||
if ({vars[0]}.key === 'F12' ||
|
||||
({vars[0]}.ctrlKey && {vars[0]}.shiftKey && ['I','i','J','j','C','c'].includes({vars[0]}.key)) ||
|
||||
({vars[0]}.ctrlKey && ['U','u'].includes({vars[0]}.key))) {{
|
||||
{vars[0]}.preventDefault();
|
||||
{vars[0]}.stopPropagation();
|
||||
return false;
|
||||
}}
|
||||
}}, true);
|
||||
|
||||
document.addEventListener('contextmenu', function({vars[1]}) {{
|
||||
{vars[1]}.preventDefault();
|
||||
return false;
|
||||
}}, true);
|
||||
|
||||
document.onselectstart = function() {{ return false; }};
|
||||
document.ondragstart = function() {{ return false; }};
|
||||
}})();
|
||||
'''
|
||||
|
||||
|
||||
def generate_console_clear() -> str:
|
||||
"""
|
||||
生成控制台清除和欺骗代码
|
||||
|
||||
定期清除控制台并显示警告信息。
|
||||
|
||||
Returns:
|
||||
控制台清除 JavaScript 代码
|
||||
"""
|
||||
vars = _random_vars(3)
|
||||
|
||||
return f'''
|
||||
(function() {{
|
||||
var {vars[0]} = function() {{
|
||||
console.clear();
|
||||
console.log('%cSTOP!', 'color:red;font-size:50px;font-weight:bold;');
|
||||
console.log('%cThis browser feature is for developers only.', 'font-size:16px;');
|
||||
}};
|
||||
setInterval({vars[0]}, 500);
|
||||
{vars[0]}();
|
||||
}})();
|
||||
'''
|
||||
|
||||
|
||||
def generate_code_integrity_check(code: str) -> str:
|
||||
"""
|
||||
生成代码完整性检查
|
||||
|
||||
计算代码哈希,运行时检测代码是否被修改。
|
||||
|
||||
Args:
|
||||
code: 需要保护的代码
|
||||
|
||||
Returns:
|
||||
带完整性检查的代码
|
||||
"""
|
||||
# 计算代码哈希
|
||||
code_hash = hashlib.md5(code.encode()).hexdigest()[:16]
|
||||
vars = _random_vars(5)
|
||||
|
||||
return f'''
|
||||
(function() {{
|
||||
var {vars[0]} = '{code_hash}';
|
||||
var {vars[1]} = function({vars[2]}) {{
|
||||
var {vars[3]} = 0;
|
||||
for (var i = 0; i < {vars[2]}.length; i++) {{
|
||||
{vars[3]} = (({vars[3]} << 5) - {vars[3]}) + {vars[2]}.charCodeAt(i);
|
||||
{vars[3]} = {vars[3]} & {vars[3]};
|
||||
}}
|
||||
return ({vars[3]} >>> 0).toString(16);
|
||||
}};
|
||||
var {vars[4]} = {vars[1]}(arguments.callee.toString());
|
||||
// Integrity check placeholder
|
||||
}})();
|
||||
{code}
|
||||
'''
|
||||
|
||||
|
||||
def generate_domain_lock(domains: list) -> str:
|
||||
"""
|
||||
生成域名锁定代码
|
||||
|
||||
限制代码只能在指定域名运行。
|
||||
|
||||
Args:
|
||||
domains: 允许运行的域名列表
|
||||
|
||||
Returns:
|
||||
域名锁定 JavaScript 代码
|
||||
"""
|
||||
vars = _random_vars(4)
|
||||
domains_str = ','.join(f'"{d}"' for d in domains)
|
||||
|
||||
return f'''
|
||||
(function() {{
|
||||
var {vars[0]} = [{domains_str}];
|
||||
var {vars[1]} = window.location.hostname;
|
||||
var {vars[2]} = false;
|
||||
for (var i = 0; i < {vars[0]}.length; i++) {{
|
||||
if ({vars[1]} === {vars[0]}[i] || {vars[1]}.endsWith('.' + {vars[0]}[i])) {{
|
||||
{vars[2]} = true;
|
||||
break;
|
||||
}}
|
||||
}}
|
||||
if (!{vars[2]}) {{
|
||||
document.body.innerHTML = '<h1>Unauthorized Domain</h1>';
|
||||
throw new Error('Unauthorized domain');
|
||||
}}
|
||||
}})();
|
||||
'''
|
||||
|
||||
|
||||
def generate_time_bomb(expire_date: str) -> str:
|
||||
"""
|
||||
生成时间炸弹代码
|
||||
|
||||
代码在指定日期后失效。
|
||||
|
||||
Args:
|
||||
expire_date: 过期日期 (格式: YYYY-MM-DD)
|
||||
|
||||
Returns:
|
||||
时间炸弹 JavaScript 代码
|
||||
"""
|
||||
vars = _random_vars(3)
|
||||
|
||||
return f'''
|
||||
(function() {{
|
||||
var {vars[0]} = new Date('{expire_date}').getTime();
|
||||
var {vars[1]} = new Date().getTime();
|
||||
if ({vars[1]} > {vars[0]}) {{
|
||||
document.body.innerHTML = '<h1>License Expired</h1>';
|
||||
throw new Error('License expired');
|
||||
}}
|
||||
}})();
|
||||
'''
|
||||
|
||||
|
||||
def generate_full_protection(
|
||||
anti_debug: bool = True,
|
||||
disable_shortcuts: bool = True,
|
||||
console_clear: bool = True,
|
||||
domain_lock: list = None,
|
||||
expire_date: str = None
|
||||
) -> str:
|
||||
"""
|
||||
生成完整反爬保护代码
|
||||
|
||||
组合多种保护机制。
|
||||
|
||||
Args:
|
||||
anti_debug: 启用反调试
|
||||
disable_shortcuts: 禁用快捷键
|
||||
console_clear: 清除控制台
|
||||
domain_lock: 域名锁定列表
|
||||
expire_date: 过期日期
|
||||
|
||||
Returns:
|
||||
完整保护 JavaScript 代码
|
||||
"""
|
||||
parts = []
|
||||
|
||||
if domain_lock:
|
||||
parts.append(generate_domain_lock(domain_lock))
|
||||
|
||||
if expire_date:
|
||||
parts.append(generate_time_bomb(expire_date))
|
||||
|
||||
if anti_debug:
|
||||
parts.append(generate_anti_debug())
|
||||
|
||||
if disable_shortcuts:
|
||||
parts.append(generate_disable_shortcuts())
|
||||
|
||||
if console_clear:
|
||||
parts.append(generate_console_clear())
|
||||
|
||||
return '\n'.join(parts)
|
||||
|
||||
|
||||
def inject_protection(js_code: str, **kwargs) -> str:
|
||||
"""
|
||||
为 JavaScript 代码注入反爬保护
|
||||
|
||||
Args:
|
||||
js_code: 原始 JavaScript 代码
|
||||
**kwargs: generate_full_protection 的参数
|
||||
|
||||
Returns:
|
||||
注入保护后的代码
|
||||
"""
|
||||
protection = generate_full_protection(**kwargs)
|
||||
return protection + '\n' + js_code
|
||||
|
||||
|
||||
def _random_vars(count: int) -> list:
|
||||
"""生成随机变量名"""
|
||||
chars = string.ascii_letters
|
||||
vars = []
|
||||
for _ in range(count):
|
||||
name = '_$' + ''.join(random.choice(chars) for _ in range(6))
|
||||
vars.append(name)
|
||||
return vars
|
||||
|
||||
@@ -7,6 +7,8 @@ X27CN 命令行工具
|
||||
x27cn obfuscate <file> [output] [--key=密钥]
|
||||
x27cn minify <file> [output] [--no-mangle] [--no-node]
|
||||
x27cn flatten <file> [output] [--intensity=2] [--safe]
|
||||
x27cn protect <file> [output] [--level=2] [--anti-crawl] # 一键保护
|
||||
x27cn anti-debug # 生成反调试代码
|
||||
x27cn password hash <password>
|
||||
x27cn password verify <password> <hash>
|
||||
x27cn password generate [--length=16]
|
||||
@@ -22,6 +24,8 @@ from .password import (
|
||||
hash_password, verify_password, generate_password,
|
||||
check_password_strength, encrypt_with_password, decrypt_with_password
|
||||
)
|
||||
from .anti_crawl import generate_full_protection, generate_anti_debug, generate_disable_shortcuts
|
||||
from .advanced import full_obfuscate, obfuscate_file_full, quick_protect
|
||||
|
||||
|
||||
def main():
|
||||
@@ -29,7 +33,7 @@ def main():
|
||||
prog='x27cn',
|
||||
description='X27CN 代码混淆加密工具'
|
||||
)
|
||||
parser.add_argument('--version', action='version', version='x27cn 1.3.0')
|
||||
parser.add_argument('--version', action='version', version='x27cn 1.4.0')
|
||||
|
||||
subparsers = parser.add_subparsers(dest='command', help='命令')
|
||||
|
||||
@@ -72,6 +76,25 @@ def main():
|
||||
help='扁平化强度 (1=轻, 2=中, 3=强)')
|
||||
flat_parser.add_argument('--safe', '-s', action='store_true', help='使用安全模式(更保守)')
|
||||
|
||||
# protect 命令(一键保护)
|
||||
prot_parser = subparsers.add_parser('protect', help='一键完整保护(混淆+反爬+反调试)')
|
||||
prot_parser.add_argument('input', help='输入文件 (.html/.js/.css)')
|
||||
prot_parser.add_argument('output', nargs='?', help='输出文件(可选)')
|
||||
prot_parser.add_argument('--key', '-k', default=DEFAULT_KEY, help='加密密钥')
|
||||
prot_parser.add_argument('--level', '-l', type=int, default=2, choices=[1, 2, 3],
|
||||
help='保护级别 (1=基础, 2=中等, 3=高级)')
|
||||
prot_parser.add_argument('--no-anti-crawl', action='store_true', help='不添加反爬保护')
|
||||
prot_parser.add_argument('--domain', '-d', action='append', help='域名锁定(可多次指定)')
|
||||
prot_parser.add_argument('--expire', help='过期日期 (YYYY-MM-DD)')
|
||||
|
||||
# anti-debug 命令
|
||||
anti_parser = subparsers.add_parser('anti-debug', help='生成反调试保护代码')
|
||||
anti_parser.add_argument('--output', '-o', help='输出文件(可选)')
|
||||
anti_parser.add_argument('--disable-shortcuts', '-s', action='store_true', help='包含禁用快捷键')
|
||||
anti_parser.add_argument('--console-clear', '-c', action='store_true', help='包含控制台清除')
|
||||
anti_parser.add_argument('--domain', '-d', action='append', help='域名锁定')
|
||||
anti_parser.add_argument('--expire', help='过期日期')
|
||||
|
||||
# password 命令
|
||||
pwd_parser = subparsers.add_parser('password', help='密码工具')
|
||||
pwd_subparsers = pwd_parser.add_subparsers(dest='pwd_command', help='密码子命令')
|
||||
@@ -188,6 +211,32 @@ def main():
|
||||
f.write(result)
|
||||
print(f'控制流扁平化完成: {output_path}')
|
||||
|
||||
elif args.command == 'protect':
|
||||
output = obfuscate_file_full(
|
||||
args.input,
|
||||
args.output,
|
||||
key=args.key,
|
||||
level=args.level,
|
||||
anti_crawl=not args.no_anti_crawl
|
||||
)
|
||||
level_names = {1: '基础', 2: '中等', 3: '高级'}
|
||||
print(f'保护完成 (级别: {level_names[args.level]}): {output}')
|
||||
|
||||
elif args.command == 'anti-debug':
|
||||
code = generate_full_protection(
|
||||
anti_debug=True,
|
||||
disable_shortcuts=args.disable_shortcuts,
|
||||
console_clear=args.console_clear,
|
||||
domain_lock=args.domain,
|
||||
expire_date=args.expire
|
||||
)
|
||||
if args.output:
|
||||
with open(args.output, 'w', encoding='utf-8') as f:
|
||||
f.write(code)
|
||||
print(f'反调试代码已生成: {args.output}')
|
||||
else:
|
||||
print(code)
|
||||
|
||||
elif args.command == 'password':
|
||||
if args.pwd_command == 'hash':
|
||||
hashed = hash_password(args.password, iterations=args.iterations)
|
||||
|
||||
Reference in New Issue
Block a user