@@ -23,7 +23,6 @@ typedef struct {
23
23
typedef struct {
24
24
const RzCore * core ;
25
25
const RzRopConstraint * constraint ;
26
- const ut64 val ;
27
26
const RzRopRegInfo * reg_info ;
28
27
const RzRopGadgetInfo * gadget_info ;
29
28
} RopStackConstraintParams ;
@@ -47,9 +46,6 @@ static void update_rop_constraint_result(const RzRopSolverResult *result,
47
46
48
47
static ut64 parse_rop_constraint_int_val (const RzRopConstraint * rop_constraint ,
49
48
const RzRopArgType type ) {
50
- if (!rop_constraint ) {
51
- return -1 ;
52
- }
53
49
const char * src_const = rop_constraint -> args [type ];
54
50
char * endptr ;
55
51
ut64 src_val ;
@@ -118,6 +114,11 @@ static void handle_mov_reg_analysis(const RopSolverAnalysisOpParams *op_params,
118
114
op_params -> gadget_info && v );
119
115
const RzAnalysisOp * op = (RzAnalysisOp * )v ;
120
116
const RzRopConstraint * constraint = op_params -> constraint ;
117
+ const char * dst_reg = constraint -> args [DST_REG ];
118
+ if (!dst_reg ) {
119
+ return ;
120
+ }
121
+
121
122
const RzRopGadgetInfo * gadget_info = op_params -> gadget_info ;
122
123
}
123
124
@@ -127,9 +128,6 @@ handle_mov_const_analysis(const RopSolverAnalysisOpParams *op_params,
127
128
rz_return_if_fail (op_params && op_params -> constraint && op_params &&
128
129
op_params -> result && v && op_params -> core );
129
130
const RzRopConstraint * constraint = op_params -> constraint ;
130
- if (!constraint ) {
131
- return ;
132
- }
133
131
const char * dst_reg = constraint -> args [DST_REG ];
134
132
if (!dst_reg ) {
135
133
return ;
@@ -190,10 +188,10 @@ static bool has_value_cb(void *user, const void *key, const ut64 value) {
190
188
RzRopSolverResult * result = user ;
191
189
if (!value ) {
192
190
result -> is_solved = false;
193
- return true ; // Continue iteration rop solver is not complete
191
+ return false ; // If it has one value, break from the loop
194
192
}
195
193
result -> is_solved = true;
196
- return false ;
194
+ return true ;
197
195
}
198
196
199
197
static bool is_rop_solver_complete (const RzRopSolverResult * result ) {
@@ -202,25 +200,6 @@ static bool is_rop_solver_complete(const RzRopSolverResult *result) {
202
200
return result -> is_solved ;
203
201
}
204
202
205
- static void mov_reg (const RzCore * core , const RzRopGadgetInfo * gadget_info ,
206
- const RzRopConstraint * rop_constraint ,
207
- const RopSolverCallbackParams * params ) {
208
- // Assertions for mov_reg solver
209
- rz_return_if_fail (gadget_info && rop_constraint );
210
- rz_return_if_fail (rop_constraint -> args [SRC_REG ] &&
211
- rop_constraint -> args [DST_REG ]);
212
- rz_return_if_fail (core && core -> analysis && core -> analysis -> reg );
213
-
214
- RzRopRegInfo * info = rz_core_rop_gadget_info_get_modified_register (
215
- gadget_info , rop_constraint -> args [DST_REG ]);
216
- if (!info ) {
217
- return ;
218
- }
219
- if (is_rop_solver_complete (params -> result )) {
220
- return ;
221
- }
222
- }
223
-
224
203
static bool stack_constraint (const RopStackConstraintParams * params ,
225
204
const RzRopSolverResult * result ) {
226
205
rz_return_val_if_fail (params && params -> constraint && params -> reg_info ,
@@ -284,7 +263,8 @@ static bool stack_constraint(const RopStackConstraintParams *params,
284
263
}
285
264
286
265
static bool is_direct_lookup (const RzCore * core ,
287
- const RzRopGadgetInfo * gadget_info , char * dst ) {
266
+ const RzRopGadgetInfo * gadget_info ,
267
+ RzPVector * dep_allow_list ) {
288
268
if (!gadget_info ) {
289
269
return false;
290
270
}
@@ -293,8 +273,32 @@ static bool is_direct_lookup(const RzCore *core,
293
273
return false;
294
274
}
295
275
296
- RzRopRegInfo * reg_info ;
276
+ RzRopRegInfo * reg_info = NULL ;
297
277
RzListIter * iter ;
278
+ if (dep_allow_list ) {
279
+ RzPVector * events = rz_core_rop_gadget_get_reg_info_by_event (
280
+ gadget_info , RZ_ROP_EVENT_VAR_READ );
281
+ if (rz_pvector_empty (events )) {
282
+ return false;
283
+ }
284
+ while (!rz_pvector_empty (events )) {
285
+ reg_info = rz_pvector_pop (events );
286
+ if (!reg_info ) {
287
+ continue ;
288
+ }
289
+ if (rz_reg_is_role (core -> analysis -> reg , reg_info -> name , RZ_REG_NAME_SP ) ||
290
+ rz_reg_is_role (core -> analysis -> reg , reg_info -> name , RZ_REG_NAME_BP )) {
291
+ continue ;
292
+ }
293
+ if (rz_pvector_find (dep_allow_list , reg_info -> name ,
294
+ (RzPVectorComparator )strcmp , NULL )) {
295
+ return true;
296
+ }
297
+ }
298
+
299
+ return false;
300
+ }
301
+
298
302
rz_list_foreach (gadget_info -> dependencies , iter , reg_info ) {
299
303
if (rz_reg_is_role (core -> analysis -> reg , reg_info -> name , RZ_REG_NAME_SP ) ||
300
304
rz_reg_is_role (core -> analysis -> reg , reg_info -> name , RZ_REG_NAME_BP )) {
@@ -306,10 +310,9 @@ static bool is_direct_lookup(const RzCore *core,
306
310
return true;
307
311
}
308
312
309
- static void rz_solver_direct_lookup (const RzCore * core ,
310
- const RzRopGadgetInfo * gadget_info ,
311
- const RzRopConstraint * rop_constraint ,
312
- const RzRopSolverResult * result ) {
313
+ static void rz_solver_mov_const_direct_lookup (
314
+ const RzCore * core , const RzRopGadgetInfo * gadget_info ,
315
+ const RzRopConstraint * rop_constraint , const RzRopSolverResult * result ) {
313
316
RzRopRegInfo * info = rz_core_rop_gadget_info_get_modified_register (
314
317
gadget_info , rop_constraint -> args [DST_REG ]);
315
318
if (!info ) {
@@ -321,8 +324,7 @@ static void rz_solver_direct_lookup(const RzCore *core,
321
324
if (src_val == -1 ) {
322
325
return ;
323
326
}
324
- const bool is_dir_lookup =
325
- is_direct_lookup (core , gadget_info , rop_constraint -> args [DST_REG ]);
327
+ const bool is_dir_lookup = is_direct_lookup (core , gadget_info , NULL );
326
328
if (info -> new_val == src_val && is_dir_lookup ) {
327
329
update_rop_constraint_result (result , rop_constraint , gadget_info -> address );
328
330
return ;
@@ -332,14 +334,56 @@ static void rz_solver_direct_lookup(const RzCore *core,
332
334
const RopStackConstraintParams stack_params = {
333
335
.core = core ,
334
336
.constraint = rop_constraint ,
335
- .val = src_val ,
336
337
.reg_info = info ,
337
338
.gadget_info = gadget_info ,
338
339
};
339
340
if (stack_constraint (& stack_params , result )) {
340
341
return ;
341
342
}
342
- return ;
343
+ }
344
+
345
+ static void rz_solver_mov_reg_direct_lookup (
346
+ const RzCore * core , const RzRopGadgetInfo * gadget_info ,
347
+ const RzRopConstraint * rop_constraint , const RzRopSolverResult * result ) {
348
+ RzRopRegInfo * dst_info = rz_core_rop_gadget_info_get_modified_register (
349
+ gadget_info , rop_constraint -> args [DST_REG ]);
350
+
351
+ if (!dst_info ) {
352
+ return ;
353
+ }
354
+ RzPVector * dep_allow_list = rz_pvector_new (free );
355
+ if (!dep_allow_list ) {
356
+ return ;
357
+ }
358
+ rz_pvector_push (dep_allow_list , rz_str_dup (rop_constraint -> args [SRC_REG ]));
359
+ const bool is_dir_lookup =
360
+ is_direct_lookup (core , gadget_info , dep_allow_list );
361
+ if (is_dir_lookup ) {
362
+ update_rop_constraint_result (result , rop_constraint , gadget_info -> address );
363
+ goto exit ;
364
+ }
365
+
366
+ exit :
367
+ rz_pvector_fini (dep_allow_list );
368
+ }
369
+
370
+ static void rz_solver_direct_lookup (const RzCore * core ,
371
+ const RzRopGadgetInfo * gadget_info ,
372
+ const RzRopConstraint * rop_constraint ,
373
+ const RzRopSolverResult * result ) {
374
+ if (!rop_constraint ) {
375
+ return ;
376
+ }
377
+ switch (rop_constraint -> type ) {
378
+ case MOV_CONST :
379
+ return rz_solver_mov_const_direct_lookup (core , gadget_info , rop_constraint ,
380
+ result );
381
+ case MOV_REG :
382
+ return rz_solver_mov_reg_direct_lookup (core , gadget_info , rop_constraint ,
383
+ result );
384
+ default :
385
+ break ;
386
+ }
343
387
}
344
388
345
389
static void mov_const (const RzCore * core , const RzRopGadgetInfo * gadget_info ,
@@ -370,6 +414,28 @@ static void mov_const(const RzCore *core, const RzRopGadgetInfo *gadget_info,
370
414
// Recipe : Search for dependencies and create a z3 state
371
415
}
372
416
417
+ static void mov_reg (const RzCore * core , const RzRopGadgetInfo * gadget_info ,
418
+ const RzRopConstraint * rop_constraint ,
419
+ const RopSolverCallbackParams * callback_params ) {
420
+ // Assertions for mov_reg solver
421
+ rz_return_if_fail (gadget_info && rop_constraint );
422
+ rz_return_if_fail (rop_constraint -> args [SRC_REG ] &&
423
+ rop_constraint -> args [DST_REG ]);
424
+ rz_return_if_fail (core && core -> analysis && core -> analysis -> reg );
425
+
426
+ RzRopRegInfo * info = rz_core_rop_gadget_info_get_modified_register (
427
+ gadget_info , rop_constraint -> args [DST_REG ]);
428
+ if (!info ) {
429
+ return ;
430
+ }
431
+ // Direct lookup case
432
+ rz_solver_direct_lookup (core , gadget_info , rop_constraint ,
433
+ callback_params -> result );
434
+ if (is_rop_solver_complete (callback_params -> result )) {
435
+ return ;
436
+ }
437
+ }
438
+
373
439
static void rop_gadget_info_constraint_find (
374
440
const RzCore * core , const RzRopConstraint * rop_constraint ,
375
441
const RzRopGadgetInfo * gadget_info , const RopSolverCallbackParams * params ) {
@@ -385,8 +451,6 @@ static void rop_gadget_info_constraint_find(
385
451
default :
386
452
break ;
387
453
}
388
-
389
- return ;
390
454
}
391
455
392
456
static bool rop_solver_cb (void * user , const ut64 k , const void * v ) {
@@ -479,7 +543,11 @@ RZ_API void rz_rop_solver_result_free(RzRopSolverResult *result) {
479
543
* \brief Prints the result of the ROP solver.
480
544
* \param result The RzRopSolverResult object to print.
481
545
*/
482
- RZ_API void rz_rop_solver_result_print (const RzRopSolverResult * result ) {
546
+ RZ_API void
547
+ rz_rop_solver_result_print (RZ_NULLABLE const RzRopSolverResult * result ) {
548
+ if (!result ) {
549
+ return ;
550
+ }
483
551
void * * it ;
484
552
rz_pvector_foreach (result -> gadget_info_addr_set , it ) {
485
553
const ut64 addr = (ut64 )* it ;
0 commit comments