Ejemplo n.º 1
0
    def __init__ (self, binary):
        self.elf = elffile.ELFFile(binary)

        if self.elf.elfclass == 32:
            self.arch_info = X86ArchitectureInformation(ARCH_X86_MODE_32)
        if self.elf.elfclass == 64:
            self.arch_info = X86ArchitectureInformation(ARCH_X86_MODE_64)

        self.emulator = ReilEmulator(self.arch_info.address_size)
        self.emulator.set_arch_registers(self.arch_info.registers_gp)
        self.emulator.set_arch_registers_size(self.arch_info.register_size)
        self.emulator.set_reg_access_mapper(self.arch_info.register_access_mapper())

        self.classifier = GadgetClassifier(self.emulator, self.arch_info)

        self.smt_solver = SmtSolver()
        self.smt_translator = SmtTranslator(self.smt_solver, self.arch_info.address_size)

        self.smt_translator.set_reg_access_mapper(self.arch_info.register_access_mapper())
        self.smt_translator.set_arch_registers_size(self.arch_info.register_size)

        self.code_analyzer = CodeAnalyzer(self.smt_solver, self.smt_translator)

        self.gadgets = {}
        self.classified_gadgets = {}

        self.regset = RegSet(self)
        self.ccf = CCFlag(self)
        self.ams = ArithmeticStore(self)
        self.memstr = MemoryStore(self)

        self.reil_translator = X86Translator(architecture_mode=self.arch_info.architecture_mode,
                                                  translation_mode=FULL_TRANSLATION)
Ejemplo n.º 2
0
    def setUp(self):

        self._arch_info = ArmArchitectureInformation(ARCH_ARM_MODE_ARM)
        self._smt_solver = SmtSolver()
        self._smt_translator = SmtTranslator(self._smt_solver,
                                             self._arch_info.address_size)

        self._ir_emulator = ReilEmulator(self._arch_info)

        self._smt_translator.set_arch_alias_mapper(
            self._arch_info.alias_mapper)
        self._smt_translator.set_arch_registers_size(
            self._arch_info.registers_size)

        self._code_analyzer = CodeAnalyzer(self._smt_solver,
                                           self._smt_translator,
                                           self._arch_info)

        self._g_classifier = GadgetClassifier(self._ir_emulator,
                                              self._arch_info)
        self._g_verifier = GadgetVerifier(self._code_analyzer, self._arch_info)
Ejemplo n.º 3
0
    def setUp(self):

        self._arch_info = ArmArchitectureInformation(ARCH_ARM_MODE_ARM)
        self._smt_solver = SmtSolver()
        self._smt_translator = SmtTranslator(self._smt_solver, self._arch_info.address_size)

        self._ir_emulator = ReilEmulator(self._arch_info)

        self._smt_translator.set_arch_alias_mapper(self._arch_info.alias_mapper)
        self._smt_translator.set_arch_registers_size(self._arch_info.registers_size)

        self._code_analyzer = CodeAnalyzer(self._smt_solver, self._smt_translator, self._arch_info)

        self._g_classifier = GadgetClassifier(self._ir_emulator, self._arch_info)
        self._g_verifier = GadgetVerifier(self._code_analyzer, self._arch_info)
