1import logging 
    2 
    3from pyvex.lifting.util import GymratLifter, Instruction, JumpKind, Type 
    4 
    5log = logging.getLogger(__name__) 
    6 
    7# pylint: disable=missing-class-docstring 
    8 
    9 
    10class Instruction_SWAPGS(Instruction): 
    11    name = "SWAPGS" 
    12    bin_format = "000011110000000111111000"  # 0f 01 f8 
    13 
    14    def compute_result(self, *args): 
    15        pass  # TODO check for priv mode 
    16 
    17 
    18class Instruction_SYSRET(Instruction): 
    19    name = "SYSRET" 
    20    bin_format = "010010000000111100000111"  # 48 04 07 
    21 
    22    def compute_result(self, *args): 
    23        result = self.dirty(Type.int_64, "%sg_dirtyhelper_SYSRET" % self.arch.name.lower(), ()) 
    24        self.jump(None, result, JumpKind.Ret) 
    25 
    26 
    27class Instruction_IRETQ(Instruction): 
    28    name = "IRETQ" 
    29    bin_format = "0100100011001111"  # 48 cf 
    30 
    31    def compute_result(self, *args): 
    32        result = self.dirty(Type.int_64, "%sg_dirtyhelper_IRETQ" % self.arch.name.lower(), ()) 
    33        self.jump(None, result, JumpKind.Ret) 
    34 
    35 
    36class Instruction_RDMSR(Instruction): 
    37    name = "RDMSR" 
    38    bin_format = "0000111100110010"  # 0f 32 
    39 
    40    def compute_result(self, *args): 
    41        ecx = self.get("ecx", Type.int_32) 
    42        result = self.dirty(Type.int_64, "%sg_dirtyhelper_RDMSR" % self.arch.name.lower(), (ecx,)) 
    43        edx = result.narrow_high(Type.int_32) 
    44        eax = result.narrow_low(Type.int_32) 
    45        if self.arch.bits == 32: 
    46            self.put(eax, "eax") 
    47            self.put(edx, "edx") 
    48        else: 
    49            self.put(eax.widen_unsigned(Type.int_64), "rax") 
    50            self.put(edx.widen_unsigned(Type.int_64), "rdx") 
    51 
    52 
    53class Instruction_XGETBV(Instruction): 
    54    name = "XGETBV" 
    55    bin_format = "000011110000000111010000"  # 0f 01 d0 
    56 
    57    def compute_result(self, *args): 
    58        ecx = self.get("ecx", Type.int_32) 
    59        result = self.dirty(Type.int_64, "%sg_dirtyhelper_XGETBV" % self.arch.name.lower(), (ecx,)) 
    60        edx = result.narrow_high(Type.int_32) 
    61        eax = result.narrow_low(Type.int_32) 
    62        if self.arch.bits == 32: 
    63            self.put(eax, "eax") 
    64            self.put(edx, "edx") 
    65        else: 
    66            self.put(eax.widen_unsigned(Type.int_64), "rax") 
    67            self.put(edx.widen_unsigned(Type.int_64), "rdx") 
    68 
    69 
    70class Instruction_AAM(Instruction): 
    71    name = "AAM" 
    72    bin_format = "11010100iiiiiiii" 
    73 
    74    # From https://www.felixcloutier.com/x86/aam 
    75    def compute_result(self):  # pylint: disable=arguments-differ 
    76        base = self.constant(int(self.data["i"], 2), Type.int_8) 
    77        temp_al = self.get("al", Type.int_8) 
    78        temp_ah = temp_al // base 
    79        temp_al = temp_al % base 
    80        self.put(temp_ah, "ah") 
    81        self.put(temp_al, "al") 
    82        log.debug( 
    83            "The generalized AAM instruction is not supported by VEX, and is handled specially by pyvex." 
    84            " It has no flag handling at present.  See pyvex/lifting/gym/x86_spotter.py for details" 
    85        ) 
    86 
    87    # TODO: Flags 
    88 
    89 
    90class Instruction_AAD(Instruction): 
    91    name = "AAD" 
    92    bin_format = "11010101iiiiiiii" 
    93 
    94    # From https://www.felixcloutier.com/x86/aad 
    95    def compute_result(self):  # pylint: disable=arguments-differ 
    96        base = self.constant(int(self.data["i"], 2), Type.int_8) 
    97        temp_al = self.get("al", Type.int_8) 
    98        temp_ah = self.get("ah", Type.int_8) 
    99        temp_al = (temp_al + (temp_ah * base)) & 0xFF 
    100        temp_ah = self.constant(0, Type.int_8) 
    101        self.put(temp_ah, "ah") 
    102        self.put(temp_al, "al") 
    103        log.debug( 
    104            "The generalized AAD instruction is not supported by VEX, and is handled specially by pyvex." 
    105            " It has no flag handling at present.  See pyvex/lifting/gym/x86_spotter.py for details" 
    106        ) 
    107 
    108    # TODO: Flags 
    109 
    110 
    111class AMD64Spotter(GymratLifter): 
    112    instrs = [ 
    113        Instruction_RDMSR, 
    114        Instruction_XGETBV, 
    115        Instruction_AAD, 
    116        Instruction_AAM, 
    117        Instruction_SWAPGS, 
    118        Instruction_IRETQ, 
    119        Instruction_SYSRET, 
    120    ] 
    121 
    122 
    123class X86Spotter(GymratLifter): 
    124    instrs = [ 
    125        Instruction_RDMSR, 
    126        Instruction_XGETBV, 
    127        Instruction_AAD, 
    128        Instruction_AAM, 
    129    ]