在做 iOS 混淆(尤其是符号混淆)时,一个很现实的问题是:
❗ 混淆词库要“像人写的”,但又不能重复、不能被特征识别
很多项目一开始用的是:
- 随机字符串(
a1b2c3❌) - 固定词表(很快被识别 ❌)
- 手写词库(维护成本极高 ❌)
更好的方案是:
✅ 自动从 GitHub 抓真实项目命名 → 清洗 → 构建混淆词库 → 定期更新
这篇文章就讲清楚一套完整落地方案。
一、整体架构
先看结构(核心流程):
GitHub API / 仓库爬取
↓
代码解析(提取函数名 / 类名 / 变量名)
↓
命名清洗(过滤无效 / 垃圾命名)
↓
词库存储(本地 JSON / DB)
↓
混淆工具使用
↓
定时任务更新(cron)
二、GitHub 数据获取(核心)
1. 使用 GitHub API(推荐)
GitHub 提供搜索 API:
https://api.github.com/search/repositories?q=language:Objective-C&sort=stars
获取热门项目,然后进一步拉代码:
https://api.github.com/repos/{owner}/{repo}/contents/
Python 示例
import requests
GITHUB_TOKEN = "your_token"
headers = {
"Authorization": f"token {GITHUB_TOKEN}"
}
def get_repos():
url = "https://api.github.com/search/repositories"
params = {
"q": "language:Objective-C",
"sort": "stars",
"per_page": 10
}
return requests.get(url, headers=headers, params=params).json()
def get_repo_files(owner, repo):
url = f"https://api.github.com/repos/{owner}/{repo}/git/trees/main?recursive=1"
return requests.get(url, headers=headers).json()
2. 直接 clone(更稳定)
git clone --depth=1 https://github.com/xxx/xxx.git
优点:
- 不受 API 限制
- 可本地批量处理
三、命名提取(重点)
目标:提取“像人写的命名”
1. 提取 Objective-C / Swift 符号
Objective-C
[A-Za-z_][A-Za-z0-9_]+
更精准一点:
[-+]\s*\([^)]+\)\s*([A-Za-z_][A-Za-z0-9_]*)
提取方法名:
- (void)loadUserData;
得到:
loadUserData
Swift
func\s+([A-Za-z_][A-Za-z0-9_]*)
class\s+([A-Za-z_][A-Za-z0-9_]*)
2. Python 解析示例
import re
def extract_names(code):
patterns = [
r'func\s+([A-Za-z_][A-Za-z0-9_]*)',
r'class\s+([A-Za-z_][A-Za-z0-9_]*)',
r'[-+]\s*\([^)]+\)\s*([A-Za-z_][A-Za-z0-9_]*)'
]
names = []
for p in patterns:
names += re.findall(p, code)
return names
四、词库清洗(关键)
直接抓下来的数据是“脏的”,必须过滤。
1. 过滤规则
❌ 无意义命名
tmp
test
aaa
bbb
foo
bar
❌ 太短
长度 < 3
❌ 系统 API(避免冲突)
viewDidLoad
init
dealloc
2. 语义过滤(推荐)
可以用简单规则:
def is_valid(name):
if len(name) < 3:
return False
blacklist = ["test", "tmp", "aaa", "demo"]
if name.lower() in blacklist:
return False
if name.startswith("_"):
return False
return True
3. 命名风格分类(提升真实度)
将词库分为:
| 类型 | 示例 |
|---|---|
| 动词 | load, fetch, update |
| 名词 | user, config |
| 组合 | loadUserData |
后续混淆可以组合生成:
random.choice(verbs) + random.choice(nouns)
五、词库存储设计
推荐 JSON:
{
"class": ["UserManager", "NetworkService"],
"method": ["loadUserData", "fetchConfig"],
"property": ["userName", "isEnabled"]
}
六、混淆工具接入
生成 mapping:
original_symbol -> new_symbol
示例:
loginUser -> fetchAccountInfo
getData -> loadConfig
生成代码
import random
def generate_mapping(symbols, word_pool):
mapping = {}
for s in symbols:
mapping[s] = random.choice(word_pool)
return mapping
七、定期更新机制(核心价值)
如果词库不更新,很容易被识别。
1. 使用 cron
0 3 * * * python update_dict.py
每天凌晨更新:
- 拉新 repo
- 更新词库
- 去重
- 覆盖旧词库
2. 增量更新策略
避免全量重建:
old_set = set(old_words)
new_set = set(new_words)
merged = old_set.union(new_set)
3. 版本控制(推荐)
dict_v1.json
dict_v2.json
方便回滚:
git diff
八、优化点(实战经验)
1. 避免重复
used_words = set()
def get_unique_word(pool):
while True:
w = random.choice(pool)
if w not in used_words:
used_words.add(w)
return w
2. 加入“行业词”
比如:
- 网络:request / response
- UI:layout / render
- 数据:cache / storage
提升“真实性”
3. 混合策略(推荐)
真实词库 + 自生成组合
例如:
fetch + Manager → fetchManager
九、效果对比
❌ 随机字符串
aB3xYz
✅ GitHub词库
loadUserProfile
updateCachePolicy
fetchNetworkConfig
差异非常明显:
✔ 更像真实代码
✔ 更难被规则识别
✔ 更符合逆向干扰目标
274

被折叠的 条评论
为什么被折叠?



