@@ -1450,6 +1450,7 @@ def _get_regs(instr, include_write=False):
1450
1450
1451
1451
def _hook_code (uc : Uc , address , size , dp : Dumpulator ):
1452
1452
try :
1453
+ uc .ctl_remove_cache (address , address + 16 )
1453
1454
code = b""
1454
1455
try :
1455
1456
code = dp .read (address , min (size , 15 ))
@@ -1693,7 +1694,6 @@ def op_mem(op: X86Op, *, aligned: bool):
1693
1694
mem_address = 0
1694
1695
if op .mem .base == X86_REG_RIP :
1695
1696
mem_address += instr .address + instr .size
1696
- raise NotImplementedError ("TODO: check if the disp is already adjusted" )
1697
1697
else :
1698
1698
base = op .mem .base
1699
1699
if base != X86_REG_INVALID :
@@ -1749,13 +1749,25 @@ def op_write(index: int, value: int, *, aligned=False):
1749
1749
else :
1750
1750
raise NotImplementedError ()
1751
1751
1752
+ def op_bits (index : int ):
1753
+ return instr .operands [index ].size * 8
1754
+
1752
1755
def cip_next ():
1753
1756
dp .regs .cip += instr .size
1754
1757
1755
1758
if instr .id == X86_INS_RDRAND :
1756
1759
# TODO: PRNG based on dmp hash
1757
1760
op_write (0 , 42 )
1758
1761
cip_next ()
1762
+ elif instr .id == X86_INS_RDTSCP :
1763
+ # TODO: properly implement
1764
+ dp .regs .rdx = 0
1765
+ dp .regs .rax = 0
1766
+ dp .regs .rcx = 0
1767
+ cip_next ()
1768
+ elif instr .id == X86_INS_RDGSBASE :
1769
+ op_write (0 , dp .regs .gs_base )
1770
+ cip_next ()
1759
1771
elif instr .id in [X86_INS_VMOVDQU , X86_INS_VMOVUPS ]:
1760
1772
src = op_read (1 )
1761
1773
op_write (0 , src )
@@ -1774,9 +1786,16 @@ def cip_next():
1774
1786
src = (src & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff ) | (xmm1 << 128 )
1775
1787
op_write (0 , src )
1776
1788
cip_next ()
1777
-
1789
+ elif instr .id == X86_INS_VPBROADCASTQ :
1790
+ src = op_read (1 ) & 0xFFFFFFFFFFFFFFFF
1791
+ result = 0
1792
+ for _ in range (op_bits (0 ) // 64 ):
1793
+ result <<= 64
1794
+ result |= src
1795
+ op_write (0 , result )
1796
+ cip_next ()
1778
1797
else :
1779
- dp .error (f"unsupported: { instr .mnemonic } { instr .op_str } " )
1798
+ dp .error (f"unsupported: { hex ( instr . address ) } | { instr .mnemonic } { instr .op_str } " )
1780
1799
# Unsupported instruction
1781
1800
return False
1782
1801
dp .debug (f"emulated: { hex (instr .address )} |{ instr .bytes .hex ()} |{ instr .mnemonic } { instr .op_str } " )
@@ -1794,6 +1813,7 @@ def _hook_invalid(uc: Uc, dp: Dumpulator):
1794
1813
try :
1795
1814
code = dp .read (address , 15 )
1796
1815
instr = next (dp .cs .disasm (code , address , 1 ))
1816
+ dp .debug (f"invalid hook { hex (address )} |{ code .hex ()} |{ instr .mnemonic } { instr .op_str } " )
1797
1817
# TODO: add a hook
1798
1818
if _emulate_unsupported_instruction (dp , instr ):
1799
1819
# Resume execution with a context switch
@@ -1807,5 +1827,8 @@ def _hook_invalid(uc: Uc, dp: Dumpulator):
1807
1827
pass # Unsupported instruction
1808
1828
except IndexError :
1809
1829
pass # Invalid memory access (NOTE: this should not be possible actually)
1830
+ except Exception as err :
1831
+ print (f"Unexpected exception { type (err )} " )
1832
+ traceback .print_exc ()
1810
1833
dp .error (f"invalid instruction at { hex (address )} " )
1811
1834
raise NotImplementedError ("TODO: throw invalid instruction exception" )
0 commit comments