@@ -340,7 +340,7 @@ static TCGHelperInfo libafl_exec_write_hookN_info = {
340
340
struct libafl_rw_hook * libafl_read_hooks ;
341
341
size_t libafl_read_hooks_num = 0 ;
342
342
343
- size_t libafl_add_read_hook (uint64_t (* gen )(uint64_t data , target_ulong pc , MemOpIdx oi ),
343
+ size_t libafl_add_read_hook (uint64_t (* gen )(uint64_t data , target_ulong pc , TCGTemp * addr , MemOpIdx oi ),
344
344
void (* exec1 )(uint64_t data , uint64_t id , target_ulong addr ),
345
345
void (* exec2 )(uint64_t data , uint64_t id , target_ulong addr ),
346
346
void (* exec4 )(uint64_t data , uint64_t id , target_ulong addr ),
@@ -394,7 +394,7 @@ GEN_REMOVE_HOOK(read)
394
394
struct libafl_rw_hook * libafl_write_hooks ;
395
395
size_t libafl_write_hooks_num = 0 ;
396
396
397
- size_t libafl_add_write_hook (uint64_t (* gen )(uint64_t data , target_ulong pc , MemOpIdx oi ),
397
+ size_t libafl_add_write_hook (uint64_t (* gen )(uint64_t data , target_ulong pc , TCGTemp * addr , MemOpIdx oi ),
398
398
void (* exec1 )(uint64_t data , uint64_t id , target_ulong addr ),
399
399
void (* exec2 )(uint64_t data , uint64_t id , target_ulong addr ),
400
400
void (* exec4 )(uint64_t data , uint64_t id , target_ulong addr ),
@@ -452,7 +452,7 @@ static void libafl_gen_rw(TCGTemp *addr, MemOpIdx oi, struct libafl_rw_hook* hoo
452
452
while (hook ) {
453
453
uint64_t cur_id = 0 ;
454
454
if (hook -> gen )
455
- cur_id = hook -> gen (hook -> data , libafl_gen_cur_pc , oi );
455
+ cur_id = hook -> gen (hook -> data , libafl_gen_cur_pc , addr , oi );
456
456
TCGHelperInfo * info = NULL ;
457
457
if (size == 1 && hook -> helper_info1 .func ) info = & hook -> helper_info1 ;
458
458
else if (size == 2 && hook -> helper_info2 .func ) info = & hook -> helper_info2 ;
@@ -685,3 +685,59 @@ size_t libafl_add_new_thread_hook(bool (*callback)(uint64_t data, uint32_t tid),
685
685
}
686
686
687
687
GEN_REMOVE_HOOK1 (new_thread )
688
+
689
+ #if TARGET_LONG_BITS == 32
690
+ #define SHADOW_BASE (0x20000000)
691
+ #elif TARGET_LONG_BITS == 64
692
+ #define SHADOW_BASE (0x7fff8000)
693
+ #else
694
+ #error Unhandled TARGET_LONG_BITS value
695
+ #endif
696
+
697
+ void libafl_tcg_gen_asan (TCGTemp * addr , size_t size )
698
+ {
699
+ if (size == 0 )
700
+ return ;
701
+
702
+ TCGv addr_val = temp_tcgv_tl (addr );
703
+ TCGv k = tcg_temp_new ();
704
+ TCGv shadow_addr = tcg_temp_new ();
705
+ TCGv_ptr shadow_ptr = tcg_temp_new_ptr ();
706
+ TCGv shadow_val = tcg_temp_new ();
707
+ TCGv test_addr = tcg_temp_new ();
708
+ TCGv_ptr test_ptr = tcg_temp_new_ptr ();
709
+
710
+ tcg_gen_andi_tl (k , addr_val , 7 );
711
+ tcg_gen_addi_tl (k , k , size - 1 );
712
+
713
+ tcg_gen_shri_tl (shadow_addr , addr_val , 3 );
714
+ tcg_gen_addi_tl (shadow_addr , shadow_addr , SHADOW_BASE );
715
+ tcg_gen_tl_ptr (shadow_ptr , shadow_addr );
716
+ tcg_gen_ld8s_tl (shadow_val , shadow_ptr , 0 );
717
+
718
+ /*
719
+ * Making conditional branches here appears to cause QEMU issues with dead
720
+ * temporaries so we will instead avoid branches. We will cause the guest
721
+ * to perform a NULL dereference in the event of an ASAN fault. Note that
722
+ * we will do this by using a store rather than a load, since the TCG may
723
+ * otherwise determine that the result of the load is unused and simply
724
+ * discard the operation. In the event that the shadow memory doesn't
725
+ * detect a fault, we will simply write the value read from the shadow
726
+ * memory back to it's original location. If, however, the shadow memory
727
+ * detects an invalid access, we will instead attempt to write the value
728
+ * at 0x0.
729
+ */
730
+ tcg_gen_movcond_tl (TCG_COND_EQ , test_addr ,
731
+ shadow_val , tcg_constant_tl (0 ),
732
+ shadow_addr , tcg_constant_tl (0 ));
733
+
734
+ if (size < 8 )
735
+ {
736
+ tcg_gen_movcond_tl (TCG_COND_GE , test_addr ,
737
+ k , shadow_val ,
738
+ test_addr , shadow_addr );
739
+ }
740
+
741
+ tcg_gen_tl_ptr (test_ptr , test_addr );
742
+ tcg_gen_st8_tl (shadow_val , test_ptr , 0 );
743
+ }
0 commit comments