コード例 #1
0
ファイル: builder.py プロジェクト: yasong/barf-project
    def gen_nop():
        """Return a NOP instruction.
        """
        empty_reg = ReilEmptyOperand()

        return ReilBuilder.build(ReilMnemonic.NOP, empty_reg, empty_reg,
                                 empty_reg)
コード例 #2
0
ファイル: builder.py プロジェクト: yasong/barf-project
    def gen_undef():
        """Return an UNDEF instruction.
        """
        empty_reg = ReilEmptyOperand()

        return ReilBuilder.build(ReilMnemonic.UNDEF, empty_reg, empty_reg,
                                 empty_reg)
コード例 #3
0
    def _classify_load_memory(self, regs_init, regs_fini, mem_fini, written_regs, read_regs):
        """Classify load-memory gadgets.
        """
        matches = []

        regs_init_inv = self._invert_dictionary(regs_init)

        # Check for "dst_reg <- mem[src_reg + offset]" pattern.
        for dst_reg, dst_val in regs_fini.items():
            # Make sure the *dst* register was written.
            if dst_reg not in written_regs:
                continue

            dst_size = self._arch_regs_size[dst_reg]

            # Look for memory addresses that contain *dst_val*.
            for src_addr in mem_fini.read_inverse(dst_val, dst_size // 8):

                # Look for registers whose values are used as memory
                # addresses.
                for src_reg, src_val in regs_init.items():
                    # Make sure the *src* register was read.
                    if src_reg not in read_regs:
                        continue

                    # Check restrictions.
                    if self._arch_regs_size[src_reg] != self._address_size:
                        continue

                    offset = (src_addr - src_val) & (2**self._address_size - 1)

                    src_reg_ir = ReilRegisterOperand(src_reg, self._arch_regs_size[src_reg])
                    src_off_ir = ReilImmediateOperand(offset, self._arch_regs_size[src_reg])
                    dst_reg_ir = ReilRegisterOperand(dst_reg, self._arch_regs_size[dst_reg])

                    matches.append({
                        "src": [src_reg_ir, src_off_ir],
                        "dst": [dst_reg_ir]
                    })

        # Check for "dst_reg <- mem[offset]" pattern.
        for dst_reg, dst_val in regs_fini.items():
            # Make sure the *dst* register was written.
            if dst_reg not in written_regs:
                continue

            dst_size = self._arch_regs_size[dst_reg]

            for src_addr in mem_fini.read_inverse(dst_val, dst_size // 8):
                src_reg_ir = ReilEmptyOperand()
                src_off_ir = ReilImmediateOperand(src_addr, self._address_size)
                dst_reg_ir = ReilRegisterOperand(dst_reg, self._arch_regs_size[dst_reg])

                matches.append({
                    "src": [src_reg_ir, src_off_ir],
                    "dst": [dst_reg_ir]
                })

        return matches
コード例 #4
0
ファイル: builder.py プロジェクト: yasong/barf-project
    def gen_sext(src, dst):
        """Return a SEXT instruction.
        """
        assert src.size <= dst.size

        empty_reg = ReilEmptyOperand()

        return ReilBuilder.build(ReilMnemonic.SEXT, src, empty_reg, dst)
コード例 #5
0
    def _classify_store_memory(self, regs_init, regs_fini, mem_fini, written_regs, read_regs):
        """Classify store-memory gadgets.
        """
        matches = []

        regs_init_inv = self._invert_dictionary(regs_init)

        # Check for "mem[dst_reg + offset] <- src_reg" pattern.
        for src_reg, src_val in regs_init.items():
            # Make sure the *src* register was read.
            if src_reg not in read_regs:
                continue

            src_size = self._arch_regs_size[src_reg]

            for addr in mem_fini.read_inverse(src_val, src_size // 8):
                for dst_reg, dst_val in regs_init.items():
                    # Make sure the *dst* register was written.
                    if dst_reg not in read_regs:
                        continue

                    # Check restrictions.
                    if self._arch_regs_size[dst_reg] != self._address_size:
                        continue

                    offset = (addr - dst_val) & (2**self._address_size - 1)

                    src_reg_ir = ReilRegisterOperand(src_reg, self._arch_regs_size[src_reg])
                    dst_reg_ir = ReilRegisterOperand(dst_reg, self._arch_regs_size[dst_reg])
                    dst_off_ir = ReilImmediateOperand(offset, self._arch_regs_size[dst_reg])

                    matches.append({
                        "src": [src_reg_ir],
                        "dst": [dst_reg_ir, dst_off_ir]
                    })

        # Check for "mem[offset] <- src_reg" pattern.
        for src_reg, src_val in regs_init.items():
            # Make sure the *src* register was read.
            if src_reg not in read_regs:
                continue

            src_size = self._arch_regs_size[src_reg]

            for addr in mem_fini.read_inverse(src_val, src_size // 8):
                offset = addr & (2**self._address_size - 1)

                src_reg_ir = ReilRegisterOperand(src_reg, self._arch_regs_size[src_reg])
                dst_reg_ir = ReilEmptyOperand()
                dst_off_ir = ReilImmediateOperand(offset, self._address_size)

                matches.append({
                    "src": [src_reg_ir],
                    "dst": [dst_reg_ir, dst_off_ir]
                })

        return matches
コード例 #6
0
def parse_operand(string, location, tokens):
    """Parse instruction operand.
    """
    sizes = {
        "dqword": 128,
        "pointer": 72,
        "qword": 64,
        "pointer": 40,
        "dword": 32,
        "word": 16,
        "byte": 8,
        "bit": 1,
    }

    if "immediate" in tokens:
        imm_str = "".join(tokens["immediate"])
        base = 16 if imm_str.startswith("0x") or imm_str.startswith(
            "-0x") else 10

        imm = int(imm_str, base)

        oprnd = ReilImmediateOperand(imm)

    if "register" in tokens:
        if tokens["register"] in ["e", "empty"]:
            oprnd = ReilEmptyOperand()

            oprnd.size = 0
        else:
            name = tokens["register"]

            oprnd = ReilRegisterOperand(name)

    if "size" in tokens:
        oprnd.size = int(sizes[tokens["size"]])

    return [oprnd]
コード例 #7
0
    def _classify_arithmetic_store(self, regs_init, regs_fini, mem_fini,
                                   written_regs, read_regs):
        """Classify arithmetic-store gadgets.
        """
        matchings = []

        # Check for "m[dst_reg + offset] <- m[dst_reg + offset] OP src_reg" pattern.
        for op_name, op_fn in self._binary_ops.items():
            for size in [8, 16, 32, 64]:
                for addr in mem_fini.get_addresses():
                    success_read_curr, val_curr = mem_fini.try_read(
                        addr, size / 8)
                    success_read_prev, val_prev = mem_fini.try_read_prev(
                        addr, size / 8)

                    if success_read_curr and success_read_prev:
                        for src_reg, src_val in regs_init.items():
                            # Make sure the *src* register was read.
                            if not src_reg in read_regs:
                                continue

                            # Check restrictions.
                            if self._arch_regs_size[src_reg] != size:
                                continue

                            if val_curr == op_fn(src_val,
                                                 val_prev) & (2**size - 1):
                                # find dst + offset
                                for dst_reg, dst_val in regs_init.items():
                                    # Make sure the *dst* register was written.
                                    if not dst_reg in read_regs:
                                        continue

                                    # Check restrictions.
                                    if self._arch_regs_size[
                                            dst_reg] != self._address_size:
                                        continue

                                    offset = (addr - dst_val) & (
                                        2**self._address_size - 1)

                                    src_reg_ir = ReilRegisterOperand(
                                        src_reg, self._arch_regs_size[src_reg])
                                    dst_reg_ir = ReilRegisterOperand(
                                        dst_reg, self._arch_regs_size[dst_reg])
                                    dst_off_ir = ReilImmediateOperand(
                                        offset, self._address_size)

                                    matchings.append({
                                        "src" : [dst_reg_ir, dst_off_ir, \
                                            src_reg_ir],
                                        "dst" : [dst_reg_ir, dst_off_ir],
                                        "op"  : op_name
                                    })

        # Check for "m[offset] <- m[offset] OP src_reg" pattern.
        for op_name, op_fn in self._binary_ops.items():
            for size in [8, 16, 32, 64]:
                for addr in mem_fini.get_addresses():
                    success_read_curr, val_curr = mem_fini.try_read(
                        addr, size / 8)
                    success_read_prev, val_prev = mem_fini.try_read_prev(
                        addr, size / 8)

                    if success_read_curr and success_read_prev:
                        for src_reg, src_val in regs_init.items():
                            # Make sure the *src* register was read.
                            if not src_reg in read_regs:
                                continue

                            # Check restrictions.
                            if self._arch_regs_size[src_reg] != size:
                                continue

                            if val_curr == op_fn(src_val,
                                                 val_prev) & (2**size - 1):
                                src_reg_ir = ReilRegisterOperand(
                                    src_reg, self._arch_regs_size[src_reg])
                                dst_reg_ir = ReilEmptyOperand()
                                dst_off_ir = ReilImmediateOperand(
                                    addr, self._address_size)

                                matchings.append({
                                    "src":
                                    [dst_reg_ir, dst_off_ir, src_reg_ir],
                                    "dst": [dst_reg_ir, dst_off_ir],
                                    "op":
                                    op_name
                                })

        return matchings
コード例 #8
0
    def _classify_arithmetic_load(self, regs_init, regs_fini, mem_fini,
                                  written_regs, read_regs):
        """Classify arithmetic-load gadgets.
        """
        matchings = []

        # Check for "dst_reg <- dst_reg OP mem[src_reg + offset]" pattern.
        for op_name, op_fn in self._binary_ops.items():
            for dst_reg, dst_val in regs_fini.items():
                # Make sure the *dst* register was read and written.
                if dst_reg not in written_regs or dst_reg not in read_regs:
                    continue

                dst_size = self._arch_regs_size[dst_reg]

                for addr in mem_fini.get_addresses():
                    success, val = mem_fini.try_read(addr, dst_size / 8)

                    if success and dst_val == op_fn(regs_init[dst_reg],
                                                    val) & (2**dst_size - 1):

                        for src_reg, src_val in regs_init.items():
                            # Make sure the *src* register was read.
                            if not src_reg in read_regs:
                                continue

                            # Check restrictions.
                            if self._arch_regs_size[
                                    src_reg] != self._address_size:
                                continue

                            offset = (addr -
                                      src_val) & (2**self._address_size - 1)

                            src_reg_ir = ReilRegisterOperand(
                                src_reg, self._arch_regs_size[src_reg])
                            src_off_ir = ReilImmediateOperand(
                                offset, self._address_size)
                            dst_reg_ir = ReilRegisterOperand(
                                dst_reg, self._arch_regs_size[dst_reg])

                            matchings.append({
                                "src": [dst_reg_ir, src_reg_ir, src_off_ir],
                                "dst": [dst_reg_ir],
                                "op":
                                op_name
                            })

        # Check for "dst_reg <- dst_reg OP mem[offset]" pattern.
        for op_name, op_fn in self._binary_ops.items():
            for dst_reg, dst_val in regs_fini.items():
                # Make sure the *dst* register was read and written.
                if dst_reg not in written_regs or dst_reg not in read_regs:
                    continue

                dst_size = self._arch_regs_size[dst_reg]

                for addr in mem_fini.get_addresses():
                    success, val = mem_fini.try_read(addr, dst_size / 8)

                    if success and dst_val == op_fn(regs_init[dst_reg],
                                                    val) & (2**dst_size - 1):
                        src_reg_ir = ReilEmptyOperand()
                        src_off_ir = ReilImmediateOperand(
                            addr, self._address_size)
                        dst_reg_ir = ReilRegisterOperand(
                            dst_reg, self._arch_regs_size[dst_reg])

                        matchings.append({
                            "src": [dst_reg_ir, src_reg_ir, src_off_ir],
                            "dst": [dst_reg_ir],
                            "op":
                            op_name
                        })

        return matchings
コード例 #9
0
ファイル: builder.py プロジェクト: yasong/barf-project
 def gen_jcc(src, dst):
     """Return a JCC instruction.
     """
     return ReilBuilder.build(ReilMnemonic.JCC, src, ReilEmptyOperand(),
                              dst)
コード例 #10
0
ファイル: builder.py プロジェクト: yasong/barf-project
 def gen_bisz(src, dst):
     """Return a BISZ instruction.
     """
     return ReilBuilder.build(ReilMnemonic.BISZ, src, ReilEmptyOperand(),
                              dst)
コード例 #11
0
ファイル: builder.py プロジェクト: yasong/barf-project
 def gen_str(src, dst):
     """Return a STR instruction.
     """
     return ReilBuilder.build(ReilMnemonic.STR, src, ReilEmptyOperand(),
                              dst)
コード例 #12
0
ファイル: builder.py プロジェクト: yasong/barf-project
 def gen_ldm(src, dst):
     """Return a LDM instruction.
     """
     return ReilBuilder.build(ReilMnemonic.LDM, src, ReilEmptyOperand(),
                              dst)
コード例 #13
0
ファイル: builder.py プロジェクト: shalekesan/barf-project
    def gen_unkn(self):
        """Return an UNKN instruction.
        """
        empty_reg = ReilEmptyOperand()

        return self.build(ReilMnemonic.UNKN, empty_reg, empty_reg, empty_reg)
コード例 #14
0
ファイル: builder.py プロジェクト: shalekesan/barf-project
 def gen_stm(self, src, dst):
     """Return a STM instruction.
     """
     return self.build(ReilMnemonic.STM, src, ReilEmptyOperand(), dst)