示例#1
0
文件: pe.py 项目: EQ4/reverse
    def get_string(self, addr, max_data_size, may_be_utf16le=True):
        i = self.__get_data_section(addr)
        if i == -1:
            return ""

        s = self.__data_sections[i]
        data = self.__data_sections_content[i]
        base = self.pe.OPTIONAL_HEADER.ImageBase
        off = addr - s.VirtualAddress - base
        txt = ['"']

        i = 0
        skipped = 0
        while i - skipped < max_data_size and \
              off < s.SizeOfRawData:
            c = data[off]
            if c == 0:
                if may_be_utf16le and i % 2 == 1:
                    skipped += 1
                else:
                    break
            else:
                if may_be_utf16le and i % 2 == 1:
                    return self.get_string(addr, max_data_size, False)
                txt.append(get_char(c))
            off += 1
            i += 1

        if c != 0 and off != s.SizeOfRawData:
            txt.append("...")

        return ''.join(txt) + '"'
示例#2
0
    def get_string(self, addr, max_data_size):
        i = self.__get_data_section_idx(addr)
        if i == -1:
            return ""

        s = self.__data_sections[i]
        data = self.__data_sections_content[i]
        off = addr - s.header.sh_addr
        txt = ['"']

        c = 0
        i = 0
        while i < max_data_size and \
              off < len(data):
            c = data[off]
            if c == 0:
                break
            txt.append(get_char(c))
            off += 1
            i += 1

        if c != 0 and off != len(data):
            txt.append("...")

        return ''.join(txt) + '"'
示例#3
0
    def get_string(self, addr, max_data_size):
        i = self.__get_data_section(addr)
        if i == -1:
            return ""

        s = self.__data_sections[i]
        data = self.__data_sections_content[i]
        base = self.pe.OPTIONAL_HEADER.ImageBase
        off = addr - s.VirtualAddress - base
        txt = ['"']

        i = 0
        while i < max_data_size and \
              off < s.SizeOfRawData:
            c = data[off]
            if c == 0:
                break
            txt.append(get_char(c))
            off += 1
            i += 1

        if c != 0 and off != s.SizeOfRawData:
            txt.append("...")

        return ''.join(txt) + '"'
示例#4
0
    def get_string(self, addr, max_data_size):
        i = self.__get_data_section_idx(addr)
        if i == -1:
            return ""

        s = self.__data_sections[i]
        data = self.__data_sections_content[i]
        off = addr - s.header.sh_addr
        txt = ['"']

        c = 0
        i = 0
        while i < max_data_size and \
              off < len(data):
            c = data[off]
            if c == 0:
                break
            txt.append(get_char(c))
            off += 1
            i += 1

        if c != 0 and off != len(data):
            txt.append("...")

        return ''.join(txt) + '"'
示例#5
0
    def _imm(self, imm, op_size, hexa, section=None, print_data=True,
             force_dont_print_data=False):

        if self.gctx.capstone_string:
            hexa = True

        label_printed = self._label(imm, print_colon=False)

        if label_printed:
            ty = self._dis.mem.get_type(imm)
            # ty == -1 : from the terminal (with -x) there are no xrefs
            if imm in self._dis.xrefs and ty != MEM_UNK or ty == -1:
                return True

        if section is None:
            section = self._binary.get_section(imm)

        # For a raw file, if the raw base is 0 the immediate is considered
        # as an address only if it's in the symbols list.
        raw_base_zero = self._binary.type == T_BIN_RAW and self.gctx.raw_base == 0

        if section is not None and not raw_base_zero:
            if not label_printed:
                self._address(imm, print_colon=False, notprefix=True)

            if not force_dont_print_data and \
                    print_data and imm not in self._binary.reverse_symbols and \
                    section is not None and section.is_data:
                s = self._binary.get_string(imm, self.gctx.max_data_size)
                if s != "\"\"":
                    self._add(" ")
                    self._string(s)

            return True

        elif op_size == 1:
            self._string("'%s'" % get_char(imm))
        elif hexa:
            self._add(hex(imm))
        else:
            self._add(str(imm))

            if imm > 0:
                if op_size == 4:
                    packed = struct.pack("<L", imm)
                elif op_size == 8:
                    packed = struct.pack("<Q", imm)
                else:
                    return True
                if set(packed).issubset(BYTES_PRINTABLE_SET):
                    self._string(" \"" + "".join(map(chr, packed)) + "\"")
                    return False

            # returns True because capstone print immediate in hexa and
            # it will be printed in a comment, sometimes it's better
            # to have the value in hexa
            return True

        return False
