(self)
loading registers from unicorn
loading registers from unicorn
loading registers from unicorn
def get_regs(self):
        ''' loading registers from unicorn '''

        # first, get the ignore list (in case of symbolic registers)
        saved_registers = []
        if options.UNICORN_SYM_REGS_SUPPORT in self.state.options:
            highest_reg_offset, reg_size = max(self.state.arch.registers.values())
            symbolic_list = (ctypes.c_uint64*(highest_reg_offset + reg_size))()
            num_regs = _UC_NATIVE.get_symbolic_registers(self._uc_state, symbolic_list)

            # If any VEX cc_dep registers are symbolic, mark VEX cc_op register as symbolic so that it would be saved
            # and restored for future use if needed
            symbolic_list = symbolic_list[:num_regs]
            for reg in self.state.arch.vex_cc_regs[1:]:
                if reg.vex_offset in symbolic_list:
                    cc_op_reg = self.state.arch.vex_cc_regs[0]
                    if cc_op_reg.vex_offset not in symbolic_list:
                        symbolic_list.extend(range(cc_op_reg.vex_offset, cc_op_reg.vex_offset + cc_op_reg.size))
                    break

            # we take the approach of saving off the symbolic regs and then writing them back

            cur_group = None
            last = None
            for i in sorted(symbolic_list):
                if cur_group is None:
                    cur_group = i
                elif i != last + 1 or cur_group//self.state.arch.bytes != i//self.state.arch.bytes:
                    l.debug("Restoring symbolic register %d", cur_group)
                    saved_registers.append((
                        cur_group, self.state.registers.load(cur_group, last-cur_group+1)
                    ))
                    cur_group = i
                last = i
            if cur_group is not None:
                l.debug("Restoring symbolic register %d", cur_group)
                saved_registers.append((
                    cur_group, self.state.registers.load(cur_group, last-cur_group+1)
                ))

        # now we sync registers out of unicorn
        for r, c in self._uc_regs.items():
            if r in self.state.arch.reg_blacklist:
                continue
            v = self.uc.reg_read(c)
            # l.debug('getting $%s = %#x', r, v)
            setattr(self.state.regs, r, v)

        # some architecture-specific register fixups
        if self.state.arch.name in ('X86', 'AMD64'):
            # update the eflags
            self.state.regs.eflags = self.state.solver.BVV(self.uc.reg_read(self._uc_const.UC_X86_REG_EFLAGS), self.state.arch.bits)

            # sync the fp clerical data
            status = self.uc.reg_read(unicorn.x86_const.UC_X86_REG_FPSW)
            c3210 = status & 0x4700
            top = (status & 0x3800) >> 11
            control = self.uc.reg_read(unicorn.x86_const.UC_X86_REG_FPCW)
            rm = (control & 0x0C00) >> 10
            self.state.regs.fpround = rm
            self.state.regs.fc3210 = c3210
            self.state.regs.ftop = top

            # sync the stx registers
            # we gotta round the 80-bit extended precision values to 64-bit doubles!
            uc_offset = unicorn.x86_const.UC_X86_REG_FP0
            vex_offset = self.state.arch.registers['fpu_regs'][0]
            vex_tag_offset = self.state.arch.registers['fpu_tags'][0] + 7
            tag_word = self.uc.reg_read(unicorn.x86_const.UC_X86_REG_FPTAG)

            for _ in range(8):
                if tag_word & 3 == 3:
                    self.state.registers.store(vex_tag_offset, 0, size=1)
                else:
                    self.state.registers.store(vex_tag_offset, 1, size=1)

                    mantissa, exponent = self.uc.reg_read(uc_offset)
                    sign = bool(exponent & 0x8000)
                    exponent = (exponent & 0x7FFF)
                    if exponent not in (0, 0x7FFF): # normal value
                        exponent = exponent - 16383 + 1023
                        if exponent <= 0:   # underflow to zero
                            exponent = 0
                            mantissa = 0
                        elif exponent >= 0x7FF: # overflow to infinity
                            exponent = 0x7FF
                            mantissa = 0
                    elif exponent == 0:     # zero or subnormal value
                        mantissa = 0
                    elif exponent == 0x7FFF:    # nan or infinity
                        exponent = 0x7FF
                        if mantissa != 0:
                            mantissa = 0xFFFF

                    val = 0x8000000000000000 if sign else 0
                    val |= exponent << 52
                    val |= (mantissa >> 11) & 0xFFFFFFFFFFFFF
                    # the mantissa calculation is to convert from the 64-bit mantissa to 52-bit
                    # additionally, extended precision keeps around an high bit that we don't care about
                    # so 11-shift, not 12

                    self.state.registers.store(vex_offset, val, size=8)

                uc_offset += 1
                vex_offset += 8
                tag_word >>= 2
                vex_tag_offset -= 1

        # TODO: ARM hardfloat

        # now, we restore the symbolic registers
        if options.UNICORN_SYM_REGS_SUPPORT in self.state.options:
            for o, r in saved_registers:
                self.state.registers.store(o, r)
