Obfuscation/rename_doxygen.py

114 lines
4.1 KiB
Python
Raw Permalink 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.

import os
import re
import subprocess
import random
import string
import sys
# ========== 配置区域 ==========
# Doxygen 源码根目录(包含源码的路径)
SOURCE_ROOT = './' # 你放源码的路径比如克隆的doxygen源码根目录
# 编译数据库路径compile_commands.json所在目录
BUILD_PATH = './build'
# clang-rename 可执行文件路径根据brew或自定义安装路径调整
CLANG_RENAME_PATH = '/usr/local/opt/llvm/bin/clang-rename'
# 支持的源码文件后缀
SOURCE_EXTENSIONS = ['.cpp', '.c', '.h', '.hpp', '.cc']
# 是否实际执行clang-renameTrue执行False只打印模拟
EXECUTE_RENAME = True
# ======== 混淆名生成 ========
def generate_random_name(length=8):
# 生成随机字母数字串,比如 A1b2C3d4
letters_and_digits = string.ascii_letters + string.digits
return ''.join(random.choice(letters_and_digits) for _ in range(length))
# ======== 扫描源码符号(示例仅提取函数和类名)========
def scan_symbols(source_root):
symbols = set()
function_pattern = re.compile(r'\b(?:class|struct|void|int|bool|char|float|double|unsigned|static|virtual|inline|constexpr|auto)\s+([a-zA-Z_]\w*)\s*\(')
class_pattern = re.compile(r'\b(class|struct)\s+([a-zA-Z_]\w*)')
variable_pattern = re.compile(r'\b(?:int|bool|char|float|double|unsigned|auto|static|constexpr)\s+([a-zA-Z_]\w*)\b')
for root, dirs, files in os.walk(source_root):
for file in files:
if any(file.endswith(ext) for ext in SOURCE_EXTENSIONS):
path = os.path.join(root, file)
try:
with open(path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
# 提取类名
for match in class_pattern.finditer(content):
symbols.add(match.group(2))
# 提取函数名
for match in function_pattern.finditer(content):
symbols.add(match.group(1))
# 提取变量名(谨慎,容易误报)
# for match in variable_pattern.finditer(content):
# symbols.add(match.group(1))
except Exception as e:
print(f"读取文件失败 {path}: {e}", file=sys.stderr)
# 过滤 C++ 关键字和常见函数名(简单示例)
keywords = {'if','for','while','switch','return','else','class','struct','static','void','int','bool','char','float','double','unsigned','auto','constexpr','inline','virtual','main'}
symbols = {s for s in symbols if s not in keywords and len(s) > 2}
return symbols
# ======== 调用 clang-rename 重命名 ========
def run_clang_rename(old_name, new_name):
print(f'[*] Renaming {old_name} -> {new_name}')
if not EXECUTE_RENAME:
print(f'(模拟) clang-rename -p {BUILD_PATH} -old-name={old_name} -new-name={new_name}')
return
try:
subprocess.run([
CLANG_RENAME_PATH,
f'-p={BUILD_PATH}',
f'-old-name={old_name}',
f'-new-name={new_name}'
], check=True)
except subprocess.CalledProcessError as e:
print(f'[错误] 重命名 {old_name}{new_name} 失败: {e}', file=sys.stderr)
def main():
print('[*] 扫描源码符号...')
symbols = scan_symbols(SOURCE_ROOT)
print(f'[+] 共发现 {len(symbols)} 个符号')
# 手动排除或者白名单防止混淆关键API可自行扩展
exclude_symbols = {
'main', 'printf', 'fprintf', 'exit',
'Doxygen', 'Config', 'Parser', 'run', 'Error',
# 可以加入更多Doxygen项目的核心接口名
}
symbols = [s for s in symbols if s not in exclude_symbols]
print(f'[+] 过滤后准备混淆 {len(symbols)} 个符号')
# 构建映射:旧名 -> 新名
rename_map = {}
for s in symbols:
new_name = generate_random_name(10)
rename_map[s] = new_name
# 逐个重命名
for old_name, new_name in rename_map.items():
run_clang_rename(old_name, new_name)
print('[*] 混淆完成')
if __name__ == '__main__':
main()