<s> """<STR_LIT>""" <EOL> import logging <EOL> from capstone import CS_ARCH_ARM <EOL> from capstone import CS_MODE_ARM <EOL> from capstone import CS_MODE_THUMB <EOL> from capstone import Cs <EOL> from capstone . arm import ARM_CC_AL <EOL> from capstone . arm import ARM_CC_EQ <EOL> from capstone . arm import ARM_CC_GE <EOL> from capstone . arm import ARM_CC_GT <EOL> from capstone . arm import ARM_CC_HI <EOL> from capstone . arm import ARM_CC_HS <EOL> from capstone . arm import ARM_CC_INVALID <EOL> from capstone . arm import ARM_CC_LE <EOL> from capstone . arm import ARM_CC_LO <EOL> from capstone . arm import ARM_CC_LS <EOL> from capstone . arm import ARM_CC_LT <EOL> from capstone . arm import ARM_CC_MI <EOL> from capstone . arm import ARM_CC_NE <EOL> from capstone . arm import ARM_CC_PL <EOL> from capstone . arm import ARM_CC_VC <EOL> from capstone . arm import ARM_CC_VS <EOL> from capstone . arm import ARM_OP_IMM <EOL> from capstone . arm import ARM_OP_MEM <EOL> from capstone . arm import ARM_OP_REG <EOL> from capstone . arm import ARM_SFT_ASR <EOL> from capstone . arm import ARM_SFT_ASR_REG <EOL> from capstone . arm import ARM_SFT_LSL <EOL> from capstone . arm import ARM_SFT_LSL_REG <EOL> from capstone . arm import ARM_SFT_LSR <EOL> from capstone . arm import ARM_SFT_LSR_REG <EOL> from capstone . arm import ARM_SFT_ROR <EOL> from capstone . arm import ARM_SFT_ROR_REG <EOL> from capstone . arm import ARM_SFT_RRX <EOL> from capstone . arm import ARM_SFT_RRX_REG <EOL> from barf . arch import ARCH_ARM_MODE_ARM <EOL> from barf . arch import ARCH_ARM_MODE_THUMB <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_AL <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_EQ <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_GE <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_GT <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_HI <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_HS <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_LE <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_LO <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_LS <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_LT <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_MI <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_NE <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_PL <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_VC <EOL> from barf . arch . arm . armbase import ARM_COND_CODE_VS <EOL> from barf . arch . arm . armbase import ARM_MEMORY_INDEX_OFFSET <EOL> from barf . arch . arm . armbase import ArmArchitectureInformation <EOL> from barf . arch . arm . armbase import ArmImmediateOperand <EOL> from barf . arch . arm . armbase import ArmInstruction <EOL> from barf . arch . arm . armbase import ArmMemoryOperand <EOL> from barf . arch . arm . armbase import ArmRegisterListOperand <EOL> from barf . arch . arm . armbase import ArmRegisterOperand <EOL> from barf . arch . arm . armbase import ArmShiftedRegisterOperand <EOL> from barf . arch . arm . armbase import cc_inverse_mapper <EOL> from barf . arch . arm . armbase import arm_alias_reg_map <EOL> from barf . arch . arm . armbase import ldm_stm_am_mapper <EOL> from barf . core . disassembler import Disassembler <EOL> from barf . core . disassembler import InvalidDisassemblerData <EOL> cc_capstone_barf_mapper = { <EOL> ARM_CC_EQ : ARM_COND_CODE_EQ , <EOL> ARM_CC_NE : ARM_COND_CODE_NE , <EOL> ARM_CC_MI : ARM_COND_CODE_MI , <EOL> ARM_CC_PL : ARM_COND_CODE_PL , <EOL> ARM_CC_VS : ARM_COND_CODE_VS , <EOL> ARM_CC_VC : ARM_COND_CODE_VC , <EOL> ARM_CC_HI : ARM_COND_CODE_HI , <EOL> ARM_CC_LS : ARM_COND_CODE_LS , <EOL> ARM_CC_GE : ARM_COND_CODE_GE , <EOL> ARM_CC_LT : ARM_COND_CODE_LT , <EOL> ARM_CC_GT : ARM_COND_CODE_GT , <EOL> ARM_CC_LE : ARM_COND_CODE_LE , <EOL> ARM_CC_AL : ARM_COND_CODE_AL , <EOL> ARM_CC_HS : ARM_COND_CODE_HS , <EOL> ARM_CC_LO : ARM_COND_CODE_LO , <EOL> } <EOL> logger = logging . getLogger ( __name__ ) <EOL> class CapstoneOperandNotSupported ( Exception ) : <EOL> pass <EOL> class ArmDisassembler ( Disassembler ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , architecture_mode = ARCH_ARM_MODE_THUMB ) : <EOL> super ( ArmDisassembler , self ) . __init__ ( ) <EOL> self . _arch_mode = architecture_mode <EOL> self . _arch_info = ArmArchitectureInformation ( architecture_mode ) <EOL> self . _avaliable_disassemblers = { } <EOL> self . __setup_available_disassemblers ( ) <EOL> self . _disassembler = self . _avaliable_disassemblers [ architecture_mode ] <EOL> def disassemble ( self , data , address , architecture_mode = ARCH_ARM_MODE_THUMB ) : <EOL> """<STR_LIT>""" <EOL> self . _disassembler = self . _avaliable_disassemblers [ architecture_mode ] <EOL> disasm = self . _cs_disassemble_one ( data , address ) <EOL> instr = self . _cs_translate_insn ( disasm ) <EOL> if instr : <EOL> instr . address = address <EOL> instr . size = disasm . size <EOL> instr . bytes = data [ <NUM_LIT:0> : disasm . size ] <EOL> return instr <EOL> def disassemble_all ( self , data , address ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def _cs_disassemble_one ( self , data , address ) : <EOL> """<STR_LIT>""" <EOL> disasm = list ( self . _disassembler . disasm ( data , address ) ) <EOL> if len ( disasm ) > <NUM_LIT:0> : <EOL> return disasm [ <NUM_LIT:0> ] <EOL> else : <EOL> cs_arm = Cs ( CS_ARCH_ARM , CS_MODE_ARM ) <EOL> disasm = list ( cs_arm . disasm ( data , address ) ) <EOL> if len ( disasm ) > <NUM_LIT:0> : <EOL> return disasm [ <NUM_LIT:0> ] <EOL> else : <EOL> raise InvalidDisassemblerData ( "<STR_LIT>" . format ( hex ( address ) ) ) <EOL> def __setup_available_disassemblers ( self ) : <EOL> arch_map = { <EOL> ARCH_ARM_MODE_ARM : CS_MODE_ARM , <EOL> ARCH_ARM_MODE_THUMB : CS_MODE_THUMB , <EOL> } <EOL> self . _avaliable_disassemblers = { <EOL> ARCH_ARM_MODE_ARM : Cs ( CS_ARCH_ARM , arch_map [ ARCH_ARM_MODE_ARM ] ) , <EOL> ARCH_ARM_MODE_THUMB : Cs ( CS_ARCH_ARM , arch_map [ ARCH_ARM_MODE_THUMB ] ) , <EOL> } <EOL> self . _avaliable_disassemblers [ ARCH_ARM_MODE_ARM ] . detail = True <EOL> self . _avaliable_disassemblers [ ARCH_ARM_MODE_THUMB ] . detail = True <EOL> def __cs_reg_idx_to_arm_op_reg ( self , cs_reg_idx , cs_insn ) : <EOL> name = str ( cs_insn . reg_name ( cs_reg_idx ) ) <EOL> if name in arm_alias_reg_map : <EOL> name = arm_alias_reg_map [ name ] <EOL> if name in self . _arch_info . registers_size : <EOL> size = self . _arch_info . registers_size [ name ] <EOL> else : <EOL> size = self . _arch_info . architecture_size <EOL> return ArmRegisterOperand ( name , size ) <EOL> def __cs_shift_to_arm_op ( self , cs_op , cs_insn , arm_base ) : <EOL> if cs_op . shift . type == <NUM_LIT:0> : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> cs_shift_mapper = { <EOL> ARM_SFT_ASR : "<STR_LIT>" , <EOL> ARM_SFT_LSL : "<STR_LIT>" , <EOL> ARM_SFT_LSR : "<STR_LIT>" , <EOL> ARM_SFT_ROR : "<STR_LIT>" , <EOL> ARM_SFT_RRX : "<STR_LIT>" , <EOL> ARM_SFT_ASR_REG : "<STR_LIT>" , <EOL> ARM_SFT_LSL_REG : "<STR_LIT>" , <EOL> ARM_SFT_LSR_REG : "<STR_LIT>" , <EOL> ARM_SFT_ROR_REG : "<STR_LIT>" , <EOL> ARM_SFT_RRX_REG : "<STR_LIT>" , <EOL> } <EOL> sh_type = cs_shift_mapper [ cs_op . shift . type ] <EOL> if cs_op . shift . type <= ARM_SFT_RRX : <EOL> amount = ArmImmediateOperand ( cs_op . shift . value , self . _arch_info . operand_size ) <EOL> if cs_op . shift . value == <NUM_LIT:0> : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> elif cs_op . shift . type <= ARM_SFT_RRX_REG : <EOL> amount = self . __cs_reg_idx_to_arm_op_reg ( cs_op . shift . value , cs_insn ) <EOL> else : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> return ArmShiftedRegisterOperand ( arm_base , sh_type , amount , arm_base . size ) <EOL> def __cs_translate_operand ( self , cs_op , cs_insn ) : <EOL> if cs_op . type == ARM_OP_REG : <EOL> reg = self . __cs_reg_idx_to_arm_op_reg ( cs_op . value . reg , cs_insn ) <EOL> if cs_op . shift . type > <NUM_LIT:0> : <EOL> oprnd = self . __cs_shift_to_arm_op ( cs_op , cs_insn , reg ) <EOL> else : <EOL> oprnd = reg <EOL> elif cs_op . type == ARM_OP_IMM : <EOL> oprnd = ArmImmediateOperand ( cs_op . value . imm , self . _arch_info . operand_size ) <EOL> elif cs_op . type == ARM_OP_MEM : <EOL> reg_base = self . __cs_reg_idx_to_arm_op_reg ( cs_op . mem . base , cs_insn ) <EOL> index_type = ARM_MEMORY_INDEX_OFFSET <EOL> if cs_op . mem . index > <NUM_LIT:0> : <EOL> if cs_op . mem . disp > <NUM_LIT:0> : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> displacement = self . __cs_reg_idx_to_arm_op_reg ( cs_op . mem . index , cs_insn ) <EOL> if cs_insn . operands [ <NUM_LIT:0> ] . shift . type > <NUM_LIT:0> : <EOL> displacement = self . __cs_shift_to_arm_op ( cs_insn . operands [ <NUM_LIT:0> ] , cs_insn , displacement ) <EOL> else : <EOL> displacement = ArmImmediateOperand ( cs_op . mem . disp , self . _arch_info . operand_size ) <EOL> disp_minus = True if cs_op . mem . index == - <NUM_LIT:1> else False <EOL> oprnd = ArmMemoryOperand ( reg_base , index_type , displacement , disp_minus , self . _arch_info . operand_size ) <EOL> else : <EOL> oprnd = None <EOL> error_msg = "<STR_LIT>" + cs_insn . mnemonic + "<STR_LIT:U+0020>" + cs_insn . op_str + "<STR_LIT>" + str ( cs_op . type ) <EOL> logger . error ( error_msg ) <EOL> raise CapstoneOperandNotSupported ( error_msg ) <EOL> return oprnd <EOL> def _cs_translate_insn ( self , cs_insn ) : <EOL> operands = [ self . __cs_translate_operand ( op , cs_insn ) for op in cs_insn . operands ] <EOL> mnemonic = cs_insn . mnemonic <EOL> if "<STR_LIT:{>" in cs_insn . op_str : <EOL> reg_list = [ ] <EOL> op_translated = [ ] <EOL> if not ( "<STR_LIT>" in mnemonic or "<STR_LIT>" in mnemonic ) : <EOL> op_translated . append ( operands [ <NUM_LIT:0> ] ) <EOL> operands = operands [ <NUM_LIT:1> : ] <EOL> for r in operands : <EOL> reg_list . append ( [ r ] ) <EOL> op_translated . append ( ArmRegisterListOperand ( reg_list , reg_list [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] . size ) ) <EOL> operands = op_translated <EOL> if mnemonic [ - <NUM_LIT:2> : ] == "<STR_LIT>" or mnemonic [ - <NUM_LIT:2> : ] == "<STR_LIT>" : <EOL> mnemonic = mnemonic [ : - <NUM_LIT:2> ] <EOL> if cs_insn . cc != ARM_CC_INVALID and cs_insn . cc != ARM_CC_AL : <EOL> cc_suffix_str = cc_inverse_mapper [ cc_capstone_barf_mapper [ cs_insn . cc ] ] <EOL> if cc_suffix_str == mnemonic [ - <NUM_LIT:2> : ] : <EOL> mnemonic = mnemonic [ : - <NUM_LIT:2> ] <EOL> if cs_insn . update_flags and mnemonic [ - <NUM_LIT:1> ] == '<STR_LIT:s>' : <EOL> mnemonic = mnemonic [ : - <NUM_LIT:1> ] <EOL> if mnemonic [ <NUM_LIT:0> : <NUM_LIT:3> ] == "<STR_LIT>" or mnemonic [ <NUM_LIT:0> : <NUM_LIT:3> ] == "<STR_LIT>" : <EOL> ldm_stm_am = None <EOL> if mnemonic [ - <NUM_LIT:2> : ] in ldm_stm_am_mapper : <EOL> ldm_stm_am = ldm_stm_am_mapper [ mnemonic [ - <NUM_LIT:2> : ] ] <EOL> mnemonic = mnemonic [ : - <NUM_LIT:2> ] <EOL> if len ( operands ) == <NUM_LIT:2> and ( mnemonic == "<STR_LIT>" or <EOL> mnemonic == "<STR_LIT>" or <EOL> mnemonic == "<STR_LIT>" or <EOL> mnemonic == "<STR_LIT>" ) : <EOL> operands = [ operands [ <NUM_LIT:0> ] , operands [ <NUM_LIT:0> ] , operands [ <NUM_LIT:1> ] ] <EOL> instr = ArmInstruction ( <EOL> mnemonic + "<STR_LIT:U+0020>" + cs_insn . op_str , <EOL> mnemonic , <EOL> operands , <EOL> self . _arch_mode <EOL> ) <EOL> if cs_insn . cc != ARM_CC_INVALID : <EOL> instr . condition_code = cc_capstone_barf_mapper [ cs_insn . cc ] <EOL> if cs_insn . update_flags : <EOL> instr . update_flags = True <EOL> if mnemonic [ <NUM_LIT:0> : <NUM_LIT:3> ] == "<STR_LIT>" or mnemonic [ <NUM_LIT:0> : <NUM_LIT:3> ] == "<STR_LIT>" : <EOL> instr . ldm_stm_addr_mode = ldm_stm_am <EOL> if "<STR_LIT:!>" in cs_insn . op_str : <EOL> instr . operands [ <NUM_LIT:0> ] . wb = True <EOL> return instr </s>
