1
1
// See https://github.com/tsarpaul/llvm-string-obfuscator
2
2
// for a more detailed explanation.
3
3
4
- use either:: Either ;
5
-
6
4
use llvm_plugin:: inkwell:: basic_block:: BasicBlock ;
7
5
use llvm_plugin:: inkwell:: module:: { Linkage , Module } ;
8
6
use llvm_plugin:: inkwell:: values:: { BasicValueEnum , FunctionValue , GlobalValue } ;
@@ -42,7 +40,7 @@ impl LlvmModulePass for StringObfuscatorModPass {
42
40
let cx = module. get_context ( ) ;
43
41
let builder = cx. create_builder ( ) ;
44
42
builder. position_before ( & instr) ;
45
- builder. build_call ( decode_stub, & [ ] , "" ) ;
43
+ builder. build_call ( decode_stub, & [ ] , "" ) . unwrap ( ) ;
46
44
} ;
47
45
48
46
PreservedAnalyses :: None
@@ -81,13 +79,9 @@ fn encode_global_strings<'a>(module: &mut Module<'a>) -> Vec<GlobalString<'a>> {
81
79
global_strings. push ( GlobalString :: Array ( global, encoded_str. len ( ) as u32 ) ) ;
82
80
}
83
81
// Rust-like strings
84
- Some ( BasicValueEnum :: StructValue ( stru) ) if stru. get_num_operands ( ) <= 1 => {
85
- let arr = match stru. get_operand ( 0 ) {
86
- Some ( Either :: Left ( BasicValueEnum :: ArrayValue ( arr) ) )
87
- if arr. is_const_string ( ) =>
88
- {
89
- arr
90
- }
82
+ Some ( BasicValueEnum :: StructValue ( stru) ) if stru. count_fields ( ) <= 1 => {
83
+ let arr = match stru. get_field_at_index ( 0 ) {
84
+ Some ( BasicValueEnum :: ArrayValue ( arr) ) if arr. is_const_string ( ) => arr,
91
85
_ => continue ,
92
86
} ;
93
87
let encoded_str = match arr. get_string_constant ( ) {
@@ -99,7 +93,7 @@ fn encode_global_strings<'a>(module: &mut Module<'a>) -> Vec<GlobalString<'a>> {
99
93
None => continue ,
100
94
} ;
101
95
let new_const = cx. const_string ( & encoded_str, false ) ;
102
- stru. set_operand ( 0 , new_const) ;
96
+ stru. set_field_at_index ( 0 , new_const) ;
103
97
global. set_constant ( false ) ;
104
98
global_strings. push ( GlobalString :: Struct ( global, 0 , encoded_str. len ( ) as u32 ) ) ;
105
99
}
@@ -129,61 +123,83 @@ fn create_decode_fn<'a>(module: &mut Module<'a>) -> FunctionValue<'a> {
129
123
let arg1 = decode_fn. get_nth_param ( 0 ) . unwrap ( ) ;
130
124
let arg2 = decode_fn. get_nth_param ( 1 ) . unwrap ( ) ;
131
125
132
- let var3 = builder. build_is_not_null ( arg1. into_pointer_value ( ) , "" ) ;
133
- let var4 = builder. build_int_compare (
134
- IntPredicate :: SGT ,
135
- arg2. into_int_value ( ) ,
136
- cx. i32_type ( ) . const_zero ( ) ,
137
- "" ,
138
- ) ;
139
- let var5 = builder. build_and ( var4, var3, "" ) ;
126
+ let var3 = builder
127
+ . build_is_not_null ( arg1. into_pointer_value ( ) , "" )
128
+ . unwrap ( ) ;
129
+ let var4 = builder
130
+ . build_int_compare (
131
+ IntPredicate :: SGT ,
132
+ arg2. into_int_value ( ) ,
133
+ cx. i32_type ( ) . const_zero ( ) ,
134
+ "" ,
135
+ )
136
+ . unwrap ( ) ;
137
+ let var5 = builder. build_and ( var4, var3, "" ) . unwrap ( ) ;
140
138
141
139
let loop_body_bb = cx. append_basic_block ( decode_fn, "" ) ;
142
140
let end_bb = cx. append_basic_block ( decode_fn, "" ) ;
143
- builder. build_conditional_branch ( var5, loop_body_bb, end_bb) ;
141
+ builder
142
+ . build_conditional_branch ( var5, loop_body_bb, end_bb)
143
+ . unwrap ( ) ;
144
144
145
145
builder. position_at_end ( loop_body_bb) ;
146
- let phi1 = builder. build_phi ( cx. i8_type ( ) . ptr_type ( AddressSpace :: default ( ) ) , "" ) ;
147
- let phi2 = builder. build_phi ( cx. i32_type ( ) , "" ) ;
148
- let var9 = builder. build_int_nsw_add (
149
- phi2. as_basic_value ( ) . into_int_value ( ) ,
150
- cx. i32_type ( ) . const_all_ones ( ) ,
151
- "" ,
152
- ) ;
153
- #[ cfg( not( any( feature = "llvm15-0" , feature = "llvm16-0" ) ) ) ]
146
+ let phi1 = builder
147
+ . build_phi ( cx. i8_type ( ) . ptr_type ( AddressSpace :: default ( ) ) , "" )
148
+ . unwrap ( ) ;
149
+ let phi2 = builder. build_phi ( cx. i32_type ( ) , "" ) . unwrap ( ) ;
150
+ let var9 = builder
151
+ . build_int_nsw_add (
152
+ phi2. as_basic_value ( ) . into_int_value ( ) ,
153
+ cx. i32_type ( ) . const_all_ones ( ) ,
154
+ "" ,
155
+ )
156
+ . unwrap ( ) ;
157
+ #[ cfg( not( any( feature = "llvm15-0" , feature = "llvm16-0" , feature = "llvm17-0" ) ) ) ]
154
158
let var10 = unsafe {
155
159
builder. build_gep (
156
160
phi1. as_basic_value ( ) . into_pointer_value ( ) ,
157
161
& [ cx. i64_type ( ) . const_int ( 1 , false ) ] ,
158
162
"" ,
159
163
)
160
- } ;
161
- #[ cfg( any( feature = "llvm15-0" , feature = "llvm16-0" ) ) ]
164
+ }
165
+ . unwrap ( ) ;
166
+ #[ cfg( any( feature = "llvm15-0" , feature = "llvm16-0" , feature = "llvm17-0" ) ) ]
162
167
let var10 = unsafe {
163
168
builder. build_gep (
164
169
cx. i8_type ( ) ,
165
170
phi1. as_basic_value ( ) . into_pointer_value ( ) ,
166
171
& [ cx. i64_type ( ) . const_int ( 1 , false ) ] ,
167
172
"" ,
168
173
)
169
- } ;
170
- #[ cfg( not( any( feature = "llvm15-0" , feature = "llvm16-0" ) ) ) ]
174
+ }
175
+ . unwrap ( ) ;
176
+ #[ cfg( not( any( feature = "llvm15-0" , feature = "llvm16-0" , feature = "llvm17-0" ) ) ) ]
171
177
let var11 = builder. build_load ( phi1. as_basic_value ( ) . into_pointer_value ( ) , "" ) ;
172
- #[ cfg( any( feature = "llvm15-0" , feature = "llvm16-0" ) ) ]
173
- let var11 = builder. build_load ( cx. i8_type ( ) , phi1. as_basic_value ( ) . into_pointer_value ( ) , "" ) ;
174
- let var12 = builder. build_int_add ( var11. into_int_value ( ) , cx. i8_type ( ) . const_all_ones ( ) , "" ) ;
175
- builder. build_store ( phi1. as_basic_value ( ) . into_pointer_value ( ) , var12) ;
176
- let var13 = builder. build_int_compare (
177
- IntPredicate :: SGT ,
178
- phi2. as_basic_value ( ) . into_int_value ( ) ,
179
- cx. i32_type ( ) . const_int ( 1 , false ) ,
180
- "" ,
181
- ) ;
182
-
183
- builder. build_conditional_branch ( var13, loop_body_bb, end_bb) ;
178
+ #[ cfg( any( feature = "llvm15-0" , feature = "llvm16-0" , feature = "llvm17-0" ) ) ]
179
+ let var11 = builder
180
+ . build_load ( cx. i8_type ( ) , phi1. as_basic_value ( ) . into_pointer_value ( ) , "" )
181
+ . unwrap ( ) ;
182
+ let var12 = builder
183
+ . build_int_add ( var11. into_int_value ( ) , cx. i8_type ( ) . const_all_ones ( ) , "" )
184
+ . unwrap ( ) ;
185
+ builder
186
+ . build_store ( phi1. as_basic_value ( ) . into_pointer_value ( ) , var12)
187
+ . unwrap ( ) ;
188
+ let var13 = builder
189
+ . build_int_compare (
190
+ IntPredicate :: SGT ,
191
+ phi2. as_basic_value ( ) . into_int_value ( ) ,
192
+ cx. i32_type ( ) . const_int ( 1 , false ) ,
193
+ "" ,
194
+ )
195
+ . unwrap ( ) ;
196
+
197
+ builder
198
+ . build_conditional_branch ( var13, loop_body_bb, end_bb)
199
+ . unwrap ( ) ;
184
200
185
201
builder. position_at_end ( end_bb) ;
186
- builder. build_return ( None ) ;
202
+ builder. build_return ( None ) . unwrap ( ) ;
187
203
phi1. add_incoming ( & [ ( & var10, loop_body_bb) , ( & arg1, start_bb) ] ) ;
188
204
phi2. add_incoming ( & [ ( & var9, loop_body_bb) , ( & arg2, start_bb) ] ) ;
189
205
@@ -206,38 +222,40 @@ fn create_decode_stub<'a>(
206
222
for globstr in global_strings {
207
223
let ( s, len) = match globstr {
208
224
GlobalString :: Array ( gs, len) => {
209
- let s = builder. build_pointer_cast (
210
- gs. as_pointer_value ( ) ,
211
- cx. i8_type ( ) . ptr_type ( AddressSpace :: default ( ) ) ,
212
- "" ,
213
- ) ;
225
+ let s = builder
226
+ . build_pointer_cast (
227
+ gs. as_pointer_value ( ) ,
228
+ cx. i8_type ( ) . ptr_type ( AddressSpace :: default ( ) ) ,
229
+ "" ,
230
+ )
231
+ . unwrap ( ) ;
214
232
( s, len)
215
233
}
216
234
GlobalString :: Struct ( gs, id, len) => {
217
- #[ cfg( not( any( feature = "llvm15-0" , feature = "llvm16-0" ) ) ) ]
235
+ #[ cfg( not( any( feature = "llvm15-0" , feature = "llvm16-0" , feature = "llvm17-0" ) ) ) ]
218
236
let s = builder
219
237
. build_struct_gep ( gs. as_pointer_value ( ) , id, "" )
220
238
. unwrap ( ) ;
221
- #[ cfg( any( feature = "llvm15-0" , feature = "llvm16-0" ) ) ]
239
+ #[ cfg( any( feature = "llvm15-0" , feature = "llvm16-0" , feature = "llvm17-0" ) ) ]
222
240
let s = {
223
241
let i8_ty_ptr = cx. i8_type ( ) . ptr_type ( AddressSpace :: default ( ) ) ;
224
242
let struct_ty = cx. struct_type ( & [ i8_ty_ptr. into ( ) ] , false ) ;
225
243
builder
226
244
. build_struct_gep ( struct_ty, gs. as_pointer_value ( ) , id, "" )
227
245
. unwrap ( )
228
246
} ;
229
- let s = builder. build_pointer_cast (
230
- s,
231
- cx. i8_type ( ) . ptr_type ( AddressSpace :: default ( ) ) ,
232
- "" ,
233
- ) ;
247
+ let s = builder
248
+ . build_pointer_cast ( s, cx. i8_type ( ) . ptr_type ( AddressSpace :: default ( ) ) , "" )
249
+ . unwrap ( ) ;
234
250
( s, len)
235
251
}
236
252
} ;
237
253
let len = cx. i32_type ( ) . const_int ( len as u64 , false ) ;
238
- builder. build_call ( decode_fn, & [ s. into ( ) , len. into ( ) ] , "" ) ;
254
+ builder
255
+ . build_call ( decode_fn, & [ s. into ( ) , len. into ( ) ] , "" )
256
+ . unwrap ( ) ;
239
257
}
240
258
241
- builder. build_return ( None ) ;
259
+ builder. build_return ( None ) . unwrap ( ) ;
242
260
decode_stub
243
261
}
0 commit comments