def jumping_address(self): if self._jumping_address is None: # On the other hand, one can compute the jumping address address = self.encoding & Bits.set(23, 0) if Bits.is_on(address, 23): address |= Bits.set(29, 24) address = (address << 2) address += self.address + 8 address &= 0xffffffff self._jumping_address = address return self._jumping_address
class AOpType(object): """ ARM Opcodes types. The cryptic AOpType name is to have short code """ ALWAYS = Bits.set(31, 29) COND_ALWAYS = 0b1110 LOAD_STORE_MULTIPLE = Bits.on(27) LOAD_STORE = Bits.on(26) LOAD_STORE_OFFSET = Bits.set(26, 25) SOFT_INTERRUPT = 0xF000000 BRANCH = 0xA000000 DATA_PROCESSING = 0x0 DATA_PROCESSING_IMMEDIATE = 0x2000000
def jumping_address(self): """ Jumping address for branching instructions """ if self.is_branch: if self._jumping_address is None: # On the other hand, one can compute the jumping address address = self.encoding & Bits.set(23, 0) if Bits.is_on(address, 23): address |= Bits.set(29, 24) address = (address << 2) address += self.address + 8 address &= 0xffffffff self._jumping_address = address return self._jumping_address return None
def opcode_field(self): """ Return the instruction part of the opcode for an ARM instruction (See the 'ARM ARM') :return: A number with the instruction part """ t = self.opcode_type() if t in [AOpType.BRANCH, AOpType.SOFT_INTERRUPT]: return t return self.encoding & Bits.set(24, 21)
def test_corrupt_bits(self): # ldr r5, [pc, #44] corrupted = corrupt_bits(31, 28, 2, 0xe59f502c) self.assertEqual(4, len(corrupted)) mask = Bits.set(31, 28) self.assertTrue(corrupted[0] & mask == AOpType.ALWAYS) self.assertFalse(corrupted[1] & mask == AOpType.ALWAYS) self.assertFalse(corrupted[2] & mask == AOpType.ALWAYS) self.assertFalse(corrupted[3] & mask == AOpType.ALWAYS)
def test_corrupt_conditional(self): # ldr r5, [pc, #44] corrupted = corrupt_conditional(2, 0xe59f502c) self.assertEqual(4, len(corrupted)) mask = Bits.set(31, 28) self.assertTrue((corrupted[0] & mask) == AOpType.ALWAYS) self.assertFalse((corrupted[1] & mask) == AOpType.ALWAYS, "{:b} - {:b}".format(corrupted[1], AOpType.ALWAYS)) self.assertFalse((corrupted[2] & mask) == AOpType.ALWAYS, "{:b} - {:b}".format(corrupted[2], AOpType.ALWAYS)) self.assertFalse((corrupted[3] & mask) == AOpType.ALWAYS, "{:b} - {:b}".format(corrupted[3], AOpType.ALWAYS))
def _rs_field_(self): """ Returns the Rd register field """ return (self.encoding & Bits.set(11, 8)) >> 8
def _rd_field_(self): """ Returns the Rd register field """ return (self.encoding & Bits.set(15, 12)) >> 12
def _rn_field_(self): """ Returns the Rn register field """ return (self.encoding & Bits.set(19, 16)) >> 16
def test_set(self): self.assertEqual(0xE0000000, Bits.set(31, 29))