コード例 #1
0
def main(APP):
    conv_imm = 0
    unconv_imm = 0

    for area in aspace.get_areas():
        if not "X" in area[engine.PROPS].get("access", ""):
            continue
        #print(area[:-2])
        last_inst = None
        for i in inst_in_area(area):
            if last_inst and i.disasm in (
                    "goto $a0",
                    "call $a0") and last_inst.disasm.startswith("$a0 = "):
                if last_inst[2].type == idaapi.o_imm:
                    if not APP.is_ui:
                        print(last_inst)
                        print(i)
                    target_addr = last_inst[2].get_addr()

                    # Change 1
                    if not APP.aspace.is_arg_offset(last_inst.ea, 2):
                        APP.aspace.make_arg_offset(last_inst.ea, 2,
                                                   target_addr)
                        conv_imm += 1
                    else:
                        unconv_imm += 1

                    # Change 2
                    # Note: side effect of this is that of sequence
                    #   $a0 = sym
                    #   call $a0
                    # "$a0 = sym" will be marked as having "c" (call) xref to sym,
                    # whereas before this plugin run, the same line had "o" xref.
                    # More formally correct approach would be to make "call $a0"
                    # line to have "c" xref, but this would lead to doubling size of
                    # xref list. So, this entire situation is considered a feature, not
                    # a bug, and indeed what a user wants (and 2 instructions above
                    # can be considered a single compound instruction anyway).
                    idaapi.ua_add_cref(
                        0, target_addr,
                        idaapi.fl_CN if i.disasm[0] == "c" else idaapi.fl_JN)

            last_inst = i

    engine.analyze(lambda c: print(c))

    if not APP.is_ui:
        print("Immediates converted to offsets: %d, already converted: %d" %
              (conv_imm, unconv_imm))
        print("Done, press Enter")
        input()
コード例 #2
0
def main(APP):
    conv_imm = 0
    unconv_imm = 0

    for area in aspace.get_areas():
        if not "X" in area[engine.PROPS].get("access", ""):
            continue
        #print(area[:-2])
        last_inst = None
        for i in inst_in_area(area):
            if last_inst and i.disasm in ("goto $a0", "call $a0") and last_inst.disasm.startswith("$a0 = "):
                if last_inst[2].type == idaapi.o_imm:
                    if not APP.is_ui:
                        print(last_inst)
                        print(i)
                    target_addr = last_inst[2].get_addr()

                    # Change 1
                    if not APP.aspace.is_arg_offset(last_inst.ea, 2):
                        APP.aspace.make_arg_offset(last_inst.ea, 2, target_addr)
                        conv_imm += 1
                    else:
                        unconv_imm += 1

                    # Change 2
                    # Note: side effect of this is that of sequence
                    #   $a0 = sym
                    #   call $a0
                    # "$a0 = sym" will be marked as having "c" (call) xref to sym,
                    # whereas before this plugin run, the same line had "o" xref.
                    # More formally correct approach would be to make "call $a0"
                    # line to have "c" xref, but this would lead to doubling size of
                    # xref list. So, this entire situation is considered a feature, not
                    # a bug, and indeed what a user wants (and 2 instructions above
                    # can be considered a single compound instruction anyway).
                    idaapi.ua_add_cref(0, target_addr, idaapi.fl_CN if i.disasm[0] == "c" else idaapi.fl_JN)

            last_inst = i

    engine.analyze(lambda c: print(c))

    if not APP.is_ui:
        print("Immediates converted to offsets: %d, already converted: %d" % (conv_imm, unconv_imm))
        print("Done, press Enter")
        input()
