代码混淆定义:
原代码 P 通过某种变换变成代码 P’,若 P 和 P’运行结果与过程行为保持一致,该种变换就称之为混淆变换。
具体来说,当混淆转换满足以下两种情况时,这种混淆变化称之为合法的转换:
(1)如果源程序 P 无法停止运行或报错结束运行,则变换后的程序 P’可以结束运行也可以继续运行。
(2)否则,目标程序 P’也结束运行并且输出与源程序相同的结果。
两个程序之间操作并不一定完全相同,且不一定有相同的效率。
实际上,混淆工具预先设定若干混淆规则,并使用其它更为复杂的代码取代源代码中符合条件的代码语句,虽然源代码语义并未改变但混淆后的程序运行过程中空间复杂度往往更高,执行时间也更长,甚至有可能改变系统环境等。
图 2.1 展示了混淆编译的整体流程,
首先混淆工具会对输入的源代码进行代码预处理得到程序控制流图 CFG、抽象语法树 AST 等信息,
然后对数据流、控制流等进行分析,并根据输入的混淆参数选择对应的混淆算法处理源代码,
最后输出混淆编译后的程序。
尽管混淆策略多种多样,但通常按 Collberg 提出的方法将其大致分为四类[16]:
布局混淆
数据流混淆
...
C/C++
未读创建一个匿名函数并执行。Objective-C采用的是上尖号^,而C++ 11采用的是配对的方括号[]。实例如下:
12345678#include <iostream>using namespace std;int main(){ []{ cout << "Hello,Worldn"; }();}
我们也可以方便的将这个创建的匿名函数赋值出来调用:
12345678910#include <iostream>using namespace std;int main(){ int i = 1024; auto func = [](int i) { // (int i) 是指传入改匿名函数的参数 cout << i; }; func(i);}
捕获选项
[] Capture nothing (or, a scorched earth strategy?)
[&] Ca ...