函数是二进制分析的基本单位,函数匹配是二进制diff的核心任务。
2.1.1 基于签名匹配 #
函数哈希签名 #
基本原理: 为每个函数计算唯一哈希值,通过哈希匹配识别相同函数。
def compute_function_hash(func):
"""
计算函数哈希
"""
# 提取函数特征
features = []
# 1. 操作码序列
opcodes = [insn.mnemonic for insn in func.instructions]
features.append(' '.join(opcodes))
# 2. 常量值
constants = extract_constants(func)
features.extend(constants)
# 3. 调用目标
calls = [callee.name for callee in func.calls]
features.extend(calls)
# 计算哈希
feature_str = '|'.join(str(f) for f in features)
return hashlib.md5(feature_str.encode()).hexdigest()Python优缺点:
| 优点 | 缺点 |
| 计算速度快 | 对编译差异敏感 |
| 实现简单 | 无法处理代码变形 |
| 适合精确匹配 | 混淆后失效 |
模糊哈希(Fuzzy Hashing) #
传统哈希:
输入: "Hello World" → MD5: b10a8db164e07541...
输入: "Hello World!" → MD5: ed076287532e8636... (完全不同)
模糊哈希:
输入: "Hello World" → 3:AXaXaXa:AXaXaXa
输入: "Hello World!" → 3:AXaXaXb:AXaXaXb (相似)
def compute_fuzzy_function_hash(func):
"""
使用SSDEEP计算函数模糊哈希
"""
normalized = normalize_function(func)
return ssdeep.hash(normalized)
def compare_functions_fuzzy(hash1, hash2):
"""
比较两个模糊哈希的相似度
返回: 0-100的相似度分数
"""
return ssdeep.compare(hash1, hash2)PythonSimHash算法 #
SimHash是一种局部敏感哈希(LSH),特别适合检测近似重复。
SimHash计算过程
│
▼
┌───────────────────────────────────────┐
│ 1. 分词 (Tokenization) │
│ func → ['push', 'mov', 'add', ...] │
│ │
│ 2. 哈希每个token │
│ 'push' → 10110101... │
│ │
│ 3. 加权向量累加 │
│ 位1: +1, 位0: -1 │
│ │
│ 4. 降维生成指纹 │
│ 正→1, 负→0 │
│ 最终: 11001010... │
└───────────────────────────────────────┘
import hashlib
def simhash(tokens, hash_bits=64):
"""
计算SimHash指纹
"""
v = [0] * hash_bits
for token in tokens:
h = int(hashlib.md5(token.encode()).hexdigest(), 16)
for i in range(hash_bits):
bit = (h >> i) & 1
v[i] += 1 if bit else -1
fingerprint = 0
for i in range(hash_bits):
if v[i] > 0:
fingerprint |= (1 << i)
return fingerprint
def hamming_distance(h1, h2):
"""计算汉明距离"""
return bin(h1 ^ h2).count('1')
def similarity(h1, h2, hash_bits=64):
"""计算相似度"""
return 1 - hamming_distance(h1, h2) / hash_bitsPython