@@ -537,6 +537,93 @@ static void test_riscv64_mmio_map(void)
537537 OK (uc_close (uc ));
538538}
539539
540+
541+ static bool test_riscv_correct_address_in_small_jump_hook_callback (uc_engine * uc , int type , uint64_t address , int size , int64_t value , void * user_data )
542+ {
543+ // Check registers
544+ uint64_t r_x5 = 0x0 ;
545+ uint64_t r_pc = 0x0 ;
546+ OK (uc_reg_read (uc , UC_RISCV_REG_X5 , & r_x5 ));
547+ OK (uc_reg_read (uc , UC_RISCV_REG_PC , & r_pc ));
548+ TEST_CHECK (r_x5 == 0x7F00 );
549+ TEST_CHECK (r_pc == 0x7F00 );
550+
551+ // Check address
552+ // printf("%lx\n", address);
553+ TEST_CHECK (address == 0x7F00 );
554+ return false;
555+ }
556+
557+ static void test_riscv_correct_address_in_small_jump_hook (void )
558+ {
559+ uc_engine * uc ;
560+ // li 0x7F00, x5 > lui t0, 8; addiw t0, t0, -256;
561+ // jr x5
562+ char code [] = "\xb7\x82\x00\x00\x9b\x82\x02\xf0\x67\x80\x02\x00" ;
563+
564+ uint64_t r_x5 = 0x0 ;
565+ uint64_t r_pc = 0x0 ;
566+ uc_hook hook ;
567+
568+ uc_common_setup (& uc , UC_ARCH_RISCV , UC_MODE_RISCV64 , code , sizeof (code ) - 1 );
569+ OK (uc_hook_add (uc , & hook , UC_HOOK_MEM_UNMAPPED , test_riscv_correct_address_in_small_jump_hook_callback , NULL , 1 , 0 ));
570+
571+ uc_assert_err (
572+ UC_ERR_FETCH_UNMAPPED ,
573+ uc_emu_start (uc , code_start , code_start + sizeof (code ) - 1 , 0 , 0 ));
574+
575+ OK (uc_reg_read (uc , UC_RISCV_REG_X5 , & r_x5 ));
576+ OK (uc_reg_read (uc , UC_RISCV_REG_PC , & r_pc ));
577+ TEST_CHECK (r_x5 == 0x7F00 );
578+ TEST_CHECK (r_pc == 0x7F00 );
579+
580+ OK (uc_close (uc ));
581+ }
582+
583+ static bool test_riscv_correct_address_in_long_jump_hook_callback (uc_engine * uc , int type , uint64_t address , int size , int64_t value , void * user_data )
584+ {
585+ // Check registers
586+ uint64_t r_x5 = 0x0 ;
587+ uint64_t r_pc = 0x0 ;
588+ OK (uc_reg_read (uc , UC_RISCV_REG_X5 , & r_x5 ));
589+ OK (uc_reg_read (uc , UC_RISCV_REG_PC , & r_pc ));
590+ TEST_CHECK (r_x5 == 0x7FFFFFFFFFFFFF00 );
591+ TEST_CHECK (r_pc == 0x7FFFFFFFFFFFFF00 );
592+
593+ // Check address
594+ // printf("%lx\n", address);
595+ TEST_CHECK (address == 0x7FFFFFFFFFFFFF00 );
596+ return false;
597+ }
598+
599+ static void test_riscv_correct_address_in_long_jump_hook (void )
600+ {
601+ uc_engine * uc ;
602+ // li 0x7FFFFFFFFFFFFF00, x5 > addi t0, zero, -1; slli t0, t0, 63; addi t0, t0, -256;
603+ // jr x5
604+ char code [] = "\x93\x02\xf0\xff\x93\x92\xf2\x03\x93\x82\x02\xf0\x67\x80\x02\x00" ;
605+
606+ uint64_t r_x5 = 0x0 ;
607+ uint64_t r_pc = 0x0 ;
608+ uc_hook hook ;
609+
610+ uc_common_setup (& uc , UC_ARCH_RISCV , UC_MODE_RISCV64 , code , sizeof (code ) - 1 );
611+ OK (uc_hook_add (uc , & hook , UC_HOOK_MEM_UNMAPPED , test_riscv_correct_address_in_long_jump_hook_callback , NULL , 1 , 0 ));
612+
613+ uc_assert_err (
614+ UC_ERR_FETCH_UNMAPPED ,
615+ uc_emu_start (uc , code_start , code_start + sizeof (code ) - 1 , 0 , 0 ));
616+
617+ OK (uc_reg_read (uc , UC_RISCV_REG_X5 , & r_x5 ));
618+ OK (uc_reg_read (uc , UC_RISCV_REG_PC , & r_pc ));
619+ TEST_CHECK (r_x5 == 0x7FFFFFFFFFFFFF00 );
620+ TEST_CHECK (r_pc == 0x7FFFFFFFFFFFFF00 );
621+
622+ OK (uc_close (uc ));
623+ }
624+
625+
626+
540627TEST_LIST = {
541628 {"test_riscv32_nop" , test_riscv32_nop },
542629 {"test_riscv64_nop" , test_riscv64_nop },
@@ -556,4 +643,6 @@ TEST_LIST = {
556643 {"test_riscv32_map" , test_riscv32_map },
557644 {"test_riscv64_code_patching" , test_riscv64_code_patching },
558645 {"test_riscv64_code_patching_count" , test_riscv64_code_patching_count },
646+ {"test_riscv_correct_address_in_small_jump_hook" , test_riscv_correct_address_in_small_jump_hook },
647+ {"test_riscv_correct_address_in_long_jump_hook" , test_riscv_correct_address_in_long_jump_hook },
559648 {NULL , NULL }};
0 commit comments