コード例 #3
0
ファイル: scratchabit.py プロジェクト: aeppert/ScratchABit
    def handle_key_unprotected(self, key):
        if key == editor.KEY_ENTER:
            line = self.get_cur_line()
            log.info("Enter pressed: %s" % line)
            op_no = self.cur_operand_no(line)
            self.show_status("Enter pressed: %s, %s" % (self.col, op_no))
            if isinstance(line, engine.DisasmObj):
                to_addr = None
                if op_no >= 0:
                    o = line[op_no]
                    to_addr = o.get_addr()
                if to_addr is None:
                    o = line.get_operand_addr()
                    if o:
                        to_addr = o.get_addr()
                self.goto_addr(to_addr, from_addr=line.ea)
        elif key == editor.KEY_ESC:
            if self.addr_stack:
                self.show_status("Returning")
                self.goto_addr(self.addr_stack.pop())
        elif key == b"q":
            return editor.KEY_QUIT
        elif key == b"c":
            addr = self.cur_addr()
            self.show_status("Analyzing at %x" % addr)
            engine.add_entrypoint(addr, False)
            engine.analyze(self.analyze_status)
            self.update_model()
        elif key == b"d":
            addr = self.cur_addr()
            fl = self.model.AS.get_flags(addr)
            if fl not in (self.model.AS.DATA, self.model.AS.UNK):
                self.show_status("Undefine first")
                return
            if fl == self.model.AS.UNK:
                self.model.AS.set_flags(addr, 1, self.model.AS.DATA, self.model.AS.DATA_CONT)
            else:
                sz = self.model.AS.get_unit_size(addr)
                self.model.undefine_unit(addr)
                sz *= 2
                if sz > 4: sz = 1
                self.model.AS.set_flags(addr, sz, self.model.AS.DATA, self.model.AS.DATA_CONT)
            self.update_model()
        elif key == b"a":
            addr = self.cur_addr()
            fl = self.model.AS.get_flags(addr)
            if fl != self.model.AS.UNK:
                self.show_status("Undefine first")
                return
            sz = 0
            label = "s_"
            while True:
                b = self.model.AS.get_byte(addr)
                fl = self.model.AS.get_flags(addr)
                if not (0x20 <= b <= 0x7e or b in (0x0a, 0x0d)):
                    if b == 0:
                        sz += 1
                    break
                if fl != self.model.AS.UNK:
                    break
                c = chr(b)
                if c < '0' or c in string.punctuation:
                    c = '_'
                label += c
                addr += 1
                sz += 1
            if sz > 0:
                self.model.AS.set_flags(self.cur_addr(), sz, self.model.AS.STR, self.model.AS.DATA_CONT)
                self.model.AS.make_unique_label(self.cur_addr(), label)
                self.update_model()
        elif key == b"u":
            addr = self.cur_addr()
            self.model.undefine_unit(addr)
            self.update_model()
        elif key == b"o":
            addr = self.cur_addr()
            line = self.get_cur_line()
            o = line.get_operand_addr()
            if not o:
                self.show_status("Cannot convert operand to offset")
                return
            if o.type != idaapi.o_imm or not self.model.AS.is_valid_addr(o.get_addr()):
                self.show_status("Cannot convert operand to offset: #%s: %s" % (o.n, o.type))
                return

            if self.model.AS.get_arg_prop(addr, o.n, "type") == idaapi.o_mem:
                self.model.AS.set_arg_prop(addr, o.n, "type", idaapi.o_imm)
                self.model.AS.del_xref(addr, o.get_addr(), idaapi.dr_O)
            else:
                self.model.AS.make_arg_offset(addr, o.n, o.get_addr())
            self.update_model(True)
        elif key == b";":
            addr = self.cur_addr()
            comment = self.model.AS.get_comment(addr) or ""
            res = self.dialog_edit_line(line=comment, width=60)
            if res:
                self.model.AS.set_comment(addr, res)
            self.update_screen()
        elif key == b"n":
            addr = self.cur_addr()
            label = self.model.AS.get_label(addr)
            def_label = self.model.AS.get_default_label(addr)
            s = label or def_label
            while True:
                res = self.dialog_edit_line(line=s)
                if not res:
                    break
                if res == def_label:
                    res = addr
                else:
                    if self.model.AS.label_exists(res):
                        s = res
                        self.show_status("Duplicate label")
                        continue
                self.model.AS.set_label(addr, res)
                if not label:
                    # If it's new label, we need to add it to model
                    self.update_model()
                    return
                break
            self.update_screen()
        elif key == b"g":

            F = npyscreen.FormBaseNew(name='Go to', lines=6, columns=40, show_atx=4, show_aty=4)
            e = F.add(LabelEntry, name="Labels")
            e.set_choices(self.model.AS.get_label_list())

            def h_enter_key(input):
                if not e.value:
                    # Hitting Enter with empty text entry opens autocomplete dropbox
                    e.auto_complete(input)
                else:
                    F.exit_editing()
            e.add_handlers({curses.ascii.CR: h_enter_key})

            F.add(npyscreen.FixedText, value="Press Tab to auto-complete", editable=False)
            F.edit()
            self.update_screen()
            if e.value:
                if '0' <= e.value[0] <= '9':
                    res = int(e.value, 0)
                else:
                    res = self.model.AS.resolve_label(e.value)

                self.goto_addr(res, from_addr=self.cur_addr())
        elif key == editor.KEY_F1:
            help.help(self)
            self.update_screen()
        elif key == b"S":
            save_state(project_dir)
            self.show_status("Saved.")
        elif key == b"\x11":  # ^Q
            F = npyscreen.Popup(name='Problems list', lines=18)
            class IssueList(npyscreen.MultiLine):
                def display_value(self, vl):
                    return "%08x %s" % vl
            lw = F.add(IssueList, name="Problems")
            #lw.return_exit = True
            lw.values = self.model.AS.get_issues()
            lw.add_handlers({curses.ascii.CR: lambda key: (lw.h_select_exit(key), F.exit_editing(), 1)})
            F.edit()
            self.update_screen()
            if lw.value is not None:
                val = lw.values[lw.value][0]
                self.goto_addr(val, from_addr=self.cur_addr())
        elif key == b"i":
            off, area = self.model.AS.addr2area(self.cur_addr())
            props = area[engine.PROPS]
            percent = 100 * off / (area[engine.END] - area[engine.START] + 1)
            func = self.model.AS.lookup_func(self.cur_addr())
            func = self.model.AS.get_label(func.start) if func else None
            self.show_status("Area: 0x%x %s (%s): %.1f%%, func: %s" % (
                area[engine.START], props.get("name", "noname"), props["access"], percent, func
            ))
        elif key == b"W":
            class TextSaveModel:
                def __init__(self, f, ctrl):
                    self.f = f
                    self.ctrl = ctrl
                    self.cnt = 0
                def add_line(self, addr, line):
                    line = ("%08x " % addr) + line.indent + line.render() + "\n"
                    self.f.write(line)
                    if self.cnt % 256 == 0:
                        self.ctrl.show_status("Writing: 0x%x" % addr)
                    self.cnt += 1
            out_fname = "out.lst"
            with open(out_fname, "w") as f:
                engine.render_partial(TextSaveModel(f, self), 0, 0, 10000000)
            self.show_status("Disassembly listing written: " + out_fname)
        elif key in (b"/", b"?"):  # "/" and Shift+"/"
            class FoundException(Exception): pass
            class TextSearchModel:
                def __init__(self, substr, ctrl):
                    self.search = substr
                    self.ctrl = ctrl
                    self.cnt = 0
                def add_line(self, addr, line):
                    line = line.render()
                    if self.search in line:
                        raise FoundException(addr)
                    if self.cnt % 256 == 0:
                        self.ctrl.show_status("Searching: 0x%x" % addr)
                    self.cnt += 1
            if key == b"/":
                F = npyscreen.FormBaseNew(name='Text Search', lines=5, columns=40, show_atx=4, show_aty=4)
                e = F.add(npyscreen.TitleText, name="Search for:")
                e.entry_widget.add_handlers({curses.ascii.CR: lambda k: F.exit_editing()})
                F.edit()
                self.update_screen()
                self.search_str = e.value
                addr = self.cur_addr()
            else:
                addr = self.next_addr()

            try:
                engine.render_from(TextSearchModel(self.search_str, self), addr, 10000000)
            except FoundException as res:
                self.goto_addr(res.args[0], from_addr=self.cur_addr())
            else:
                self.show_status("Not found: " + self.search_str)

        else:
            self.show_status("Unbound key: " + repr(key))
