@@ -31,7 +31,7 @@ use libafl_bolts::{
31
31
use libafl_qemu:: {
32
32
elf:: EasyElf ,
33
33
modules:: { drcov:: DrCovModule , StdAddressFilter } ,
34
- ArchExtras , CallingConvention , Emulator , GuestAddr , GuestReg , MmapPerms , Qemu , QemuExecutor ,
34
+ ArchExtras , CallingConvention , Emulator , GuestAddr , GuestReg , MmapPerms , QemuExecutor ,
35
35
QemuExitReason , QemuRWError , QemuShutdownCause , Regs ,
36
36
} ;
37
37
@@ -123,80 +123,93 @@ pub fn fuzz() {
123
123
124
124
env:: remove_var ( "LD_LIBRARY_PATH" ) ;
125
125
126
- let qemu = Qemu :: init ( & options. args ) . unwrap ( ) ;
127
-
128
- let mut elf_buffer = Vec :: new ( ) ;
129
- let elf = EasyElf :: from_file ( qemu. binary_path ( ) , & mut elf_buffer) . unwrap ( ) ;
130
-
131
- let test_one_input_ptr = elf
132
- . resolve_symbol ( "LLVMFuzzerTestOneInput" , qemu. load_addr ( ) )
133
- . expect ( "Symbol LLVMFuzzerTestOneInput not found" ) ;
134
- log:: debug!( "LLVMFuzzerTestOneInput @ {test_one_input_ptr:#x}" ) ;
126
+ let mut run_client = |state : Option < _ > ,
127
+ mut mgr : LlmpRestartingEventManager < _ , _ , _ > ,
128
+ client_description : ClientDescription | {
129
+ let mut cov_path = options. coverage_path . clone ( ) ;
135
130
136
- qemu. entry_break ( test_one_input_ptr) ;
131
+ let emulator_modules = tuple_list ! ( DrCovModule :: builder( )
132
+ . filter( StdAddressFilter :: default ( ) )
133
+ . filename( cov_path. clone( ) )
134
+ . full_trace( false )
135
+ . build( ) ) ;
137
136
138
- for m in qemu. mappings ( ) {
139
- log:: debug!(
140
- "Mapping: 0x{:016x}-0x{:016x}, {}" ,
141
- m. start( ) ,
142
- m. end( ) ,
143
- m. path( ) . unwrap_or( & "<EMPTY>" . to_string( ) )
144
- ) ;
145
- }
137
+ let emulator = Emulator :: empty ( )
138
+ . qemu_parameters ( options. args . clone ( ) )
139
+ . modules ( emulator_modules)
140
+ . build ( )
141
+ . expect ( "QEMU initialization failed" ) ;
142
+ let qemu = emulator. qemu ( ) ;
143
+
144
+ let mut elf_buffer = Vec :: new ( ) ;
145
+ let elf = EasyElf :: from_file ( qemu. binary_path ( ) , & mut elf_buffer) . unwrap ( ) ;
146
+
147
+ let test_one_input_ptr = elf
148
+ . resolve_symbol ( "LLVMFuzzerTestOneInput" , qemu. load_addr ( ) )
149
+ . expect ( "Symbol LLVMFuzzerTestOneInput not found" ) ;
150
+ log:: debug!( "LLVMFuzzerTestOneInput @ {test_one_input_ptr:#x}" ) ;
151
+
152
+ qemu. entry_break ( test_one_input_ptr) ;
153
+
154
+ for m in qemu. mappings ( ) {
155
+ log:: debug!(
156
+ "Mapping: 0x{:016x}-0x{:016x}, {}" ,
157
+ m. start( ) ,
158
+ m. end( ) ,
159
+ m. path( ) . unwrap_or( & "<EMPTY>" . to_string( ) )
160
+ ) ;
161
+ }
146
162
147
- let pc: GuestReg = qemu. read_reg ( Regs :: Pc ) . unwrap ( ) ;
148
- log:: debug!( "Break at {pc:#x}" ) ;
163
+ let pc: GuestReg = qemu. read_reg ( Regs :: Pc ) . unwrap ( ) ;
164
+ log:: debug!( "Break at {pc:#x}" ) ;
149
165
150
- let ret_addr: GuestAddr = qemu. read_return_address ( ) . unwrap ( ) ;
151
- log:: debug!( "Return address = {ret_addr:#x}" ) ;
166
+ let ret_addr: GuestAddr = qemu. read_return_address ( ) . unwrap ( ) ;
167
+ log:: debug!( "Return address = {ret_addr:#x}" ) ;
152
168
153
- qemu. set_breakpoint ( ret_addr) ;
169
+ qemu. set_breakpoint ( ret_addr) ;
154
170
155
- let input_addr = qemu
156
- . map_private ( 0 , MAX_INPUT_SIZE , MmapPerms :: ReadWrite )
157
- . unwrap ( ) ;
158
- log:: debug!( "Placing input at {input_addr:#x}" ) ;
171
+ let input_addr = qemu
172
+ . map_private ( 0 , MAX_INPUT_SIZE , MmapPerms :: ReadWrite )
173
+ . unwrap ( ) ;
174
+ log:: debug!( "Placing input at {input_addr:#x}" ) ;
159
175
160
- let stack_ptr: GuestAddr = qemu. read_reg ( Regs :: Sp ) . unwrap ( ) ;
176
+ let stack_ptr: GuestAddr = qemu. read_reg ( Regs :: Sp ) . unwrap ( ) ;
161
177
162
- let reset = |buf : & [ u8 ] , len : GuestReg | -> Result < ( ) , QemuRWError > {
163
- unsafe {
164
- let _ = qemu. write_mem ( input_addr, buf) ;
165
- qemu. write_reg ( Regs :: Pc , test_one_input_ptr) ?;
166
- qemu. write_reg ( Regs :: Sp , stack_ptr) ?;
167
- qemu. write_return_address ( ret_addr) ?;
168
- qemu. write_function_argument ( CallingConvention :: Cdecl , 0 , input_addr) ?;
169
- qemu. write_function_argument ( CallingConvention :: Cdecl , 1 , len) ?;
178
+ let reset = |buf : & [ u8 ] , len : GuestReg | -> Result < ( ) , QemuRWError > {
179
+ unsafe {
180
+ let _ = qemu. write_mem ( input_addr, buf) ;
181
+ qemu. write_reg ( Regs :: Pc , test_one_input_ptr) ?;
182
+ qemu. write_reg ( Regs :: Sp , stack_ptr) ?;
183
+ qemu. write_return_address ( ret_addr) ?;
184
+ qemu. write_function_argument ( CallingConvention :: Cdecl , 0 , input_addr) ?;
185
+ qemu. write_function_argument ( CallingConvention :: Cdecl , 1 , len) ?;
170
186
171
- match qemu. run ( ) {
172
- Ok ( QemuExitReason :: Breakpoint ( _) ) => { }
173
- Ok ( QemuExitReason :: End ( QemuShutdownCause :: HostSignal ( Signal :: SigInterrupt ) ) ) => {
174
- process:: exit ( 0 )
187
+ match qemu. run ( ) {
188
+ Ok ( QemuExitReason :: Breakpoint ( _) ) => { }
189
+ Ok ( QemuExitReason :: End ( QemuShutdownCause :: HostSignal (
190
+ Signal :: SigInterrupt ,
191
+ ) ) ) => process:: exit ( 0 ) ,
192
+ _ => panic ! ( "Unexpected QEMU exit." ) ,
175
193
}
176
- _ => panic ! ( "Unexpected QEMU exit." ) ,
177
- }
178
-
179
- Ok ( ( ) )
180
- }
181
- } ;
182
194
183
- let mut harness =
184
- |_emulator : & mut Emulator < _ , _ , _ , _ , _ > , _state : & mut _ , input : & BytesInput | {
185
- let target = input. target_bytes ( ) ;
186
- let mut buf = target. as_slice ( ) ;
187
- let mut len = buf. len ( ) ;
188
- if len > MAX_INPUT_SIZE {
189
- buf = & buf[ 0 ..MAX_INPUT_SIZE ] ;
190
- len = MAX_INPUT_SIZE ;
195
+ Ok ( ( ) )
191
196
}
192
- let len = len as GuestReg ;
193
- reset ( buf, len) . unwrap ( ) ;
194
- ExitKind :: Ok
195
197
} ;
196
198
197
- let mut run_client = |state : Option < _ > ,
198
- mut mgr : LlmpRestartingEventManager < _ , _ , _ > ,
199
- client_description : ClientDescription | {
199
+ let mut harness =
200
+ |_emulator : & mut Emulator < _ , _ , _ , _ , _ > , _state : & mut _ , input : & BytesInput | {
201
+ let target = input. target_bytes ( ) ;
202
+ let mut buf = target. as_slice ( ) ;
203
+ let mut len = buf. len ( ) ;
204
+ if len > MAX_INPUT_SIZE {
205
+ buf = & buf[ 0 ..MAX_INPUT_SIZE ] ;
206
+ len = MAX_INPUT_SIZE ;
207
+ }
208
+ let len = len as GuestReg ;
209
+ reset ( buf, len) . unwrap ( ) ;
210
+ ExitKind :: Ok
211
+ } ;
212
+
200
213
let core_id = client_description. core_id ( ) ;
201
214
let core_idx = options
202
215
. cores
@@ -232,23 +245,11 @@ pub fn fuzz() {
232
245
let scheduler = QueueScheduler :: new ( ) ;
233
246
let mut fuzzer = StdFuzzer :: new ( scheduler, feedback, objective) ;
234
247
235
- let mut cov_path = options. coverage_path . clone ( ) ;
236
248
let coverage_name = cov_path. file_stem ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
237
249
let coverage_extension = cov_path. extension ( ) . unwrap_or_default ( ) . to_str ( ) . unwrap ( ) ;
238
250
let core = core_id. 0 ;
239
251
cov_path. set_file_name ( format ! ( "{coverage_name}-{core:03}.{coverage_extension}" ) ) ;
240
252
241
- let emulator_modules = tuple_list ! ( DrCovModule :: builder( )
242
- . filter( StdAddressFilter :: default ( ) )
243
- . filename( cov_path)
244
- . full_trace( false )
245
- . build( ) ) ;
246
-
247
- let emulator = Emulator :: empty ( )
248
- . qemu ( qemu)
249
- . modules ( emulator_modules)
250
- . build ( ) ?;
251
-
252
253
let mut executor = QemuExecutor :: new (
253
254
emulator,
254
255
& mut harness,
0 commit comments