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 corrupt_bits(hi, lo, amount, instruction): """ Corrupt the bits in an instruction by fliping bits around :param hi: Corruption bit start :param lo: Corruption bit end :param amount: Number of bits to corrupt :param instruction: Instruction to corrupt :return: Returns the original instruction, as well as all the others resulting from the corruption """ # Generate random positions result, bits = [instruction], [] while len(bits) < amount: x = random.randint(lo, hi) if x not in bits: bits.append(x) for i in range(1, 2**amount): noise, j, m = 0, 1, math.log(i, 2) + 1 while j <= m: noise += Bits.on(bits[j - 1]) if j & i else 0 j <<= 1 noised = instruction ^ noise if noised not in result: result.append(noised) return result
def corrupt_all_bits(lo, hi, instruction): """ Corrupt all the bits from a given instruction from lo to hi bits :param hi: Hi bit to corrupt :param lo: Lo bit to corrupt :param instruction: Instruction to corrupt :return: the list of corrupted instructions """ result = [instruction] for i in range(lo, hi): k = len(result) mask = Bits.on(i) for j in range(0, k): masked = result[j] ^ mask if masked not in result: result.append(masked) return result
def corrupt_all_bits_tuples(tuples, instruction): """ Corrupt all the bits expressed as a list of (hi, lo) tuples in a given instruction. Lazy me, this routine assumes that the hi and lo bits of the tuples do not intersect, i.e. having tuples like (0, 2) and (1, 3) which intersects in 1 and 2 produces unexpected results :param tuples: Bits to corrupt :param instruction: Instruction to corrupt :return: the list of corrupted instructions """ size = 0 for t in tuples: l, h = t Bits.check_range(l, h) size += h - l result = [instruction] * (2**size) kk = 1 for t in tuples: l, h = t for i in range(l, h): for k in range(0, kk): result[kk + k] = result[k] ^ Bits.on(i) kk *= 2 return result
def is_branch_with_link(self): return self.is_branch and (self.encoding & Bits.on(24))
def test_on(self): self.assertEqual(2**31, Bits.on(31)) self.assertTrue(1, Bits.on(0))