1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
//! 難読化設定(ObfuscationConfig)
//!
//! 各難読化パスの有効/無効およびパラメータを管理する。
//! `--fobfuscate` と `--obf-level=N` で制御する。
//! 全16パス(TACKY IR 11パス + ASM 5パス)。
//! Pass 16(OPSEC)はシンボルリネーム + 文字列リーク検出 + シンボル Strip + バイナリ監査。
//! `--opsec-policy=warn|deny` で違反時の動作を制御(deny = fail-closed)。
/// OPSEC ポリシー: 違反時の動作を制御する。
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum OpsecPolicy {
/// 警告のみ(コンパイルは続行)
Warn,
/// コンパイルを失敗させる(fail-closed)
Deny,
}
/// 難読化パスの設定。パイプライン全体で共有される。
#[derive(Debug, Clone)]
pub struct ObfuscationConfig {
// ── パス有効/無効 ──
/// Pass 1 (TACKY): 定数の間接化(即値を a*b+c に分解)
pub constant_encoding: bool,
/// Pass 2 (TACKY): 算術置換(Add/Subtract を多段計算に展開)
pub arith_subst: bool,
/// Pass 3 (TACKY): ジャンクコード挿入
pub junk_code: bool,
/// Pass 4 (TACKY): 不透明述語
pub opaque_predicates: bool,
/// Pass 5 (TACKY): 制御フロー平坦化
pub cff: bool,
/// Pass 6 (TACKY): 文字列暗号化
pub string_encryption: bool,
/// Pass 7 (ASM): 反逆アセンブリ(ゴミバイト挿入)
pub anti_disassembly: bool,
/// Pass 8 (ASM): 関数呼び出しの間接化
pub indirect_calls: bool,
/// Pass 9 (ASM): レジスタシャッフル(dead mov 挿入)
pub reg_shuffle: bool,
/// Pass 10 (ASM): スタックフレーム難読化(偽スタックスロット挿入)
pub stack_frame_obf: bool,
/// Pass 11 (ASM): 命令置換(同等命令列への置換)
pub instr_subst: bool,
/// Pass 12 (TACKY): 関数インライン展開
pub func_inline: bool,
/// Pass 13 (TACKY): 関数アウトライン化
pub func_outline: bool,
/// Pass 14 (TACKY): VM仮想化(コード仮想化)
pub vm_virtualize: bool,
/// Pass 15 (TACKY): ライブラリ関数難読化
pub lib_obfuscate: bool,
/// Pass 16 (TACKY): OPSEC 衛生化(シンボルリネーム)
pub opsec: bool,
/// OPSEC 文字列リーク警告
pub opsec_warn: bool,
/// OPSEC シンボル strip(.globl 抑制 + バイナリ strip)
pub opsec_strip: bool,
/// OPSEC ポリシー(Warn=警告のみ, Deny=コンパイル失敗)
pub opsec_policy: OpsecPolicy,
/// リンク後バイナリの OPSEC 監査
pub opsec_audit: bool,
/// Multi-file: global シンボルを OPSEC リネームから保護する
pub preserve_globals: bool,
// ── 頻度パラメータ ──
/// ジャンクコード挿入頻度(N命令ごとに挿入)
pub junk_freq: usize,
/// 不透明述語頻度(N個の値生成命令ごとに適用)
pub pred_freq: usize,
// ── CFF パラメータ ──
/// 状態エンコード乗数 (encoded = index * cff_a + cff_b)
pub cff_a: i32,
/// 状態エンコードバイアス
pub cff_b: i32,
/// 算術置換頻度(N回に1回適用)
pub arith_freq: usize,
/// レジスタシャッフル頻度(N命令ごとに挿入)
pub reg_shuffle_freq: usize,
/// 偽スタックスロット数
pub stack_frame_padding: usize,
/// 偽スタック操作の挿入頻度(N命令ごと)
pub stack_frame_fake_freq: usize,
/// 命令置換頻度(N命令ごと)
pub instr_subst_freq: usize,
/// インライン展開頻度(N回の適格呼び出しごとにインライン化)
pub func_inline_freq: usize,
/// アウトライン化の最小ブロックサイズ
pub func_outline_min_block: usize,
// ── 文字列暗号化パラメータ ──
/// 暗号化キー(加算ベース)
pub string_key: u8,
}
impl ObfuscationConfig {
/// レベルに応じたプリセット設定を生成する。
///
/// | Level | 概要 |
/// |-------|------|
/// | 1 | 軽量: 定数+ジャンク+述語のみ、低頻度 |
/// | 2 | 標準: +CFF+算術置換 |
/// | 3 | 強力: 全14パス有効(VM仮想化除く) |
/// | 4 | 最大: 全15パス有効、高頻度 |
pub fn from_level(level: u8) -> Self {
match level {
1 => ObfuscationConfig {
constant_encoding: true,
arith_subst: false,
junk_code: true,
opaque_predicates: true,
cff: false,
string_encryption: false,
anti_disassembly: false,
indirect_calls: false,
reg_shuffle: false,
stack_frame_obf: false,
instr_subst: false,
func_inline: false,
func_outline: false,
vm_virtualize: false,
lib_obfuscate: true,
opsec: false,
opsec_warn: false,
opsec_strip: false,
opsec_policy: OpsecPolicy::Warn,
opsec_audit: false,
preserve_globals: false,
junk_freq: 8,
pred_freq: 10,
arith_freq: 3,
reg_shuffle_freq: 5,
stack_frame_padding: 4,
stack_frame_fake_freq: 8,
instr_subst_freq: 4,
func_inline_freq: 3,
func_outline_min_block: 4,
cff_a: 37,
cff_b: 0xCAFE,
string_key: 0x5A,
},
2 => ObfuscationConfig {
constant_encoding: true,
arith_subst: true,
junk_code: true,
opaque_predicates: true,
cff: true,
string_encryption: false,
anti_disassembly: false,
indirect_calls: false,
reg_shuffle: false,
stack_frame_obf: false,
instr_subst: false,
func_inline: false,
func_outline: false,
vm_virtualize: false,
lib_obfuscate: true,
opsec: false,
opsec_warn: true,
opsec_strip: false,
opsec_policy: OpsecPolicy::Warn,
opsec_audit: false,
preserve_globals: false,
junk_freq: 4,
pred_freq: 5,
arith_freq: 5,
reg_shuffle_freq: 5,
stack_frame_padding: 4,
stack_frame_fake_freq: 8,
instr_subst_freq: 4,
func_inline_freq: 3,
func_outline_min_block: 4,
cff_a: 37,
cff_b: 0xCAFE,
string_key: 0x5A,
},
3 => ObfuscationConfig {
constant_encoding: true,
arith_subst: true,
junk_code: true,
opaque_predicates: true,
cff: true,
string_encryption: true,
anti_disassembly: true,
indirect_calls: true,
reg_shuffle: true,
stack_frame_obf: true,
instr_subst: true,
func_inline: true,
func_outline: true,
vm_virtualize: false,
lib_obfuscate: true,
opsec: true,
opsec_warn: true,
opsec_strip: true,
opsec_policy: OpsecPolicy::Warn,
opsec_audit: false,
preserve_globals: false,
junk_freq: 4,
pred_freq: 5,
arith_freq: 3,
reg_shuffle_freq: 5,
stack_frame_padding: 4,
stack_frame_fake_freq: 8,
instr_subst_freq: 4,
func_inline_freq: 3,
func_outline_min_block: 4,
cff_a: 37,
cff_b: 0xCAFE,
string_key: 0x5A,
},
// level >= 4: 最大
_ => ObfuscationConfig {
constant_encoding: true,
arith_subst: true,
junk_code: true,
opaque_predicates: true,
cff: true,
string_encryption: true,
anti_disassembly: true,
indirect_calls: true,
reg_shuffle: true,
stack_frame_obf: true,
instr_subst: true,
func_inline: true,
func_outline: true,
vm_virtualize: true,
lib_obfuscate: true,
opsec: true,
opsec_warn: true,
opsec_strip: true,
opsec_policy: OpsecPolicy::Warn,
opsec_audit: false,
preserve_globals: false,
junk_freq: 2,
pred_freq: 2,
arith_freq: 2,
reg_shuffle_freq: 3,
stack_frame_padding: 8,
stack_frame_fake_freq: 4,
instr_subst_freq: 2,
func_inline_freq: 2,
func_outline_min_block: 3,
cff_a: 37,
cff_b: 0xCAFE,
string_key: 0x5A,
},
}
}
/// 現在のデフォルト設定(Level 3 相当 = 従来の --fobfuscate と同等)
#[allow(dead_code)]
pub fn default_all() -> Self {
Self::from_level(3)
}
}