def get_regs ( self ) : # first, get the ignore list (in case of symbolic registers) saved_registers = [ ] if options . UNICORN_SYM_REGS_SUPPORT in self . state . options : highest_reg_offset , reg_size = max ( self . state . arch . registers . values ( ) ) symbolic_list = ( ctypes . c_uint64 * ( highest_reg_offset + reg_size ) ) ( ) num_regs = _UC_NATIVE . get_symbolic_registers ( self . _uc_state , symbolic_list ) # If any VEX cc_dep registers are symbolic, mark VEX cc_op register as symbolic so that it would be saved # and restored for future use if needed symbolic_list = symbolic_list [ : num_regs ] for reg in self . state . arch . vex_cc_regs [ 1 : ] : if reg . vex_offset in symbolic_list : cc_op_reg = self . state . arch . vex_cc_regs [ 0 ] if cc_op_reg . vex_offset not in symbolic_list : symbolic_list . extend ( range ( cc_op_reg . vex_offset , cc_op_reg . vex_offset + cc_op_reg . size ) ) break # we take the approach of saving off the symbolic regs and then writing them back cur_group = None last = None for i in sorted ( symbolic_list ) : if cur_group is None : cur_group = i elif i != last + 1 or cur_group // self . state . arch . bytes != i // self . state . arch . bytes : l . debug ( "Restoring symbolic register %d" , cur_group ) saved_registers . append ( ( cur_group , self . state . registers . load ( cur_group , last - cur_group + 1 ) ) ) cur_group = i last = i if cur_group is not None : l . debug ( "Restoring symbolic register %d" , cur_group ) saved_registers . append ( ( cur_group , self . state . registers . load ( cur_group , last - cur_group + 1 ) ) ) # now we sync registers out of unicorn for r , c in self . _uc_regs . items ( ) : if r in self . state . arch . reg_blacklist : continue v = self . uc . reg_read ( c ) # l.debug('getting $%s = %#x', r, v) setattr ( self . state . regs , r , v ) # some architecture-specific register fixups if self . state . arch . name in ( 'X86' , 'AMD64' ) : # update the eflags self . state . regs . eflags = self . state . solver . BVV ( self . uc . reg_read ( self . _uc_const . UC_X86_REG_EFLAGS ) , self . state . arch . bits ) # sync the fp clerical data status = self . uc . reg_read ( unicorn . x86_const . UC_X86_REG_FPSW ) c3210 = status & 0x4700 top = ( status & 0x3800 ) >> 11 control = self . uc . reg_read ( unicorn . x86_const . UC_X86_REG_FPCW ) rm = ( control & 0x0C00 ) >> 10 self . state . regs . fpround = rm self . state . regs . fc3210 = c3210 self . state . regs . ftop = top # sync the stx registers # we gotta round the 80-bit extended precision values to 64-bit doubles! uc_offset = unicorn . x86_const . UC_X86_REG_FP0 vex_offset = self . state . arch . registers [ 'fpu_regs' ] [ 0 ] vex_tag_offset = self . state . arch . registers [ 'fpu_tags' ] [ 0 ] + 7 tag_word = self . uc . reg_read ( unicorn . x86_const . UC_X86_REG_FPTAG ) for _ in range ( 8 ) : if tag_word & 3 == 3 : self . state . registers . store ( vex_tag_offset , 0 , size = 1 ) else : self . state . registers . store ( vex_tag_offset , 1 , size = 1 ) mantissa , exponent = self . uc . reg_read ( uc_offset ) sign = bool ( exponent & 0x8000 ) exponent = ( exponent & 0x7FFF ) if exponent not in ( 0 , 0x7FFF ) : # normal value exponent = exponent - 16383 + 1023 if exponent <= 0 : # underflow to zero exponent = 0 mantissa = 0 elif exponent >= 0x7FF : # overflow to infinity exponent = 0x7FF mantissa = 0 elif exponent == 0 : # zero or subnormal value mantissa = 0 elif exponent == 0x7FFF : # nan or infinity exponent = 0x7FF if mantissa != 0 : mantissa = 0xFFFF val = 0x8000000000000000 if sign else 0 val |= exponent << 52 val |= ( mantissa >> 11 ) & 0xFFFFFFFFFFFFF # the mantissa calculation is to convert from the 64-bit mantissa to 52-bit # additionally, extended precision keeps around an high bit that we don't care about # so 11-shift, not 12 self . state . registers . store ( vex_offset , val , size = 8 ) uc_offset += 1 vex_offset += 8 tag_word >>= 2 vex_tag_offset -= 1 # TODO: ARM hardfloat # now, we restore the symbolic registers if options . UNICORN_SYM_REGS_SUPPORT in self . state . options : for o , r in saved_registers : self . state . registers . store ( o , r )