コード例 #4
0
ファイル: scratchabit.py プロジェクト: aeppert/ScratchABit
    if show_bytes:
        engine.DisasmObj.LEADER_SIZE += show_bytes * 2 + 1

    # Strip suffix if any from def filename
    project_dir = project_name + ".scratchabit"

    if os.path.exists(project_dir + "/project.labels"):
        load_state(project_dir)
    else:
        for label, addr in ENTRYPOINTS:
            if engine.ADDRESS_SPACE.is_exec(addr):
                engine.add_entrypoint(addr)
            engine.ADDRESS_SPACE.make_unique_label(addr, label)
        def _progress(cnt):
            sys.stdout.write("Performing initial analysis... %d\r" % cnt)
        engine.analyze(_progress)
        print()

    #engine.print_address_map()

    if ENTRYPOINTS:
        show_addr = ENTRYPOINTS[0][1]
    else:
        show_addr = engine.ADDRESS_SPACE.min_addr()

    t = time.time()
    #_model = engine.render()
    _model = engine.render_partial_around(show_addr, 0, HEIGHT * 2)
    print("Rendering time: %fs" % (time.time() - t))
    #print(_model.lines())
    #sys.exit()
コード例 #5
0
    def handle_key(self, key):
        if key == editor.KEY_ENTER:
            line = self.get_cur_line()
            log.info("Enter pressed: %s" % line)
            op_no = self.cur_operand_no(line)
            self.show_status("Enter pressed: %s, %s" % (self.col, op_no))
            if isinstance(line, engine.DisasmObj):
                to_addr = None
                if op_no >= 0:
                    o = line[op_no]
                    to_addr = o.get_addr()
                if to_addr is None:
                    o = line.get_operand_addr()
                    if o:
                        to_addr = o.get_addr()
                self.goto_addr(to_addr, from_addr=line.ea)
        elif key == editor.KEY_ESC:
            if self.addr_stack:
                self.show_status("Returning")
                self.goto_addr(self.addr_stack.pop())
        elif key == b"q":
            return editor.KEY_QUIT
        elif key == b"c":
            addr = self.cur_addr()
            self.show_status("Analyzing at %x" % addr)
            engine.add_entrypoint(addr)
            engine.analyze(self.analyze_status)
            self.update_model()
        elif key == b"d":
            addr = self.cur_addr()
            fl = self.model.AS.get_flags(addr)
            if fl not in (self.model.AS.DATA, self.model.AS.UNK):
                self.show_status("Undefine first")
                return
            if fl == self.model.AS.UNK:
                self.model.AS.set_flags(addr, 1, self.model.AS.DATA, self.model.AS.DATA_CONT)
            else:
                sz = self.model.AS.get_unit_size(addr)
                self.model.undefine(addr)
                sz *= 2
                if sz > 4: sz = 1
                self.model.AS.set_flags(addr, sz, self.model.AS.DATA, self.model.AS.DATA_CONT)
            self.update_model()
        elif key == b"a":
            addr = self.cur_addr()
            fl = self.model.AS.get_flags(addr)
            if fl != self.model.AS.UNK:
                self.show_status("Undefine first")
                return
            sz = 0
            label = "s_"
            while True:
                b = self.model.AS.get_byte(addr)
                fl = self.model.AS.get_flags(addr)
                if not (0x20 <= b <= 0x7e or b in (0x0a, 0x0d)):
                    if b == 0:
                        sz += 1
                    break
                if fl != self.model.AS.UNK:
                    break
                c = chr(b)
                if c < '0' or c in string.punctuation:
                    c = '_'
                label += c
                addr += 1
                sz += 1
            if sz > 0:
                self.model.AS.set_flags(self.cur_addr(), sz, self.model.AS.STR, self.model.AS.DATA_CONT)
                self.model.AS.make_unique_label(self.cur_addr(), label)
                self.update_model()
        elif key == b"u":
            addr = self.cur_addr()
            self.model.undefine(addr)
            self.update_model()
        elif key == b"o":
            addr = self.cur_addr()
            line = self.get_cur_line()
            o = line.get_operand_addr()
            if not o:
                self.show_status("Cannot convert operand to offset")
                return
            if o.type != idaapi.o_imm or not self.model.AS.is_valid_addr(o.get_addr()):
                self.show_status("Cannot convert operand to offset: #%s: %s" % (o.n, o.type))
                return

            if self.model.AS.get_arg_prop(addr, o.n, "type") == idaapi.o_mem:
                self.model.AS.set_arg_prop(addr, o.n, "type", idaapi.o_imm)
                self.model.AS.del_xref(addr, o.get_addr(), idaapi.dr_O)
            else:
                self.model.AS.set_arg_prop(addr, o.n, "type", idaapi.o_mem)
                label = self.model.AS.get_label(o.get_addr())
                if not label:
                    self.model.AS.make_auto_label(o.get_addr())
                self.model.AS.add_xref(addr, o.get_addr(), idaapi.dr_O)
            self.update_model(True)
        elif key == b";":
            addr = self.cur_addr()
            comment = self.model.AS.get_comment(addr) or ""
            res = self.dialog_edit_line(line=comment, width=60)
            if res:
                self.model.AS.set_comment(addr, res)
            self.update_screen()
        elif key == b"n":
            addr = self.cur_addr()
            label = self.model.AS.get_label(addr)
            def_label = self.model.AS.get_default_label(addr)
            s = label or def_label
            while True:
                res = self.dialog_edit_line(line=s)
                if not res:
                    break
                if res == def_label:
                    res = addr
                else:
                    if self.model.AS.label_exists(res):
                        s = res
                        self.show_status("Duplicate label")
                        continue
                self.model.AS.set_label(addr, res)
                if not label:
                    # If it's new label, we need to add it to model
                    self.update_model()
                    return
                break
            self.update_screen()
        elif key == b"g":

            F = npyscreen.FormBaseNew(name='Go to', lines=6, columns=40, show_atx=4, show_aty=4)
            e = F.add(LabelEntry, name="Labels")
            e.set_choices(self.model.AS.get_label_list())

            def h_enter_key(input):
                if not e.value:
                    # Hitting Enter with empty text entry opens autocomplete dropbox
                    e.auto_complete(input)
                else:
                    F.exit_editing()
            e.add_handlers({curses.ascii.CR: h_enter_key})

            F.add(npyscreen.FixedText, value="Press Tab to auto-complete", editable=False)
            F.edit()
            self.update_screen()
            if e.value:
                if '0' <= e.value[0] <= '9':
                    res = int(e.value, 0)
                else:
                    res = self.model.AS.resolve_label(e.value)

                self.goto_addr(res, from_addr=self.cur_addr())
        elif key == editor.KEY_F1:
            help.help(self)
            self.update_screen()
        elif key == b"S":
            save_state(project_dir)
            self.show_status("Saved.")