Ejemplo n.º 4
0
class ArmGadgetClassifierTests(unittest.TestCase):
    def setUp(self):

        self._arch_info = ArmArchitectureInformation(ARCH_ARM_MODE_32)
        self._smt_solver = SmtSolver()
        self._smt_translator = SmtTranslator(self._smt_solver,
                                             self._arch_info.address_size)
        self._ir_emulator = ReilEmulator(self._arch_info.address_size)

        self._ir_emulator.set_arch_registers(self._arch_info.registers_gp_all)
        self._ir_emulator.set_arch_registers_size(
            self._arch_info.registers_size)
        self._ir_emulator.set_reg_access_mapper(self._arch_info.alias_mapper)

        self._smt_translator.set_reg_access_mapper(
            self._arch_info.alias_mapper)
        self._smt_translator.set_arch_registers_size(
            self._arch_info.registers_size)

        self._code_analyzer = CodeAnalyzer(self._smt_solver,
                                           self._smt_translator)

        self._g_classifier = GadgetClassifier(self._ir_emulator,
                                              self._arch_info)
        self._g_verifier = GadgetVerifier(self._code_analyzer, self._arch_info)

    def _find_and_classify_gadgets(self, binary):
        g_finder = GadgetFinder(
            ArmDisassembler(), binary,
            ArmTranslator(translation_mode=LITE_TRANSLATION), ARCH_ARM,
            ARCH_ARM_MODE_32)

        g_candidates = g_finder.find(0x00000000, len(binary), instrs_depth=4)
        g_classified = self._g_classifier.classify(g_candidates[0])

        #         Debug:
        #         self._print_candidates(g_candidates)
        #         self._print_classified(g_classified)

        return g_candidates, g_classified

    def test_move_register_1(self):
        # testing : dst_reg <- src_reg
        binary = "\x04\x00\xa0\xe1"  # 0x00 : (4)  mov    r0, r4
        binary += "\x31\xff\x2f\xe1"  # 0x04 : (4)  blx    r1

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 2)

        self.assertEquals(g_classified[0].type, GadgetType.MoveRegister)
        self.assertEquals(g_classified[0].sources,
                          [ReilRegisterOperand("r4", 32)])
        self.assertEquals(g_classified[0].destination,
                          [ReilRegisterOperand("r0", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 1)
        self.assertTrue(
            ReilRegisterOperand("r14", 32) in
            g_classified[0].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_move_register_2(self):
        # testing : dst_reg <- src_reg
        binary = "\x00\x00\x84\xe2"  # 0x00 : (4)  add    r0, r4, #0
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.MoveRegister)
        self.assertEquals(g_classified[0].sources,
                          [ReilRegisterOperand("r4", 32)])
        self.assertEquals(g_classified[0].destination,
                          [ReilRegisterOperand("r0", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    # TODO: test_move_register_n: mul r0, r4, #1

    def test_load_constant_1(self):
        # testing : dst_reg <- constant
        binary = "\x0a\x20\xa0\xe3"  # 0x00 : (4)  mov    r2, #10
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadConstant)
        self.assertEquals(g_classified[0].sources,
                          [ReilImmediateOperand(10, 32)])
        self.assertEquals(g_classified[0].destination,
                          [ReilRegisterOperand("r2", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)
        self.assertFalse(
            ReilRegisterOperand("r2", 32) in
            g_classified[0].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_load_constant_2(self):
        # testing : dst_reg <- constant
        binary = "\x02\x20\x42\xe0"  # 0x00 : (4)  sub    r2, r2, r2
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadConstant)
        self.assertEquals(g_classified[0].sources,
                          [ReilImmediateOperand(0, 32)])
        self.assertEquals(g_classified[0].destination,
                          [ReilRegisterOperand("r2", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)
        self.assertFalse(
            ReilRegisterOperand("r2", 32) in
            g_classified[0].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_load_constant_3(self):
        # testing : dst_reg <- constant
        binary = "\x02\x20\x22\xe0"  # 0x00 : (4)  eor    r2, r2, r2
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadConstant)
        self.assertEquals(g_classified[0].sources,
                          [ReilImmediateOperand(0, 32)])
        self.assertEquals(g_classified[0].destination,
                          [ReilRegisterOperand("r2", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)
        self.assertFalse(
            ReilRegisterOperand("r2", 32) in
            g_classified[0].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_load_constant_4(self):
        # testing : dst_reg <- constant
        binary = "\x00\x20\x02\xe2"  # 0x00 : (4)  and    r2, r2, #0
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadConstant)
        self.assertEquals(g_classified[0].sources,
                          [ReilImmediateOperand(0, 32)])
        self.assertEquals(g_classified[0].destination,
                          [ReilRegisterOperand("r2", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)
        self.assertFalse(
            ReilRegisterOperand("r2", 32) in
            g_classified[0].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_load_constant_5(self):
        # testing : dst_reg <- constant
        binary = "\x00\x20\x02\xe2"  # and    r2, r2, #0
        binary += "\x21\x20\x82\xe3"  # orr    r2, r2, #33
        binary += "\x1e\xff\x2f\xe1"  # bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadConstant)
        self.assertEquals(g_classified[0].sources,
                          [ReilImmediateOperand(33, 32)])
        self.assertEquals(g_classified[0].destination,
                          [ReilRegisterOperand("r2", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)
        self.assertFalse(
            ReilRegisterOperand("r2", 32) in
            g_classified[0].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_arithmetic_add_1(self):
        # testing : dst_reg <- src1_reg + src2_reg
        binary = "\x08\x00\x84\xe0"  # 0x00 : (4)  add    r0, r4, r8
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.Arithmetic)
        self.assertEquals(
            g_classified[0].sources,
            [ReilRegisterOperand("r4", 32),
             ReilRegisterOperand("r8", 32)])
        self.assertEquals(g_classified[0].destination,
                          [ReilRegisterOperand("r0", 32)])
        self.assertEquals(g_classified[0].operation, "+")

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_arithmetic_sub_1(self):
        # testing : dst_reg <- src1_reg + src2_reg
        binary = "\x08\x00\x44\xe0"  # 0x00 : (4)  sub    r0, r4, r8
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.Arithmetic)
        self.assertEquals(
            g_classified[0].sources,
            [ReilRegisterOperand("r4", 32),
             ReilRegisterOperand("r8", 32)])
        self.assertEquals(g_classified[0].destination,
                          [ReilRegisterOperand("r0", 32)])
        self.assertEquals(g_classified[0].operation, "-")

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_load_memory_1(self):
        # testing : dst_reg <- m[src_reg]
        binary = "\x00\x30\x94\xe5"  # 0x00 : (4)  ldr    r3, [r4]
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadMemory)
        self.assertEquals(
            g_classified[0].sources,
            [ReilRegisterOperand("r4", 32),
             ReilImmediateOperand(0x0, 32)])
        self.assertEquals(g_classified[0].destination,
                          [ReilRegisterOperand("r3", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_load_memory_2(self):
        # testing : dst_reg <- m[src_reg + offset]
        binary = "\x33\x30\x94\xe5"  # 0x00 : (4)  ldr    r3, [r4 + 0x33]
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadMemory)
        self.assertEquals(
            g_classified[0].sources,
            [ReilRegisterOperand("r4", 32),
             ReilImmediateOperand(0x33, 32)])
        self.assertEquals(g_classified[0].destination,
                          [ReilRegisterOperand("r3", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    # TODO: ARM's ldr rd, [rn, r2] is not a valid classification right now

    def test_store_memory_1(self):
        # testing : dst_reg <- m[src_reg]
        binary = "\x00\x30\x84\xe5"  # 0x00 : (4)  str    r3, [r4]
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.StoreMemory)
        self.assertEquals(g_classified[0].sources,
                          [ReilRegisterOperand("r3", 32)])
        self.assertEquals(
            g_classified[0].destination,
            [ReilRegisterOperand("r4", 32),
             ReilImmediateOperand(0x0, 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_store_memory_2(self):
        # testing : dst_reg <- m[src_reg + offset]
        binary = "\x33\x30\x84\xe5"  # 0x00 : (4)  str    r3, [r4 + 0x33]
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.StoreMemory)
        self.assertEquals(g_classified[0].sources,
                          [ReilRegisterOperand("r3", 32)])
        self.assertEquals(
            g_classified[0].destination,
            [ReilRegisterOperand("r4", 32),
             ReilImmediateOperand(0x33, 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_arithmetic_load_add_1(self):
        # testing : dst_reg <- dst_reg + mem[src_reg]
        binary = "\x00\x30\x94\xe5"  # 0x00 : (4)  ldr    r3, [r4]
        binary += "\x03\x00\x80\xe0"  # 0x00 : (4)  add    r0, r0, r3
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 2)

        self.assertEquals(g_classified[1].type, GadgetType.ArithmeticLoad)
        self.assertEquals(g_classified[1].sources, [
            ReilRegisterOperand("r0", 32),
            ReilRegisterOperand("r4", 32),
            ReilImmediateOperand(0x0, 32)
        ])
        self.assertEquals(g_classified[1].destination,
                          [ReilRegisterOperand("r0", 32)])
        self.assertEquals(g_classified[1].operation, "+")

        self.assertEquals(len(g_classified[1].modified_registers), 1)

        self.assertFalse(
            ReilRegisterOperand("r0", 32) in
            g_classified[1].modified_registers)
        self.assertTrue(
            ReilRegisterOperand("r3", 32) in
            g_classified[1].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[1]))

    def test_arithmetic_load_add_2(self):
        # testing : dst_reg <- dst_reg + mem[src_reg + offset]
        binary = "\x22\x30\x94\xe5"  # 0x00 : (4)  ldr    r3, [r4, 0x22]
        binary += "\x03\x00\x80\xe0"  # 0x00 : (4)  add    r0, r0, r3
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 2)

        self.assertEquals(g_classified[1].type, GadgetType.ArithmeticLoad)
        self.assertEquals(g_classified[1].sources, [
            ReilRegisterOperand("r0", 32),
            ReilRegisterOperand("r4", 32),
            ReilImmediateOperand(0x22, 32)
        ])
        self.assertEquals(g_classified[1].destination,
                          [ReilRegisterOperand("r0", 32)])
        self.assertEquals(g_classified[1].operation, "+")

        self.assertEquals(len(g_classified[1].modified_registers), 1)

        self.assertFalse(
            ReilRegisterOperand("r0", 32) in
            g_classified[1].modified_registers)
        self.assertTrue(
            ReilRegisterOperand("r3", 32) in
            g_classified[1].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[1]))

    def test_arithmetic_store_add_1(self):
        # testing : m[dst_reg] <- m[dst_reg] + src_reg
        binary = "\x00\x30\x94\xe5"  # 0x00 : (4)  ldr    r3, [r4]
        binary += "\x03\x30\x80\xe0"  # 0x00 : (4)  add    r3, r0, r3
        binary += "\x00\x30\x84\xe5"  # 0x00 : (4)  str    r3, [r4]
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 2)

        self.assertEquals(g_classified[1].type, GadgetType.ArithmeticStore)
        self.assertEquals(g_classified[1].sources, [
            ReilRegisterOperand("r4", 32),
            ReilImmediateOperand(0x0, 32),
            ReilRegisterOperand("r0", 32)
        ])
        self.assertEquals(
            g_classified[1].destination,
            [ReilRegisterOperand("r4", 32),
             ReilImmediateOperand(0x0, 32)])
        self.assertEquals(g_classified[1].operation, "+")

        self.assertEquals(len(g_classified[1].modified_registers), 1)

        self.assertFalse(
            ReilRegisterOperand("r4", 32) in
            g_classified[1].modified_registers)
        self.assertTrue(
            ReilRegisterOperand("r3", 32) in
            g_classified[1].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[1]))

    def test_arithmetic_store_add_2(self):
        # testing : dst_reg <- dst_reg + mem[src_reg + offset]
        binary = "\x22\x30\x94\xe5"  # 0x00 : (4)  ldr    r3, [r4, 0x22]
        binary += "\x03\x30\x80\xe0"  # 0x00 : (4)  add    r3, r0, r3
        binary += "\x22\x30\x84\xe5"  # 0x00 : (4)  str    r3, [r4, 0x22]
        binary += "\x1e\xff\x2f\xe1"  # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 2)

        self.assertEquals(g_classified[1].type, GadgetType.ArithmeticStore)
        self.assertEquals(g_classified[1].sources, [
            ReilRegisterOperand("r4", 32),
            ReilImmediateOperand(0x22, 32),
            ReilRegisterOperand("r0", 32)
        ])
        self.assertEquals(
            g_classified[1].destination,
            [ReilRegisterOperand("r4", 32),
             ReilImmediateOperand(0x22, 32)])
        self.assertEquals(g_classified[1].operation, "+")

        self.assertEquals(len(g_classified[1].modified_registers), 1)

        self.assertFalse(
            ReilRegisterOperand("r4", 32) in
            g_classified[1].modified_registers)
        self.assertTrue(
            ReilRegisterOperand("r3", 32) in
            g_classified[1].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[1]))

    def _print_candidates(self, candidates):
        print "Candidates :"

        for gadget in candidates:
            print gadget
            print "-" * 10

    def _print_classified(self, classified):
        print "Classified :"

        for gadget in classified:
            print gadget
            print gadget.type
            print "-" * 10
Ejemplo n.º 5
0
class ArmGadgetClassifierTests(unittest.TestCase):

    def setUp(self):

        self._arch_info = ArmArchitectureInformation(ARCH_ARM_MODE_32)
        self._smt_solver = SmtSolver()
        self._smt_translator = SmtTranslator(self._smt_solver, self._arch_info.address_size)
        self._ir_emulator = ReilEmulator(self._arch_info.address_size)

        self._ir_emulator.set_arch_registers(self._arch_info.registers_gp_all)
        self._ir_emulator.set_arch_registers_size(self._arch_info.registers_size)
        self._ir_emulator.set_reg_access_mapper(self._arch_info.alias_mapper)

        self._smt_translator.set_reg_access_mapper(self._arch_info.alias_mapper)
        self._smt_translator.set_arch_registers_size(self._arch_info.registers_size)

        self._code_analyzer = CodeAnalyzer(self._smt_solver, self._smt_translator)

        self._g_classifier = GadgetClassifier(self._ir_emulator, self._arch_info)
        self._g_verifier = GadgetVerifier(self._code_analyzer, self._arch_info)

    def _find_and_classify_gadgets(self, binary):
        g_finder = GadgetFinder(ArmDisassembler(), binary, ArmTranslator(translation_mode=LITE_TRANSLATION), ARCH_ARM, ARCH_ARM_MODE_32)

        g_candidates = g_finder.find(0x00000000, len(binary), instrs_depth=4)
        g_classified = self._g_classifier.classify(g_candidates[0])

#         Debug:
#         self._print_candidates(g_candidates)
#         self._print_classified(g_classified)

        return g_candidates, g_classified

    def test_move_register_1(self):
        # testing : dst_reg <- src_reg
        binary  = "\x04\x00\xa0\xe1"                     # 0x00 : (4)  mov    r0, r4
        binary += "\x31\xff\x2f\xe1"                     # 0x04 : (4)  blx    r1

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 2)

        self.assertEquals(g_classified[0].type, GadgetType.MoveRegister)
        self.assertEquals(g_classified[0].sources, [ReilRegisterOperand("r4", 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r0", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 1)
        self.assertTrue(ReilRegisterOperand("r14", 32) in g_classified[0].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_move_register_2(self):
        # testing : dst_reg <- src_reg
        binary  = "\x00\x00\x84\xe2"                     # 0x00 : (4)  add    r0, r4, #0
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr


        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.MoveRegister)
        self.assertEquals(g_classified[0].sources, [ReilRegisterOperand("r4", 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r0", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    # TODO: test_move_register_n: mul r0, r4, #1

    def test_load_constant_1(self):
        # testing : dst_reg <- constant
        binary  = "\x0a\x20\xa0\xe3"                     # 0x00 : (4)  mov    r2, #10
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadConstant)
        self.assertEquals(g_classified[0].sources, [ReilImmediateOperand(10, 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r2", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)
        self.assertFalse(ReilRegisterOperand("r2", 32) in g_classified[0].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_load_constant_2(self):
        # testing : dst_reg <- constant
        binary  = "\x02\x20\x42\xe0"                     # 0x00 : (4)  sub    r2, r2, r2
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadConstant)
        self.assertEquals(g_classified[0].sources, [ReilImmediateOperand(0, 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r2", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)
        self.assertFalse(ReilRegisterOperand("r2", 32) in g_classified[0].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_load_constant_3(self):
        # testing : dst_reg <- constant
        binary  = "\x02\x20\x22\xe0"                     # 0x00 : (4)  eor    r2, r2, r2
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadConstant)
        self.assertEquals(g_classified[0].sources, [ReilImmediateOperand(0, 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r2", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)
        self.assertFalse(ReilRegisterOperand("r2", 32) in g_classified[0].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_load_constant_4(self):
        # testing : dst_reg <- constant
        binary  = "\x00\x20\x02\xe2"                     # 0x00 : (4)  and    r2, r2, #0
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadConstant)
        self.assertEquals(g_classified[0].sources, [ReilImmediateOperand(0, 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r2", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)
        self.assertFalse(ReilRegisterOperand("r2", 32) in g_classified[0].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_load_constant_5(self):
        # testing : dst_reg <- constant
        binary  = "\x00\x20\x02\xe2"                     # and    r2, r2, #0
        binary += "\x21\x20\x82\xe3"                     # orr    r2, r2, #33
        binary += "\x1e\xff\x2f\xe1"                     # bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadConstant)
        self.assertEquals(g_classified[0].sources, [ReilImmediateOperand(33, 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r2", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)
        self.assertFalse(ReilRegisterOperand("r2", 32) in g_classified[0].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_arithmetic_add_1(self):
        # testing : dst_reg <- src1_reg + src2_reg
        binary  = "\x08\x00\x84\xe0"                     # 0x00 : (4)  add    r0, r4, r8
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.Arithmetic)
        self.assertEquals(g_classified[0].sources, [ReilRegisterOperand("r4", 32), ReilRegisterOperand("r8", 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r0", 32)])
        self.assertEquals(g_classified[0].operation, "+")

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_arithmetic_sub_1(self):
        # testing : dst_reg <- src1_reg + src2_reg
        binary  = "\x08\x00\x44\xe0"                     # 0x00 : (4)  sub    r0, r4, r8
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.Arithmetic)
        self.assertEquals(g_classified[0].sources, [ReilRegisterOperand("r4", 32), ReilRegisterOperand("r8", 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r0", 32)])
        self.assertEquals(g_classified[0].operation, "-")

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_load_memory_1(self):
        # testing : dst_reg <- m[src_reg]
        binary  = "\x00\x30\x94\xe5"                     # 0x00 : (4)  ldr    r3, [r4]
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadMemory)
        self.assertEquals(g_classified[0].sources, [ReilRegisterOperand("r4", 32), ReilImmediateOperand(0x0, 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r3", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_load_memory_2(self):
        # testing : dst_reg <- m[src_reg + offset]
        binary  = "\x33\x30\x94\xe5"                     # 0x00 : (4)  ldr    r3, [r4 + 0x33]
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.LoadMemory)
        self.assertEquals(g_classified[0].sources, [ReilRegisterOperand("r4", 32), ReilImmediateOperand(0x33, 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r3", 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    # TODO: ARM's ldr rd, [rn, r2] is not a valid classification right now

    def test_store_memory_1(self):
        # testing : dst_reg <- m[src_reg]
        binary  = "\x00\x30\x84\xe5"                     # 0x00 : (4)  str    r3, [r4]
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.StoreMemory)
        self.assertEquals(g_classified[0].sources, [ReilRegisterOperand("r3", 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r4", 32), ReilImmediateOperand(0x0, 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_store_memory_2(self):
        # testing : dst_reg <- m[src_reg + offset]
        binary  = "\x33\x30\x84\xe5"                     # 0x00 : (4)  str    r3, [r4 + 0x33]
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 1)

        self.assertEquals(g_classified[0].type, GadgetType.StoreMemory)
        self.assertEquals(g_classified[0].sources, [ReilRegisterOperand("r3", 32)])
        self.assertEquals(g_classified[0].destination, [ReilRegisterOperand("r4", 32), ReilImmediateOperand(0x33, 32)])

        self.assertEquals(len(g_classified[0].modified_registers), 0)

        self.assertTrue(self._g_verifier.verify(g_classified[0]))

    def test_arithmetic_load_add_1(self):
        # testing : dst_reg <- dst_reg + mem[src_reg]
        binary  = "\x00\x30\x94\xe5"                     # 0x00 : (4)  ldr    r3, [r4]
        binary += "\x03\x00\x80\xe0"                     # 0x00 : (4)  add    r0, r0, r3
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 2)

        self.assertEquals(g_classified[1].type, GadgetType.ArithmeticLoad)
        self.assertEquals(g_classified[1].sources, [ReilRegisterOperand("r0", 32), ReilRegisterOperand("r4", 32), ReilImmediateOperand(0x0, 32)])
        self.assertEquals(g_classified[1].destination, [ReilRegisterOperand("r0", 32)])
        self.assertEquals(g_classified[1].operation, "+")

        self.assertEquals(len(g_classified[1].modified_registers), 1)

        self.assertFalse(ReilRegisterOperand("r0", 32) in g_classified[1].modified_registers)
        self.assertTrue(ReilRegisterOperand("r3", 32) in g_classified[1].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[1]))

    def test_arithmetic_load_add_2(self):
        # testing : dst_reg <- dst_reg + mem[src_reg + offset]
        binary  = "\x22\x30\x94\xe5"                     # 0x00 : (4)  ldr    r3, [r4, 0x22]
        binary += "\x03\x00\x80\xe0"                     # 0x00 : (4)  add    r0, r0, r3
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 2)

        self.assertEquals(g_classified[1].type, GadgetType.ArithmeticLoad)
        self.assertEquals(g_classified[1].sources, [ReilRegisterOperand("r0", 32), ReilRegisterOperand("r4", 32), ReilImmediateOperand(0x22, 32)])
        self.assertEquals(g_classified[1].destination, [ReilRegisterOperand("r0", 32)])
        self.assertEquals(g_classified[1].operation, "+")

        self.assertEquals(len(g_classified[1].modified_registers), 1)

        self.assertFalse(ReilRegisterOperand("r0", 32) in g_classified[1].modified_registers)
        self.assertTrue(ReilRegisterOperand("r3", 32) in g_classified[1].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[1]))

    def test_arithmetic_store_add_1(self):
        # testing : m[dst_reg] <- m[dst_reg] + src_reg
        binary  = "\x00\x30\x94\xe5"                     # 0x00 : (4)  ldr    r3, [r4]
        binary += "\x03\x30\x80\xe0"                     # 0x00 : (4)  add    r3, r0, r3
        binary += "\x00\x30\x84\xe5"                     # 0x00 : (4)  str    r3, [r4]
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 2)

        self.assertEquals(g_classified[1].type, GadgetType.ArithmeticStore)
        self.assertEquals(g_classified[1].sources, [ReilRegisterOperand("r4", 32), ReilImmediateOperand(0x0, 32), ReilRegisterOperand("r0", 32)])
        self.assertEquals(g_classified[1].destination, [ReilRegisterOperand("r4", 32), ReilImmediateOperand(0x0, 32)])
        self.assertEquals(g_classified[1].operation, "+")

        self.assertEquals(len(g_classified[1].modified_registers), 1)

        self.assertFalse(ReilRegisterOperand("r4", 32) in g_classified[1].modified_registers)
        self.assertTrue(ReilRegisterOperand("r3", 32) in g_classified[1].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[1]))

    def test_arithmetic_store_add_2(self):
        # testing : dst_reg <- dst_reg + mem[src_reg + offset]
        binary  = "\x22\x30\x94\xe5"                     # 0x00 : (4)  ldr    r3, [r4, 0x22]
        binary += "\x03\x30\x80\xe0"                     # 0x00 : (4)  add    r3, r0, r3
        binary += "\x22\x30\x84\xe5"                     # 0x00 : (4)  str    r3, [r4, 0x22]
        binary += "\x1e\xff\x2f\xe1"                     # 0x04 : (4)  bx     lr

        g_candidates, g_classified = self._find_and_classify_gadgets(binary)

        self.assertEquals(len(g_candidates), 1)
        self.assertEquals(len(g_classified), 2)

        self.assertEquals(g_classified[1].type, GadgetType.ArithmeticStore)
        self.assertEquals(g_classified[1].sources, [ReilRegisterOperand("r4", 32), ReilImmediateOperand(0x22, 32), ReilRegisterOperand("r0", 32)])
        self.assertEquals(g_classified[1].destination, [ReilRegisterOperand("r4", 32), ReilImmediateOperand(0x22, 32)])
        self.assertEquals(g_classified[1].operation, "+")

        self.assertEquals(len(g_classified[1].modified_registers), 1)

        self.assertFalse(ReilRegisterOperand("r4", 32) in g_classified[1].modified_registers)
        self.assertTrue(ReilRegisterOperand("r3", 32) in g_classified[1].modified_registers)

        self.assertTrue(self._g_verifier.verify(g_classified[1]))

    def _print_candidates(self, candidates):
        print "Candidates :"

        for gadget in candidates:
            print gadget
            print "-" * 10

    def _print_classified(self, classified):
        print "Classified :"

        for gadget in classified:
            print gadget
            print gadget.type
            print "-" * 10
Ejemplo n.º 6
0
class GadgetTools():
    def __init__ (self, binary):
        self.elf = elffile.ELFFile(binary)

        if self.elf.elfclass == 32:
            self.arch_info = X86ArchitectureInformation(ARCH_X86_MODE_32)
        if self.elf.elfclass == 64:
            self.arch_info = X86ArchitectureInformation(ARCH_X86_MODE_64)

        self.emulator = ReilEmulator(self.arch_info.address_size)
        self.emulator.set_arch_registers(self.arch_info.registers_gp)
        self.emulator.set_arch_registers_size(self.arch_info.register_size)
        self.emulator.set_reg_access_mapper(self.arch_info.register_access_mapper())

        self.classifier = GadgetClassifier(self.emulator, self.arch_info)

        self.smt_solver = SmtSolver()
        self.smt_translator = SmtTranslator(self.smt_solver, self.arch_info.address_size)

        self.smt_translator.set_reg_access_mapper(self.arch_info.register_access_mapper())
        self.smt_translator.set_arch_registers_size(self.arch_info.register_size)

        self.code_analyzer = CodeAnalyzer(self.smt_solver, self.smt_translator)

        self.gadgets = {}
        self.classified_gadgets = {}

        self.regset = RegSet(self)
        self.ccf = CCFlag(self)
        self.ams = ArithmeticStore(self)
        self.memstr = MemoryStore(self)

        self.reil_translator = X86Translator(architecture_mode=self.arch_info.architecture_mode,
                                                  translation_mode=FULL_TRANSLATION)




    def find_gadgets(self, max_instr=10, max_bytes=15):
        logging.info('searching gadgets in binary..')
        for s in self.elf.iter_sections():
            if (s.header.sh_type == 'SHT_PROGBITS') and (s.header.sh_flags & 0x4):
                sz = s.header.sh_size
                base = s.header.sh_addr
                mem = Memory(lambda x, y : s.data()[x - base], None)
                gfinder = GadgetFinder(X86Disassembler(architecture_mode=self.arch_info.architecture_mode),
                                    mem,
                                    self.reil_translator)

                logging.info("searching gadgets in section " + s.name + "...")

                for g in gfinder.find(base, base + sz - 1, max_instr, max_bytes):
                    ret = g.instrs[-1].asm_instr
                    if not isinstance(ret, Ret):
                        continue
                    if len(ret.operands) > 0 and ret.operands[0].immediate > 0x10:
                        continue

                    self.gadgets[g.address] = g

                logging.info("found {0} gadgets".format(len(self.gadgets)))

    def classify_gadgets(self):
        #setting 0 to cf flags to avoid impossible random value invalidates results

        rflags =  self.classifier.set_reg_init({'cf': 0})

        for g in self.gadgets.itervalues():
            tgs = self.classifier.classify(g)
            for tg in tgs:
                if tg.type not in self.classified_gadgets:
                    self.classified_gadgets[tg.type] = []

                self.classified_gadgets[tg.type].append(tg)



    def find_reg_set_gadgets(self):
        self.regset.add(self.gadgets.itervalues())


    def read_carrier_flag(self, g):
        self.emulator.reset()
        regs_init = utils.make_random_regs_context(self.arch_info)

        self.emulator.execute_lite(g.get_ir_instrs(), regs_init)

        return 'eflags' in self.emulator.registers


    def find_arithmetic_mem_set_gadgets(self):
        self.ams.add(self.classified_gadgets[GadgetType.ArithmeticStore])

    def get_stack_slide_chunk(self, slide):
        #TODO not use only pop gadgets and chain more slide if we wan't longer slide
        return self.regset.get_slide_stack_chunk(slide)


    def get_ret_func_chunk(self, args, address):
        """Return a chainable chunk that return to address and set up args or registers as if a function was called with args.

        Args:

        args (list): the list of args to setup as function arguments
        address (int): the address where to return

        """
        if self.arch_info.architecture_size == 64:
            if len(args) > 6:
                raise BaseException("chunk for calling a function whit more of six args isn't implemented")

            args_regs = ['rdi', 'rsi', 'rdx', 'rcx', 'r8', 'r9']
            regs_values = {args_regs[i] : a for i, a in enumerate(args)}
            regs_c = self.regset.get_chunk(regs_values)
            ret_c = PayloadChunk("", self.arch_info, address)
            return PayloadChunk.get_general_chunk([regs_c, ret_c])

        if self.arch_info.architecture_size == 32:
            slide_c = self.regset.get_slide_stack_chunk(len(args) * 4)
            print slide_c
            ret_c = RetToAddress32(args, address, self.arch_info)
            print ret_c
            return PayloadChunk.get_general_chunk([ret_c, slide_c])

    def get_mem_set_libc_read_chunk(self, location, fd, size, read_address):
        if self.arch_info.architecture_size == 64:
            print "TO IMPLEMENT"
            return


        if self.arch_info.architecture_size == 32:
            slide_chunk = self.regset.get_slide_stack_chunk(4 * 3)
            pl_chunk = MemSetLibcRead32(location,
                                        fd,
                                        size,
                                        read_address,
                                        self.arch_info)


        return PayloadChunk.get_general_chunk([pl_chunk, slide_chunk])

    def build_mem_add(self, location, offset, size, mem_pre = None):
        return self.ams.get_memory_add_chunk(location, offset, size, mem_pre)


    def check_mem_side_effects_and_stack_end(self, g, regs_init, location, size):
        stack_reg = 'esp'
        if (self.arch_info.architecture_size == 64):
            stack_reg = 'rsp'

        stack_base = 0x50
        regs_init[stack_reg] = stack_base

        #TODO fix try and execute (zero div in mv where finding ccf)
        try:
            cregs, mem_final = self.emulator.execute_lite(g.get_ir_instrs(), regs_init)
        except:
            pass

        mem_side_effects = []

        for addr in mem_final.get_addresses():
            if addr in [location + i for i in xrange(size/8)]:
                continue

            sp, vp = mem_final.try_read_prev(addr, 8)
            sn, vn = mem_final.try_read(addr, 8)

            #quick fix. We should disting between reading from stack and read side effetcs
            if sn and not sp and (addr >= stack_base - abs(stack_base - cregs[stack_reg]) and addr <= stack_base + abs(stack_base - cregs[stack_reg])):
                continue

            if (sp and sn and vp != vn) or (sn and not sp) :
                mem_side_effects.append(addr)

        return mem_side_effects, cregs[stack_reg] - stack_base - self.arch_info.address_size / 8

    def find_memory_store(self):
        self.mem_set_gadgets = {}

        if not GadgetType.StoreMemory in self.classified_gadgets:
            return

        self.memstr.add(self.classified_gadgets[GadgetType.StoreMemory])

    def find_ccfs(self):
        self.ccf.add(self.gadgets.values())