示例#6
0
    def _imm(self, imm, op_size, hexa, section=None, print_data=True,
             force_dont_print_data=False):

        label_printed = self._label(imm, print_colon=False)

        if label_printed:
            ty = self.ctx.dis.mem.get_type(imm)
            # ty == -1 : from the terminal (with -x) there are no xrefs
            if imm in self.ctx.dis.xrefs and ty != MEM_UNK or ty == -1:
                return True

        if section is None:
            section = self.binary.get_section(imm)

        # For a raw file, if the raw base is 0 the immediate is considered
        # as an address only if it's in the symbols list.
        raw_base_zero = self.binary.type == T_BIN_RAW and self.ctx.raw_base == 0

        if section is not None and not raw_base_zero:
            if not label_printed:
                self._address(imm, print_colon=False, notprefix=True)

            if not force_dont_print_data and \
                    print_data and imm not in self.ctx.db.reverse_symbols and \
                    section is not None and section.is_data:
                s = self.binary.get_string(imm, self.ctx.max_data_size)
                if s != "\"\"":
                    self._add(" ")
                    self._string(s)

            return True

        elif op_size == 1:
            self._string("'%s'" % get_char(imm))
        elif hexa:
            self._add(hex(imm))
        else:
            self._add(str(imm))

            if imm > 0:
                if op_size == 4:
                    packed = struct.pack("<L", imm)
                elif op_size == 8:
                    packed = struct.pack("<Q", imm)
                else:
                    return True
                if set(packed).issubset(BYTES_PRINTABLE_SET):
                    self._string(" \"" + "".join(map(chr, packed)) + "\"")
                    return False

            # returns True because capstone print immediate in hexa and
            # it will be printed in a comment, sometimes it's better
            # to have the value in hexa
            return True

        return False
示例#7
0
    def get_string(self, addr, max_data_size):
        s = self.get_section(addr)
        if s is None:
            return ""

        data = s.data
        off = addr - s.start
        txt = ['"']

        c = 0
        i = 0
        while i < max_data_size and off < len(data):
            c = data[off]
            if c == 0:
                break
            txt.append(get_char(c))
            off += 1
            i += 1

        if c != 0 and off != len(data):
            txt.append("...")

        return "".join(txt) + '"'
示例#8
0
    def get_string(self, addr, max_data_size):
        s = self.get_section(addr)
        if s is None:
            return ""

        data = s.data
        off = addr - s.start
        txt = ['"']

        c = 0
        i = 0
        while i < max_data_size and \
              off < len(data):
            c = data[off]
            if c == 0:
                break
            txt.append(get_char(c))
            off += 1
            i += 1

        if c != 0 and off != len(data):
            txt.append("...")

        return ''.join(txt) + '"'