コード例 #6
0
    engine.DisasmObj.LEADER_SIZE = 8 + 1
    if show_bytes:
        engine.DisasmObj.LEADER_SIZE += show_bytes * 2 + 1

    # Strip suffix if any from def filename
    project_name = sys.argv[1].rsplit(".", 1)[0]
    project_dir = project_name + ".scratchabit"

    if os.path.exists(project_dir + "/project.labels"):
        load_state(project_dir)
    else:
        for label, addr in ENTRYPOINTS:
            engine.add_entrypoint(addr)
            engine.ADDRESS_SPACE.set_label(addr, label)
        engine.analyze()

    #engine.print_address_map()

    if ENTRYPOINTS:
        show_addr = ENTRYPOINTS[0][1]
    else:
        show_addr = engine.ADDRESS_SPACE.min_addr()

    t = time.time()
    #_model = engine.render()
    _model = engine.render_partial_around(show_addr, 0, HEIGHT * 2)
    print("Rendering time: %fs" % (time.time() - t))
    #print(_model.lines())
    #sys.exit()
コード例 #7
0
ファイル: scratchabit.py プロジェクト: noscripter/ScratchABit
    def handle_key_unprotected(self, key):
        if key == editor.KEY_ENTER:
            line = self.get_cur_line()
            log.info("Enter pressed: %s" % line)
            op_no = self.cur_operand_no(line)
            self.show_status("Enter pressed: %s, %s" % (self.col, op_no))
            to_addr = None
            # No longer try to jump only to addresses in args, parse
            # textual representation below
            if False and isinstance(line, engine.DisasmObj):
                if op_no >= 0:
                    o = line[op_no]
                    to_addr = o.get_addr()
                if to_addr is None:
                    o = line.get_operand_addr()
                    if o:
                        to_addr = o.get_addr()
            if to_addr is None:
                pos = self.col - line.LEADER_SIZE - len(line.indent)
                word = utils.get_word_at_pos(line.cache, pos)
                if word:
                    if word[0].isdigit():
                        to_addr = int(word, 0)
                    else:
                        to_addr = self.model.AS.resolve_label(word)
                        if to_addr is None:
                            self.show_status("Unknown address: %s" % word)
                            return
            self.goto_addr(to_addr, from_addr=line.ea)
        elif key == editor.KEY_ESC:
            if self.addr_stack:
                self.show_status("Returning")
                self.goto_addr(self.addr_stack.pop())
        elif key == b"q":
            return editor.KEY_QUIT
        elif key == b"c":
            addr = self.cur_addr()
            self.show_status("Analyzing at %x" % addr)
            engine.add_entrypoint(addr, False)
            engine.analyze(self.analyze_status)
            self.update_model()
        elif key == b"d":
            addr = self.cur_addr()
            fl = self.model.AS.get_flags(addr)
            if fl not in (self.model.AS.DATA, self.model.AS.UNK):
                self.show_status("Undefine first")
                return
            if fl == self.model.AS.UNK:
                self.model.AS.set_flags(addr, 1, self.model.AS.DATA, self.model.AS.DATA_CONT)
            else:
                sz = self.model.AS.get_unit_size(addr)
                self.model.undefine_unit(addr)
                sz *= 2
                if sz > 4: sz = 1
                self.model.AS.set_flags(addr, sz, self.model.AS.DATA, self.model.AS.DATA_CONT)
            self.update_model()
        elif key == b"a":
            addr = self.cur_addr()
            fl = self.model.AS.get_flags(addr)
            if fl != self.model.AS.UNK:
                self.show_status("Undefine first")
                return
            sz = 0
            label = "s_"
            while True:
                b = self.model.AS.get_byte(addr)
                fl = self.model.AS.get_flags(addr)
                if not (0x20 <= b <= 0x7e or b in (0x0a, 0x0d)):
                    if b == 0:
                        sz += 1
                    break
                if fl != self.model.AS.UNK:
                    break
                c = chr(b)
                if c < '0' or c in string.punctuation:
                    c = '_'
                label += c
                addr += 1
                sz += 1
            if sz > 0:
                self.model.AS.set_flags(self.cur_addr(), sz, self.model.AS.STR, self.model.AS.DATA_CONT)
                self.model.AS.make_unique_label(self.cur_addr(), label)
                self.update_model()
        elif key == b"u":
            addr = self.cur_addr()
            self.model.undefine_unit(addr)
            self.update_model()
        elif key == b"o":
            addr = self.cur_addr()
            line = self.get_cur_line()
            o = line.get_operand_addr()
            if not o:
                self.show_status("Cannot convert operand to offset")
                return
            if o.type != idaapi.o_imm or not self.model.AS.is_valid_addr(o.get_addr()):
                self.show_status("Cannot convert operand to offset: #%s: %s" % (o.n, o.type))
                return

            if self.model.AS.get_arg_prop(addr, o.n, "type") == idaapi.o_mem:
                self.model.AS.set_arg_prop(addr, o.n, "type", idaapi.o_imm)
                self.model.AS.del_xref(addr, o.get_addr(), idaapi.dr_O)
            else:
                self.model.AS.make_arg_offset(addr, o.n, o.get_addr())
            self.update_model(True)
        elif key == b";":
            addr = self.cur_addr()
            comment = self.model.AS.get_comment(addr) or ""
            res = self.dialog_edit_line(line=comment, width=60)
            if res is not None:
                self.model.AS.set_comment(addr, res)
                self.update_model()
            else:
                self.update_screen()
        elif key == b"n":
            addr = self.cur_addr()
            label = self.model.AS.get_label(addr)
            def_label = self.model.AS.get_default_label(addr)
            s = label or def_label
            while True:
                res = self.dialog_edit_line(line=s)
                if not res:
                    break
                if res == def_label:
                    res = addr
                else:
                    if self.model.AS.label_exists(res):
                        s = res
                        self.show_status("Duplicate label")
                        continue
                self.model.AS.set_label(addr, res)
                if not label:
                    # If it's new label, we need to add it to model
                    self.update_model()
                    return
                break
            self.update_screen()
        elif key == b"g":
            d = Dialog(4, 4, title="Go to")
            d.add(1, 1, WLabel("Label/addr:"))
            entry = WAutoComplete(20, "", self.model.AS.get_label_list())
            entry.popup_h = 12
            entry.finish_dialog = ACTION_OK
            d.add(13, 1, entry)
            d.add(1, 2, WLabel("Press Down to auto-complete"))
            res = d.loop()
            self.update_screen()

            if res == ACTION_OK:
                value = entry.get_text()
                if '0' <= value[0] <= '9':
                    addr = int(value, 0)
                else:
                    addr = self.model.AS.resolve_label(value)
                self.goto_addr(addr, from_addr=self.cur_addr())

        elif key == editor.KEY_F1:
            help.help(self)
            self.update_screen()
        elif key == b"S":
            saveload.save_state(project_dir)
            self.show_status("Saved.")
        elif key == b"\x11":  # ^Q
            class IssueList(WListBox):
                def render_line(self, l):
                    return "%08x %s" % l
            d = Dialog(4, 4, title="Problems list")
            lw = IssueList(40, 16, self.model.AS.get_issues())
            lw.finish_dialog = ACTION_OK
            d.add(1, 1, lw)
            res = d.loop()
            self.update_screen()
            if res == ACTION_OK:
                val = lw.get_cur_line()
                if val:
                    self.goto_addr(val[0], from_addr=self.cur_addr())

        elif key == b"i":
            off, area = self.model.AS.addr2area(self.cur_addr())
            props = area[engine.PROPS]
            percent = 100 * off / (area[engine.END] - area[engine.START] + 1)
            func = self.model.AS.lookup_func(self.cur_addr())
            func = self.model.AS.get_label(func.start) if func else None
            self.show_status("Area: 0x%x %s (%s): %.1f%%, func: %s" % (
                area[engine.START], props.get("name", "noname"), props["access"], percent, func
            ))
        elif key == b"I":
            L = 5
            T = 2
            W = 66
            H = 20
            self.dialog_box(L, T, W, H)
            v = Viewer(L + 1, T + 1, W - 2, H - 2)
            lines = []
            for area in self.model.AS.get_areas():
                props = area[engine.PROPS]
                lines.append("%s (%08x-%08x):" % (props.get("name", "noname"), area[engine.START], area[engine.END]))
                flags = area[engine.FLAGS]
                l = ""
                for i in range(len(flags)):
                    if i % 64 == 0 and l:
                        lines.append(l)
                        l = ""
                    l += engine.flag2char(flags[i])
                if l:
                    lines.append(l)
            v.set_lines(lines)
            v.loop()
            self.update_screen()
        elif key == b"W":
            out_fname = "out.lst"
            with open(out_fname, "w") as f:
                engine.render_partial(TextSaveModel(f, self), 0, 0, 10000000)
            self.show_status("Disassembly listing written: " + out_fname)
        elif key == b"\x17":  # Ctrl+W
            outfile = self.write_func(self.cur_addr())
            if outfile:
                self.show_status("Wrote file: %s" % outfile)
        elif key in (b"/", b"?"):  # "/" and Shift+"/"
            class FoundException(Exception): pass
            class TextSearchModel:
                def __init__(self, substr, ctrl):
                    self.search = substr
                    self.ctrl = ctrl
                    self.cnt = 0
                def add_line(self, addr, line):
                    line = line.render()
                    if self.search in line:
                        raise FoundException(addr)
                    if self.cnt % 256 == 0:
                        self.ctrl.show_status("Searching: 0x%x" % addr)
                    self.cnt += 1
            if key == b"/":
                d = Dialog(4, 4, title="Text Search")
                d.add(1, 1, WLabel("Search for:"))
                entry = WTextEntry(20, self.search_str)
                entry.finish_dialog = ACTION_OK
                d.add(13, 1, entry)
                res = d.loop()
                self.update_screen()
                self.search_str = entry.get_text()
                if res != ACTION_OK or not self.search_str:
                    return
                addr = self.cur_addr()
            else:
                addr = self.next_addr()

            try:
                engine.render_from(TextSearchModel(self.search_str, self), addr, 10000000)
            except FoundException as res:
                self.goto_addr(res.args[0], from_addr=self.cur_addr())
            else:
                self.show_status("Not found: " + self.search_str)

        else:
            self.show_status("Unbound key: " + repr(key))
コード例 #8
0
ファイル: analyze.py プロジェクト: acolombi/event_generator
    print(
        '\tstart_date and end_date may be either YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS[.ffffff] format'
    )
    print('output written to out_lambdas.dat and out_boundaries.dat')


def read_input(args):
    return [
        engine.read_datetime(line.strip()) for line in fileinput.input(args)
    ]


if __name__ == '__main__':
    try:
        start, end, args = engine.parse_args(sys.argv)
    except Exception as e:
        print('Invalid argument.', e)
        print_usage()
        sys.exit(1)

    input_events = read_input(args[1:])
    lambdas, boundaries = engine.analyze(input_events, start, end)

    with open('out_lambdas.dat', 'w') as f:
        for item in lambdas:
            f.write("%s\n" % item)

    with open('out_boundaries.dat', 'w') as f:
        for item in boundaries:
            f.write("%s\n" % item)