@@ -2377,6 +2377,74 @@ static void test_x86_hook_insn_rdtscp(void)
23772377 OK (uc_close (uc ));
23782378}
23792379
2380+ static void test_x86_hook_insn_rdrand_cb (uc_engine * uc , uint64_t * value ,
2381+ bool * success , void * user_data )
2382+ {
2383+ (* (int * )user_data )++ ;
2384+ * value = 0x0123456789ABCDEF ;
2385+ }
2386+
2387+ static void test_x86_hook_insn_rdrand (void )
2388+ {
2389+ char code [] = "\x48\x0F\xC7\xF3" ; // RDRAND RBX
2390+ uc_engine * uc ;
2391+ uint64_t rbx = 0 ;
2392+ uint64_t eflags = 0 ;
2393+ int called = 0 ;
2394+ uc_hook hook ;
2395+
2396+ OK (uc_open (UC_ARCH_X86 , UC_MODE_64 , & uc ));
2397+ OK (uc_ctl_set_cpu_model (uc , UC_CPU_X86_HASWELL ));
2398+ OK (uc_mem_map (uc , code_start , code_len , UC_PROT_ALL ));
2399+ OK (uc_mem_write (uc , code_start , code , sizeof (code ) - 1 ));
2400+ OK (uc_hook_add (uc , & hook , UC_HOOK_INSN , test_x86_hook_insn_rdrand_cb , & called ,
2401+ 1 , 0 , UC_X86_INS_RDRAND ));
2402+ OK (uc_emu_start (uc , code_start , code_start + sizeof (code ) - 1 , 0 , 0 ));
2403+ OK (uc_hook_del (uc , hook ));
2404+
2405+ OK (uc_reg_read (uc , UC_X86_REG_RBX , & rbx ));
2406+ OK (uc_reg_read (uc , UC_X86_REG_EFLAGS , & eflags )); // check carry flag is set
2407+ TEST_CHECK (called == 1 );
2408+ TEST_CHECK (rbx == 0x0123456789ABCDEF );
2409+ TEST_CHECK ((eflags & 1 ) != 0 );
2410+ OK (uc_close (uc ));
2411+ }
2412+
2413+ static void test_x86_hook_insn_rdrand_failure_cb (uc_engine * uc ,
2414+ uint64_t * value , bool * success ,
2415+ void * user_data )
2416+ {
2417+ (* (int * )user_data )++ ;
2418+ * success = false;
2419+ }
2420+
2421+ static void test_x86_hook_insn_rdrand_failure (void )
2422+ {
2423+ char code [] = "\x48\x0F\xC7\xF3" ; // RDRAND RBX
2424+ uc_engine * uc ;
2425+ uint64_t rbx = 1 ;
2426+ uint64_t eflags = 0 ;
2427+ int called = 0 ;
2428+ uc_hook hook ;
2429+
2430+ OK (uc_open (UC_ARCH_X86 , UC_MODE_64 , & uc ));
2431+ OK (uc_ctl_set_cpu_model (uc , UC_CPU_X86_HASWELL ));
2432+ OK (uc_mem_map (uc , code_start , code_len , UC_PROT_ALL ));
2433+ OK (uc_mem_write (uc , code_start , code , sizeof (code ) - 1 ));
2434+ OK (uc_hook_add (uc , & hook , UC_HOOK_INSN ,
2435+ test_x86_hook_insn_rdrand_failure_cb , & called , 1 , 0 ,
2436+ UC_X86_INS_RDRAND ));
2437+ OK (uc_emu_start (uc , code_start , code_start + sizeof (code ) - 1 , 0 , 0 ));
2438+ OK (uc_hook_del (uc , hook ));
2439+
2440+ OK (uc_reg_read (uc , UC_X86_REG_RBX , & rbx ));
2441+ OK (uc_reg_read (uc , UC_X86_REG_EFLAGS , & eflags ));
2442+ TEST_CHECK (called == 1 );
2443+ TEST_CHECK (rbx == 0 );
2444+ TEST_CHECK ((eflags & 1 ) == 0 );
2445+ OK (uc_close (uc ));
2446+ }
2447+
23802448static int test_x86_hook_insn_wrmsr_cb (uc_engine * uc , void * user_data )
23812449{
23822450 * (int * )user_data = 1 ;
@@ -2802,6 +2870,8 @@ TEST_LIST = {
28022870 {"test_x86_ro_segfault" , test_x86_ro_segfault },
28032871 {"test_x86_hook_insn_rdtsc" , test_x86_hook_insn_rdtsc },
28042872 {"test_x86_hook_insn_rdtscp" , test_x86_hook_insn_rdtscp },
2873+ {"test_x86_hook_insn_rdrand" , test_x86_hook_insn_rdrand },
2874+ {"test_x86_hook_insn_rdrand_failure" , test_x86_hook_insn_rdrand_failure },
28052875 {"test_x86_hook_insn_wrmsr" , test_x86_hook_insn_wrmsr },
28062876 {"test_x86_hook_insn_rdmsr" , test_x86_hook_insn_rdmsr },
28072877 {"test_x86_dr7" , test_x86_dr7 },
0 commit comments