示例#9
0
    def print_operand(self, i, num_op, hexa=False, show_deref=True):
        def inv(n):
            return n == X86_OP_INVALID

        op = i.operands[num_op]

        if op.type == X86_OP_IMM:
            imm = op.value.imm
            sec_name, is_data = self.binary.is_address(imm)

            if sec_name is not None:
                print_no_end(hex(imm))
                if self.ctx.sectionsname:
                    print_no_end(" (" + color_section(sec_name) + ")")
                if is_data:
                    s = self.binary.get_string(imm, self.ctx.max_data_size)
                    print_no_end(" " + color_string(s))
                if imm in self.binary.reverse_symbols:
                    print_no_end(" ")
                    self.print_symbol(imm)
            elif op.size == 1:
                print_no_end(color_string("'%s'" % get_char(imm)))
            elif hexa:
                print_no_end(hex(imm))
            else:
                print_no_end(str(imm))

                if imm > 0:
                    packed = struct.pack("<L", imm)
                    if set(packed).issubset(BYTES_PRINTABLE_SET):
                        print_no_end(color_string(" \""))
                        print_no_end(color_string("".join(map(chr, packed))))
                        print_no_end(color_string("\""))
                        return False

                # returns True because capstone print immediate in hexa
                # it will be printed in a comment, sometimes it better
                # to have the value in hexa
                return True

            return False

        elif op.type == X86_OP_REG:
            print_no_end(i.reg_name(op.value.reg))
            return False

        elif op.type == X86_OP_FP:
            print_no_end("%f" % op.value.fp)
            return False

        elif op.type == X86_OP_MEM:
            mm = op.mem

            if not inv(mm.base) and mm.disp != 0 \
                and inv(mm.segment) and inv(mm.index):

                if (mm.base == X86_REG_RBP or mm.base == X86_REG_EBP) and \
                       self.var_name_exists(i, num_op):
                    print_no_end(color_var(self.get_var_name(i, num_op)))
                    return True
                elif mm.base == X86_REG_RIP or mm.base == X86_REG_EIP:
                    addr = i.address + i.size + mm.disp
                    print_no_end("*({0})".format(
                        self.binary.reverse_symbols.get(addr, hex(addr))))
                    return True

            printed = False
            if show_deref:
                print_no_end("*(")

            if not inv(mm.base):
                print_no_end("%s" % i.reg_name(mm.base))
                printed = True

            elif not inv(mm.segment):
                print_no_end("%s" % i.reg_name(mm.segment))
                printed = True

            if not inv(mm.index):
                if printed:
                    print_no_end(" + ")
                if mm.scale == 1:
                    print_no_end("%s" % i.reg_name(mm.index))
                else:
                    print_no_end("(%s*%d)" % (i.reg_name(mm.index), mm.scale))
                printed = True

            if mm.disp != 0:
                if mm.disp < 0:
                    if printed:
                        print_no_end(" - ")
                    print_no_end(-mm.disp)
                else:
                    if printed:
                        print_no_end(" + ")
                        print_no_end(mm.disp)
                    else:
                        if mm.disp in self.binary.reverse_symbols:
                            print_no_end(hex(mm.disp) + " ")
                            self.print_symbol(mm.disp)
                        else:
                            print_no_end(hex(mm.disp))

            if show_deref:
                print_no_end(")")
            return True
示例#10
0
    def _imm(self, i, imm, op_size, hexa, section=None, print_data=True,
             force_dont_print_data=False):

        if imm in self.ctx.labels:
            self._label(imm, print_colon=False)
            return True

        if section is None:
            section = self.binary.get_section(imm)

        print_sec = section is not None and self.ctx.sectionsname

        # For a raw file, if the raw base is 0 the immediate is considered
        # as an address only if it's in the symbols list.
        raw_base_set = self.binary.type == T_BIN_RAW and self.ctx.raw_base == 0

        is_sym = imm in self.binary.reverse_symbols

        if section is not None and not raw_base_set or is_sym:
            modified = False

            if print_sec:
                self._add("(")
                self._section(section.name)
                self._add(")")

            if is_sym:
                if print_sec:
                    self._add(" ")
                self._symbol(imm)
                modified = True

            if not modified:
                if print_sec:
                    self._add(" ")
                self._add(hex(imm))

            if not force_dont_print_data and \
                    (print_data or not is_sym) and \
                    section is not None and section.is_data:
                s = self.binary.get_string(imm, self.ctx.max_data_size)
                if s != "\"\"":
                    self._add(" ")
                    self._string(s)

            return modified

        elif op_size == 1:
            self._string("'%s'" % get_char(imm))
        elif hexa:
            self._add(hex(imm))
        else:
            self._add(str(imm))

            if imm > 0:
                if op_size == 4:
                    packed = struct.pack("<L", imm)
                elif op_size == 8:
                    packed = struct.pack("<Q", imm)
                else:
                    return True
                if set(packed).issubset(BYTES_PRINTABLE_SET):
                    self._string(" \"" + "".join(map(chr, packed)) + "\"")
                    return False

            # returns True because capstone print immediate in hexa and
            # it will be printed in a comment, sometimes it's better
            # to have the value in hexa
            return True

        return False
示例#11
0
    def print_operand(self, i, num_op, hexa=False, show_deref=True):
        def inv(n):
            return n == X86_OP_INVALID

        op = i.operands[num_op]

        if op.type == X86_OP_IMM:
            imm = op.value.imm
            sec_name, is_data = self.binary.is_address(imm)

            if sec_name is not None:
                print_no_end(hex(imm))
                if self.ctx.sectionsname:
                    print_no_end(" (" + color_section(sec_name) + ")")
                if is_data:
                    s = self.binary.get_string(imm, self.ctx.max_data_size)
                    print_no_end(" " + color_string(s))
                if imm in self.binary.reverse_symbols:
                    print_no_end(" ")
                    self.print_symbol(imm)
            elif op.size == 1:
                print_no_end(color_string("'%s'" % get_char(imm)))
            elif hexa:
                print_no_end(hex(imm))
            else:
                print_no_end(str(imm))

                if imm > 0:
                    packed = struct.pack("<L", imm)
                    if set(packed).issubset(BYTES_PRINTABLE_SET):
                        print_no_end(color_string(" \""))
                        print_no_end(color_string("".join(map(chr, packed))))
                        print_no_end(color_string("\""))
                        return False

                # returns True because capstone print immediate in hexa
                # it will be printed in a comment, sometimes it better
                # to have the value in hexa
                return True

            return False

        elif op.type == X86_OP_REG:
            print_no_end(i.reg_name(op.value.reg))
            return False

        elif op.type == X86_OP_FP:
            print_no_end("%f" % op.value.fp)
            return False

        elif op.type == X86_OP_MEM:
            mm = op.mem

            if not inv(mm.base) and mm.disp != 0 \
                and inv(mm.segment) and inv(mm.index):

                if (mm.base == X86_REG_RBP or mm.base == X86_REG_EBP) and \
                       self.var_name_exists(i, num_op):
                    print_no_end(color_var(self.get_var_name(i, num_op)))
                    return True
                elif mm.base == X86_REG_RIP or mm.base == X86_REG_EIP:
                    addr = i.address + i.size + mm.disp
                    print_no_end("*({0})".format(
                        self.binary.reverse_symbols.get(addr, hex(addr))))
                    return True

            printed = False
            if show_deref:
                print_no_end("*(")

            if not inv(mm.base):
                print_no_end("%s" % i.reg_name(mm.base))
                printed = True

            elif not inv(mm.segment):
                print_no_end("%s" % i.reg_name(mm.segment))
                printed = True

            if not inv(mm.index):
                if printed:
                    print_no_end(" + ")
                if mm.scale == 1:
                    print_no_end("%s" % i.reg_name(mm.index))
                else:
                    print_no_end("(%s*%d)" % (i.reg_name(mm.index), mm.scale))
                printed = True

            if mm.disp != 0:
                if mm.disp < 0:
                    if printed:
                        print_no_end(" - ")
                    print_no_end(-mm.disp)
                else:
                    if printed:
                        print_no_end(" + ")
                        print_no_end(mm.disp)
                    else:
                        if mm.disp in self.binary.reverse_symbols:
                            print_no_end(hex(mm.disp) + " ")
                            self.print_symbol(mm.disp)
                        else:
                            print_no_end(hex(mm.disp))

            if show_deref:
                print_no_end(")")
            return True
示例#12
0
    def _imm(self,
             i,
             imm,
             op_size,
             hexa,
             section=None,
             print_data=True,
             force_dont_print_data=False):

        if imm in self.ctx.labels:
            self._label(imm, print_colon=False)
            return True

        if section is None:
            section = self.binary.get_section(imm)

        print_sec = section is not None and self.ctx.sectionsname

        # For a raw file, if the raw base is 0 the immediate is considered
        # as an address only if it's in the symbols list.
        raw_base_set = self.binary.type == T_BIN_RAW and self.ctx.raw_base == 0

        is_sym = imm in self.binary.reverse_symbols

        if section is not None and not raw_base_set or is_sym:
            modified = False

            if print_sec:
                self._add("(")
                self._section(section.name)
                self._add(")")

            if is_sym:
                if print_sec:
                    self._add(" ")
                self._symbol(imm)
                modified = True

            if not modified:
                if print_sec:
                    self._add(" ")
                self._add(hex(imm))

            if not force_dont_print_data and \
                    (print_data or not is_sym) and \
                    section is not None and section.is_data:
                s = self.binary.get_string(imm, self.ctx.max_data_size)
                if s != "\"\"":
                    self._add(" ")
                    self._string(s)

            return modified

        elif op_size == 1:
            self._string("'%s'" % get_char(imm))
        elif hexa:
            self._add(hex(imm))
        else:
            self._add(str(imm))

            if imm > 0:
                if op_size == 4:
                    packed = struct.pack("<L", imm)
                elif op_size == 8:
                    packed = struct.pack("<Q", imm)
                else:
                    return True
                if set(packed).issubset(BYTES_PRINTABLE_SET):
                    self._string(" \"" + "".join(map(chr, packed)) + "\"")
                    return False

            # returns True because capstone print immediate in hexa and
            # it will be printed in a comment, sometimes it's better
            # to have the value in hexa
            return True

        return False