Exemple #1
0
    def wrapper(*args, **kwargs):
        try:
            gdb.selected_frame()
        except RuntimeError:
            raise gdb.GdbError("No frame is currently selected.")

        return function(*args, **kwargs)
Exemple #2
0
   def invoke (self, arg, from_tty):
      # Get to the call resolve function.
      i = 0
      while not symbol_equal_to_string(gdb.selected_frame().function(), self.START_FUNC):
         if symbol_equal_to_string(gdb.selected_frame().function(), self.SKIP_FUNC):
            gdb.execute("finish", False, to_string=True)

         if i > Eo_step.STEP_LIMIT:
             break
         else:
             i += 1
         gdb.execute("step", False, to_string=True)

      # If we found the function, return from it, otherwise, fail.
      if symbol_equal_to_string(gdb.selected_frame().function(), self.START_FUNC):
         gdb.execute("finish", False, to_string=True)
      else:
         print("Search limit reached, you tried calling eo_step too far from an eo_do.")
         return

      # Step until we move to a different function. FIXME: The hook can confuse us, needs to be solved.
      cur_func = gdb.selected_frame().function()
      while gdb.selected_frame().function() == cur_func:
         gdb.execute("stepi", False, to_string=True)

      # One last call to skip into the implementation
      gdb.execute("step", True)
Exemple #3
0
    def invoke(self, arg, from_tty):
        args = arg.split()
        max = 0
        if len(args) >= 1:
            max = int(args[0])
        events = collections.defaultdict(list)
        frequency = float(gdb.selected_frame().read_var("ftracer_frequency"))
        thr_max = 0
        for i in gdb.inferiors():
            for t in i.threads():
                gdb.execute("thread %d" % (t.num,))
                ftracer_len = gdb.selected_frame().read_var("ftracer_size") 
                x = gdb.selected_frame().read_var("ftracer_tbuf")
                for j in range(0, ftracer_len-1):
                    v = x[j]
                    tstamp = int(v["tstamp"])
                    if tstamp:
                        o = (t.num, v["func"], v["arg1"], v["arg2"], v["arg3"], v["rsp"])
                        events[tstamp].append(o)
                        if int(t.num) > thr_max:
                            thr_max = int(t.num)
        print ("%*s %*s %3s %-*s %s" %
                (TSTAMP_WIDTH, "TIME",
                 TSTAMP_WIDTH, "DELTA", "THR",
                 THR_WIDTH * thr_max, "FUNC", "ARGS"))
        prev = 0
        delta = 0
        start = 0
        threads = collections.defaultdict(Thr)
        k = sorted(events.keys())
        if max:
            k = collections.deque(k, max)
        for t in k:
            if prev:
                delta = t - prev
            if start == 0:
                start = t
            for e in events[t]:
                tnum = e[0]
                thr = threads[tnum]
                thr.update(int(e[5]))
		if thr_max >= 8:
			func = "<%d> " % (tnum)
			width = 30
		else:
                	func = " " * (THR_WIDTH * (tnum-1)) 
                       	width = THR_WIDTH * thr_max,
                func += " " * (thr.level() * 2) 
                func += resolve(int(e[1]))
                print "%*.2f %*.2f %3d %-*s %x %x %x" % (
                       TSTAMP_WIDTH,
                       (t - start) / frequency,
                       TSTAMP_WIDTH,
                       delta / frequency,
                       tnum,
		       width,
                       func,
                       int(e[2]), int(e[3]), int(e[4]))
            prev = t
Exemple #4
0
def getinsn():
    length = gdb.selected_frame().architecture().disassemble(gdb.selected_frame().pc())[0]['length']
    CODE = gdb.selected_inferior().read_memory(gdb.selected_frame().pc(), length).tobytes()
    md = Cs(CS_ARCH_X86, CS_MODE_64)
    md.detail = True
    insns = list(md.disasm(CODE, 0x1000))
    assert(len(insns) == 1)
    return insns[0]
Exemple #5
0
 def listOfLocals(varList):
     frame = gdb.selected_frame()
     try:
         frame = gdb.selected_frame()
         #warn("FRAME %s: " % frame)
     except RuntimeError, error:
         warn("FRAME NOT ACCESSIBLE: %s" % error)
         return []
Exemple #6
0
def setloc():
    global loc
    try:
        # loc = "%i:%s"%(gdb.newest_frame().find_sal().line, gdb.newest_frame().find_sal().symtab.filename)
        loc = "%i:%s"%(gdb.selected_frame().find_sal().line, gdb.selected_frame().find_sal().symtab.filename)
        # print(loc)
    except gdb.error:
        pass
def disassemble_block(block=None):
    global _arch
    if block is None:
        _block = gdb.selected_frame().block()
    else:
        _block = block
    if _arch is None:
        _arch = gdb.selected_frame().architecture()
    return _arch.disassemble(_block.start, _block.end)
Exemple #8
0
   def invoke (self, arg, from_tty):
      # While libeo is not reached, we step into
      while gdb.solib_name(gdb.selected_frame().pc()).find("libeo.so") == -1:
         # step by one assembly instruction, no print
         gdb.execute("stepi", False, to_string=True)

      # While we are in libeo or in an unknown function, we step into
      while (gdb.selected_frame().function() == None) or (gdb.solib_name(gdb.selected_frame().pc()).find("libeo.so") != -1):
         # step by one assembly instruction, no print
         gdb.execute("stepi", False, to_string=True)

      print "Stopped at file " + gdb.selected_frame().find_sal().symtab.filename+ " line " + str(gdb.selected_frame().find_sal().line) + " function " + str(gdb.selected_frame().function())
Exemple #9
0
    def send_expr(self):
        try:
            if self.last_frame != gdb.selected_frame():
                print('new frame')
                self.refresh_expr = True
                self.last_frame = gdb.selected_frame()
        except:
            pass

        if self.expr is not None and self.refresh_expr:
            self.refresh_expr = False
            self.vim(op='refresh', expr=self.expr)
Exemple #10
0
    def invoke(self, *args):
        try:
            gdb.execute(self._command, to_string=True)
            while not self.is_relevant_function(gdb.selected_frame()):
                gdb.execute(self._command, to_string=True)
        except RuntimeError as e:
            raise gdb.GdbError(*e.args)

        frame = gdb.selected_frame()
        index = 0
        while frame:
            frame = frame.older()
            index += 1

        self.print_stackframe(index=index - 1)
def update_observable_suggestions():
    frame = gdb.selected_frame()
    block = frame.block()
    observable_symbols = list()
    while not block is None:
        for symbol in block:
            if (symbol.is_argument or symbol.is_variable):
                name = symbol.name
                # Get struct/class fields
                if name == 'this':
                    # The GDB API is a bit convoluted, so I have to do some contortion in order
                    # to get the class type from the this object so I can iterate over its fields
                    this_type = gdb.parse_and_eval(symbol.name).dereference().type
                    for field_name, field_val in this_type.iteritems():
                        if (not field_name in observable_symbols) and (gdbiwtype.is_symbol_observable(field_val)):
                            observable_symbols.append(field_name)
                elif (not name in observable_symbols) and (gdbiwtype.is_symbol_observable(symbol)):
                    observable_symbols.append(name)
                    pass
                pass
            pass

        block = block.superblock
        pass

    if lib.is_running():
        lib.update_available_variables(observable_symbols)

    pass
Exemple #12
0
    def __init__(self, handle):
        self.handle = long(handle)

        if ObjectHandle.eg is None:
            ObjectHandle.eg = gdb.selected_frame().read_var('executor_globals')
        
        self.store = self.eg['objects_store']
Exemple #13
0
    def invoke(self, arg, from_tty):
        tc = gdb.selected_frame().read_var(arg if arg else "tc")
        if not str(tc.type).startswith("MVMThreadContext"):
            raise ValueError("Please invoke the heap analyzer command on a MVMThreadContext, usually tc.")

        # find out the GC generation we're in (just a number increasing by 1 every time we GC)
        instance = tc['instance']
        generation = instance['gc_seq_number']

        nursery = NurseryData(generation, tc['nursery_tospace'], tc['nursery_alloc_limit'], tc['nursery_alloc'])

        nursery.analyze(tc)

        nursery_memory.append(nursery)

        print("the current generation of the gc is", generation)

        sizeclass_data = []
        for sizeclass in range(MVM_GEN2_BINS):
            g2sc = Gen2Data(generation, tc['gen2']['size_classes'][sizeclass], sizeclass)
            sizeclass_data.append(g2sc)
            g2sc.analyze(tc)

        overflowdata = OverflowData(generation)

        overflowdata.analyze(tc)

        for g2sc in sizeclass_data:
            g2sc.summarize()

        nursery.summarize()

        overflowdata.summarize()
Exemple #14
0
def bt(demangle=True):
    # Find the newest frame.
    frame = gdb.selected_frame()
    while True:
        next = frame.newer()
        if not next:
            break
        frame = next

    if demangle:
        pipe = os.popen('c++filt', 'w')
    else:
        pipe = sys.stdout

    i = 0
    while frame:
        s = gdb.execute('p dumpSymbol((void*)0x%x)' % frame.pc(),
                        to_string=True)
        m = re.match(r'.*"(.*)"$', s)
        if m:
            pipe.write("#%-2d %s\n" % (i, m.group(1)))
        else:
            sal = frame.find_sal()
            lineno = ''
            if sal.symtab:
                lineno = ' at %s:%d' % (sal.symtab, sal.line)
            pipe.write("#%-2d 0x%x %s%s\n" %
                       (i, frame.pc(), frame.name(), lineno))
        frame = frame.older()
        i += 1

    pipe.close()
Exemple #15
0
 def __init__(self, thread_ctx):
     self.thread_ctx = thread_ctx
     self.old_frame = gdb.selected_frame()
     self.old_regs = self.save_regs()
     self.old_gdb_thread = gdb.selected_thread()
     self.gdb_thread = get_thread_owning_memory(thread_ctx.address)
     self.new_regs = None
Exemple #16
0
    def invoke(self, arg, for_tty):
        thread_nr = 0
        exit_thread_context()
        state = vmstate()
        for t in state.thread_list:
            with thread_context(t, state):
                cpu = thread_cpu(t)
                tid = t["_id"]
                name = t["_attr"]["_name"]["_M_elems"].string()
                newest_frame = gdb.selected_frame()
                # Non-running threads have always, by definition, just called
                # a reschedule, and the stack trace is filled with reschedule
                # related functions (switch_to, schedule, wait_until, etc.).
                # Here we try to skip such functions and instead show a more
                # interesting caller which initiated the wait.
                file_blacklist = [
                    "arch-switch.hh",
                    "sched.cc",
                    "sched.hh",
                    "mutex.hh",
                    "mutex.cc",
                    "mutex.c",
                    "mutex.h",
                ]

                # Functions from blacklisted files which are interesting
                sched_thread_join = "sched::thread::join()"
                function_whitelist = [sched_thread_join]

                def is_interesting(resolved_frame):
                    is_whitelisted = resolved_frame.func_name in function_whitelist
                    is_blacklisted = os.path.basename(resolved_frame.file_name) in file_blacklist
                    return is_whitelisted or not is_blacklisted

                fr = find_or_give_last(is_interesting, traverse_resolved_frames(newest_frame))

                if fr:
                    location = "%s at %s:%s" % (fr.func_name, strip_dotdot(fr.file_name), fr.line)
                else:
                    location = "??"

                gdb.write(
                    "%4d (0x%x) %-15s cpu%s %-10s %s vruntime %12g\n"
                    % (
                        tid,
                        ulong(t),
                        name,
                        cpu["arch"]["acpi_id"] if cpu != 0 else "?",
                        thread_status(t),
                        location,
                        t["_runtime"]["_Rtt"],
                    )
                )

                if fr and fr.func_name == sched_thread_join:
                    gdb.write("\tjoining on %s\n" % fr.frame.read_var("this"))

                show_thread_timers(t)
                thread_nr += 1
        gdb.write("Number of threads: %d\n" % thread_nr)
Exemple #17
0
	def get_frame(self):
		try:
			frame = gdb.selected_frame()
		except gdb.error:
			raise NoFrame("no frame is selected")

		return frame
Exemple #18
0
    def invoke(self, args, from_tty):
        # get the first frame
        selected_frame = frame = gdb.selected_frame()
        while frame.older():
            frame = frame.older()

        print_all = args == '-a'

        index = 0
        while frame:
            is_c = False

            is_relevant = False
            try:
                is_relevant = self.is_relevant_function(frame)
            except CyGDBError:
                pass

            if print_all or is_relevant:
                self.print_stackframe(frame, index)

            index += 1
            frame = frame.newer()

        selected_frame.select()
  def invoke(self, arg, from_tty):
    frame = gdb.selected_frame()
    val = frame.read_var(arg)
    if str(val.type.strip_typedefs()) == 'SkBitmap':
      pixels = val['fPixels']
      row_bytes = val['fRowBytes']
      info = val['fInfo']
      width = info['fWidth']
      height = info['fHeight']
      color_type = info['fColorType']
      alpha_type = info['fAlphaType']

      process = gdb.selected_inferior()
      memory_data = process.read_memory(pixels, row_bytes * height)
      size = (width, height)
      image = None
      # See Unpack.c for the values understood after the "raw" parameter.
      if color_type == ColorType.bgra_8888.value:
        if alpha_type == AlphaType.unpremul.value:
          image = Image.frombytes("RGBA", size, memory_data.tobytes(),
                                  "raw", "BGRA", row_bytes, 1)
        elif alpha_type == AlphaType.premul.value:
          # RGBA instead of RGBa, because Image.show() doesn't work with RGBa.
          image = Image.frombytes("RGBA", size, memory_data.tobytes(),
                                  "raw", "BGRa", row_bytes, 1)

      if image:
        # Fails on premultiplied alpha, it cannot convert to RGB.
        image.show()
      else:
        print ("Need to add support for %s %s." % (
               str(ColorType(int(color_type))),
               str(AlphaType(int(alpha_type)))
        ))
 def stop(self):
     frame = gdb.selected_frame().older()
     for spec in self._backtrace_specs:
         if not (frame and spec.matches(frame)):
             return False
         frame = frame.older()
     return True
Exemple #21
0
  def invoke (self, arg, from_tty):
    self.dont_repeat()
    num = arg and int(arg) or 100
    self.setup()

    try:
      while num > 0:
        num -= 1
        gdb.execute('continue')

        frame = gdb.selected_frame()
        if frame.pc() != self.func:
          raise KeyboardInterrupt

        node = gdb.parse_and_eval('(NODE*) $rsi')
        file = node['nd_file'].string()
        line = gdb.parse_and_eval('nd_line(%s)' % node)
        method = gdb.parse_and_eval('rb_id2name($rcx)')
        method = method > 0 and method.string() or '(unknown)'

        print "%s in %s:%d" % (method,file,line)

      self.teardown()
    except KeyboardInterrupt:
      self.teardown()
    except RuntimeError, text:
      self.teardown()
      if not re.search('signaled while in a function called from GDB', text):
        raise
 def break_handler(event):
   pp = pprint.PrettyPrinter(2)
   while (gdb.selected_frame().name() != 'rb_eval'):
     gdb.execute('up')
   node = gdb.parse_and_eval('node')
   pp.pprint(inspect_node(node))
   gdb.execute('continue')
Exemple #23
0
    def invoke(self, arg, from_tty):
        # delete all breakpoints
        gdb.execute("d")
        gdb.execute("break free")
        # loop iterations only in free()
        gdb.execute("continue")

        max = 1 << 24
        i = 0

        initial = self.memory()

        for i in range(max):
            try:
                mem = gdb.selected_frame().read_var("mem")
                current = self.mallocUsableSize(mem)
            except gdb.error:
                break

            bt = gdb.execute("bt", False, True)

            # 5 %
            if (current > initial*0.05):
                gdb.write("Current: %lu bytes, initial %lu bytes (%i iteration)\n" % (current, initial, i))
                gdb.write("Backtrace before current free():\n%s\n" % (bt))
                return

            if ((i % 100000) == 0):
                gdb.write("Iteration %i backtrace:\n%s\n" % (i, bt))

            gdb.execute("continue", False, True)

        gdb.write("Finished with %i iterations\n" % (i))
        gdb.write("Last backtrace:\n%s\n" % (bt))
Exemple #24
0
 def invoke(self, *args):
     try:
         gdb.execute(self._command, to_string=True)
         while not self.is_relevant_function(gdb.selected_frame()):
             gdb.execute(self._command, to_string=True)
     except RuntimeError, e:
         raise gdb.GdbError(*e.args)
Exemple #25
0
    def print_stackframe(self, frame, index, is_c=False):
        """
        Print a C, Cython or Python stack frame and the line of source code
        if available.
        """
        # do this to prevent the require_cython_frame decorator from
        # raising GdbError when calling self.cy.cy_cvalue.invoke()
        selected_frame = gdb.selected_frame()
        frame.select()

        try:
            source_desc, lineno = self.get_source_desc(frame)
        except NoFunctionNameInFrameError:
            print('#%-2d Unknown Frame (compile with -g)' % index)
            return

        if not is_c and self.is_python_function(frame):
            pyframe = libpython.Frame(frame).get_pyop()
            if pyframe is None or pyframe.is_optimized_out():
                # print this python function as a C function
                return self.print_stackframe(frame, index, is_c=True)

            func_name = pyframe.co_name
            func_cname = 'PyEval_EvalFrameEx'
            func_args = []
        elif self.is_cython_function(frame):
            cyfunc = self.get_cython_function(frame)
            f = lambda arg: self.cy.cy_cvalue.invoke(arg, frame=frame)

            func_name = cyfunc.name
            func_cname = cyfunc.cname
            func_args = [] # [(arg, f(arg)) for arg in cyfunc.arguments]
        else:
            source_desc, lineno = self.get_source_desc(frame)
            func_name = frame.name()
            func_cname = func_name
            func_args = []

        try:
            gdb_value = gdb.parse_and_eval(func_cname)
        except RuntimeError:
            func_address = 0
        else:
            # Seriously? Why is the address not an int?
            func_address = int(str(gdb_value.address).split()[0], 0)

        a = ', '.join('%s=%s' % (name, val) for name, val in func_args)
        sys.stdout.write('#%-2d 0x%016x in %s(%s)' % (index, func_address, func_name, a))

        if source_desc.filename is not None:
            sys.stdout.write(' at %s:%s' % (source_desc.filename, lineno))

        sys.stdout.write('\n')

        try:
            sys.stdout.write('    ' + source_desc.get_source(lineno))
        except gdb.GdbError:
            pass

        selected_frame.select()
Exemple #26
0
		def setup(fn_name):
			fn_full_name = self.prefix + fn_name
			print 'setting up breakpoint for', fn_full_name
			on_enter_instance = on_enter(fn_name, fn_full_name)

			# free() does not need a finishing breakpoint, because it returns a void
			# without this the leak detector is unstable, because
			# on some systems je_free() has a bunch of cross jumps somewhere:
			# anight@dura3:~/projects/test> gdb --batch -ex 'disassemble je_free' ./a.out  | grep jmpq | grep -v je_free
			#   0x000000000040554c <+428>:   jmpq   0x42aaa0 <je_tcache_event_hard>
			#   0x00000000004055a3 <+515>:   jmpq   0x40f0a0 <je_arena_dalloc_small>
			#   0x000000000040564e <+686>:   jmpq   0x421240 <je_huge_dalloc>
			#   0x000000000040566a <+714>:   jmpq   0x425aa0 <je_quarantine>
			#   0x00000000004056cb <+811>:   jmpq   0x40f2b0 <je_arena_dalloc_large>
			#
			# Luckily, this does not apply to all other memory functions

			if fn_name == 'free':
				return

			arch = gdb.selected_frame().architecture()
			sym = gdb.lookup_global_symbol(fn_full_name, gdb.SYMBOL_FUNCTIONS_DOMAIN)
			block = gdb.block_for_pc(long(sym.value().address))
			ptr = block.start
			while ptr < block.end:
				da = arch.disassemble(ptr)[0]
				if da['asm'].rstrip().endswith('retq'):
					print 'setting up finish breakpoint for', da
					on_result_ready_instance = on_result_ready(on_enter_instance, '*0x%lx' % da['addr'])
				ptr += da['length']
Exemple #27
0
 def invoke(self, n = 1):
     for frame in FrameIterator(gdb.selected_frame()):
         if n <= 0:
             frame.select()
             break
         n = n - 1
     return 1
Exemple #28
0
def update():
    m = sys.modules[__name__]

    m.current = fix_arch(gdb.selected_frame().architecture().name())
    m.ptrsize = pwndbg.typeinfo.ptrsize
    m.ptrmask = (1 << 8*pwndbg.typeinfo.ptrsize)-1

    if 'little' in gdb.execute('show endian', to_string=True):
        m.endian = 'little'
    else:
        m.endian = 'big'

    m.fmt = {
    (4, 'little'): '<I',
    (4, 'big'):    '>I',
    (8, 'little'): '<Q',
    (8, 'big'):    '>Q',
    }.get((m.ptrsize, m.endian))

    # Attempt to detect the qemu-user binary name
    if m.current == 'arm' and m.endian == 'big':
        m.qemu = 'armeb'
    elif m.current == 'mips' and m.endian == 'little':
        m.qemu = 'mipsel'
    else:
        m.qemu = m.current
Exemple #29
0
 def goto_selected_frame(self):
     try:
         frame = gdb.selected_frame()
     except gdb.error:
         return # no frame selected
     filename, line = self.to_loc(frame.find_sal())
     self.goto_file(filename, line)
Exemple #30
0
    def invoke(self, arg, from_tty):
        element_type = gdb.lookup_type('WebCore::Element')
        node_type = gdb.lookup_type('WebCore::Node')
        frame = gdb.selected_frame()
        try:
            val = gdb.Frame.read_var(frame, arg)
        except:
            print "No such variable, or invalid type"
            return

        target_type = str(val.type.target().strip_typedefs())
        if target_type == str(node_type):
            stack = []
            while val:
                stack.append([val,
                    val.cast(element_type.pointer()).dereference()['m_tagName']])
                val = val.dereference()['m_parent']

            padding = ''
            while len(stack) > 0:
                pair = stack.pop()
                print padding, pair[1], pair[0]
                padding = padding + '  '
        else:
            print 'Sorry: I don\'t know how to deal with %s yet.' % target_type
Exemple #31
0
def deduce_L():
    L = gdb.lookup_symbol('L')[0]
    if L:
        return L.value(gdb.selected_frame())
Exemple #32
0
def cur_depth():
    global GLOBAL_INDENT
    GLOBAL_INDENT = framedepth(gdb.selected_frame()) - break_depth
    return GLOBAL_INDENT
Exemple #33
0
 def find_helper(self):
     arch = gdb.selected_frame().architecture().name()
     for cls in GDBHelper.__inheritors__:
         if hasattr(cls, 'archs') and arch in cls.archs:
             return cls()
     raise LookupError('No helper found for arch {}'.format(arch))
 def wrapper(self, *args, **kwargs):
     frame = kwargs.get('frame') or gdb.selected_frame()
     if not self.is_cython_function(frame):
         raise gdb.GdbError('Selected frame does not correspond with a '
                            'Cython function we know about.')
     return function(self, *args, **kwargs)
Exemple #35
0
def TL(name):
    try:
        return gdb.lookup_symbol(name)[0].value()
    except gdb.error:
        return gdb.lookup_symbol(name)[0].value(gdb.selected_frame())
Exemple #36
0
def run_test():

    test_result = {}
    test_port = test_params["test_port"]
    rom_start = test_params['rom_start']
    ram_start = test_params['ram_start']
    ram_length = test_params['ram_length']
    invalid_addr = test_params["invalid_start"]
    error_on_invalid_access = test_params["expect_error_on_invalid_access"]
    ignore_hw_bkpt_result = test_params["ignore_hw_bkpt_result"]
    target_test_elf = test_params["test_elf"]

    assert ram_length >= MAX_TEST_SIZE
    stack_addr = ram_start + STACK_OFFSET
    test_ram_addr = ram_start + TEST_RAM_OFFSET

    fail_count = 0
    try:
        # Turn off confirmations that would block the script
        gdb_execute("set pagination off")
        gdb_execute("set confirm off")

        # Allow GDB to access even unmapped regions
        gdb_execute("set mem inaccessible-by-default off")

        # Set raw logging
        gdb_execute("set remotelogfile gdb_test_raw%d.txt" % testn)

        # Connect to server
        gdb_execute("target remote localhost:%d" % test_port)

        # Show memory regions, useful for debug and verification.
        gdb_execute("info mem")

        # Possibly useful other commands for reference:
        # info breakpoints
        # info mem
        # show code-cache
        # show stack-cache
        # show dcache
        # show mem inaccessible-by-default
        # show can-use-hw-watchpoints
        # info all-registers
        # set logging file gdb.txt
        # set logging on

        # Test running the monitor commands
        for command in monitor_commands:
            gdb_execute("mon %s" % command)

        # Load target-specific test program into flash.
        gdb_execute("load %s" % target_test_elf)

        # Reset the target and let it run so it has
        # a chance to disable the watchdog
        gdb_execute("mon reset halt")
        gdb_execute("c&")
        event = yield (0.1)
        if not is_event_signal(event, "SIGINT"):
            fail_count += 1
            print("Error - target not interrupted as expected")

        # Load test program and symbols
        test_binary = "../src/gdb_test_program/gdb_test.bin"
        test_elf = "../src/gdb_test_program/gdb_test.elf"
        gdb_execute("restore %s binary 0x%x" % (test_binary, ram_start))
        gdb_execute("add-symbol-file %s 0x%x" % (test_elf, ram_start))

        # Set pc to the test program.  Make sure
        # interrupts are disabled to prevent
        # other code from running.
        gdb_execute("set $primask = 1")
        gdb_execute("set $sp = 0x%x" % stack_addr)
        gdb_execute("b main")
        breakpoint = gdb.Breakpoint("main")
        gdb_execute("set $pc = main")
        gdb_execute("c&")
        event = yield (DEFAULT_TIMEOUT)
        if not is_event_breakpoint(event, breakpoint):
            fail_count += 1
            print("Error - could not set pc to function")
        breakpoint.delete()

        ## Stepping removed as a workaround for a GDB bug. Launchpad issue tracking this is here:
        ## https://bugs.launchpad.net/gcc-arm-embedded/+bug/1700595
        #
        #        # Test the speed of the different step types
        #        test_result["step_time_si"] = test_step_type("si")
        #        test_result["step_time_s"] = test_step_type("s")
        #        test_result["step_time_n"] = test_step_type("n")
        test_result["step_time_si"] = -1
        test_result["step_time_s"] = -1
        test_result["step_time_n"] = -1
        # TODO,c1728p9 - test speed getting stack trace
        # TODO,c1728p9 - test speed with cache turned on
        # TODO,c1728p9 - check speed vs breakpoints

        # Let target run to initialize variables
        gdb_execute("c&")
        event = yield (0.1)
        if not is_event_signal(event, "SIGINT"):
            fail_count += 1
            print("Error - target not interrupted as expected")

        # Check number of supported breakpoints, along
        # with graceful handling of a request using
        # more than the supported number of breakpoints
        break_list = []
        for i in range(MAX_BKPT):
            addr = rom_start + i * 4
            breakpoint = gdb.Breakpoint("*0x%x" % addr)
            break_list.append(breakpoint)
        while True:
            try:
                gdb_execute("c&")
                yield (0.1)
                break
            except gdb.error:
                bkpt = break_list.pop()
                bkpt.delete()
        test_result["breakpoint_count"] = len(break_list)
        for bkpt in break_list:
            bkpt.delete()

        # Check number of supported watchpoints, along
        # with graceful handling of a request using
        # more than the supported number of watchpoints
        watch_list = []
        for i in range(MAX_BKPT):
            addr = rom_start + i * 4
            breakpoint = gdb.Breakpoint("*0x%x" % addr, gdb.BP_WATCHPOINT,
                                        gdb.WP_ACCESS)
            watch_list.append(breakpoint)
        while True:
            try:
                gdb_execute("c&")
                yield (0.1)
                break
            except gdb.error:
                bkpt = watch_list.pop()
                bkpt.delete()
        test_result["watchpoint_count"] = len(watch_list)
        for bkpt in watch_list:
            bkpt.delete()

        # Make sure breakpoint is hit as expected
        rmt_func = "breakpoint_test"
        gdb_execute("set var run_breakpoint_test = 1")
        breakpoint = gdb.Breakpoint(rmt_func)
        gdb_execute("c&")
        event = yield (DEFAULT_TIMEOUT)
        if not is_event_breakpoint(event, breakpoint):
            fail_count += 1
            print("Error - breakpoint 1 test failed")
        func_name = gdb.selected_frame().function().name
        if rmt_func != func_name:
            fail_count += 1
            print("ERROR - break occurred at wrong function %s" % func_name)
        breakpoint.delete()
        gdb_execute("set var run_breakpoint_test = 0")

        # Let target run, make sure breakpoint isn't hit
        gdb_execute("set var run_breakpoint_test = 1")
        gdb_execute("c&")
        event = yield (0.1)
        if not is_event_signal(event, "SIGINT"):
            fail_count += 1
            print("Error - target not interrupted as expected")
        gdb_execute("set var run_breakpoint_test = 0")

        # Make sure hardware breakpoint is hit as expected
        rmt_func = "breakpoint_test"
        gdb_execute("set var run_breakpoint_test = 1")
        gdb_execute("hbreak %s" % rmt_func)
        gdb_execute("c&")
        event = yield (DEFAULT_TIMEOUT)
        # TODO, c1728p9 - determine why there isn't a breakpoint event returned
        #         if not is_event_breakpoint(event):
        #             fail_count += 1
        #             print("Error - breakpoint 2 test failed")
        func_name = gdb.selected_frame().function().name
        if rmt_func != func_name and not ignore_hw_bkpt_result:
            fail_count += 1
            print("ERROR - break occurred at wrong function %s" % func_name)
        gdb_execute("clear %s" % rmt_func)
        gdb_execute("set var run_breakpoint_test = 0")

        # Test valid memory write
        addr_value_list = [(test_ram_addr + i * 4, randrange(1, 50))
                           for i in range(4)]
        for addr, value in addr_value_list:
            gdb_execute("set *((int *) 0x%x) = 0x%x" % (addr, value))

        # Test invalid memory write
        invalid_addr_list = [invalid_addr + i * 4 for i in range(4)]
        for addr in invalid_addr_list:
            try:
                gdb_execute("set *((int *) 0x%x) = 0x%x" %
                            (addr, randrange(1, 50)))
                if error_on_invalid_access:
                    fail_count += 1
                    print("Error - invalid memory write did not fault @ 0x%x" %
                          addr)
            except gdb.MemoryError:
                pass

        # Test valid memory read
        for addr, value in addr_value_list:
            val_read = gdb.parse_and_eval("*((int *) 0x%x)" % addr)
            val_read = int(val_read)
            assert value == val_read

        # Test invalid memory read
        for addr in invalid_addr_list:
            try:
                gdb_execute("x 0x%x" % addr)
                if error_on_invalid_access:
                    fail_count += 1
                    print("Error - invalid memory read did not fault @ 0x%x" %
                          addr)
            except gdb.MemoryError:
                pass

        # Test watchpoints
        access_addr = long(gdb.parse_and_eval("&watchpoint_write_buffer[1]"))
        bkpt_sizes = [1, 2, 4]
        bkpt_accesses = ["read", "write", "read_write"]
        # use "range(-4, 8, 1)" for extended testing
        bkpt_addresses = [access_addr + offset for offset in range(0, 4, 1)]
        sizes = [1, 2, 4]
        accesses = ["read", "write", "read_write"]
        addresses = [access_addr]
        generator = product(bkpt_sizes, bkpt_accesses, bkpt_addresses, sizes,
                            accesses, addresses)
        for bkpt_size, bkpt_access, bkpt_addr, size, access, addr in generator:
            gdb_size = size_to_type(bkpt_size)
            gdb_access = to_gdb_access(bkpt_access)
            gdb_execute("set var watchpoint_write = %i" %
                        (1 if has_write(access) else 0))
            gdb_execute("set var watchpoint_read = %i" %
                        (1 if has_read(access) else 0))
            gdb_execute("set var watchpoint_size = %i" % size)
            gdb_execute("set var write_address = %i" % addr)
            breakpoint = gdb.Breakpoint("*(%s)0x%x" % (gdb_size, bkpt_addr),
                                        gdb.BP_WATCHPOINT, gdb_access)

            # Run until breakpoint is hit
            gdb_execute("c&")
            event = yield (0.1)
            bkpt_hit = not is_event_signal(event, "SIGINT")

            # Compare against expected result
            should_break = should_trigger_break(bkpt_size, bkpt_access,
                                                bkpt_addr, size, access, addr)
            valid = valid_watchpoint(bkpt_size, bkpt_access, bkpt_addr)

            if valid and bkpt_hit != should_break:
                fail_count += 1
                print("Error - watchpoint problem:")
                print("  Watchpoint was hit %s" % bkpt_hit)
                print("  Watchpoint should be hit %s" % should_break)
                print("  bkpt_size %s, bkpt_access %s, bkpt_address 0x%x, "
                      "size %s, access %s, addr 0x%x" %
                      (bkpt_size, bkpt_access, bkpt_addr, size, access, addr))
                print()

            breakpoint.delete()

        # TODO,c1728p9 - test reading/writing registers

        # TODO,c1728p9 - test stepping into interrupts

        # TODO,c1728p9 - test vector catch
        # -test hard fault handling
        # -test reset catch
        # TODO,c1728p9 - test signals/hard fault

        if fail_count:
            print("Test completed with %i errors" % fail_count)
        else:
            print("Test completed successfully")
    except:
        print("Main Error:")
        traceback.print_exc()
        fail_count += 1
    finally:
        test_result["fail_count"] = fail_count
        test_result_filename = "test_results%d.txt" % testn
        with open(test_result_filename, "wb") as f:
            f.write(json.dumps(test_result))
        gdb_execute("detach")
        gdb_execute("quit %i" % fail_count)
Exemple #37
0
    def invoke(self, arg, from_tty):
        "Usage can be obtained via heap -h"

        if SIZE_SZ == 0:
            retrieve_sizesz()

        inferior = get_inferior()

        if arg.find("-h") != -1:
            print_title("Heap Dump Help")
            print("")
            print_header("Options:")
            print("\n")
            print_header("{:<12}".format("-a 0x1234"))
            print("Specify an arena address")
            print_header("{:<12}".format("-b"))
            print("Print compact bin listing (only free chunks)")
            print_header("{:<12}".format("-c"))
            print("Print compact arena listing (all chunks)")
            print_header("{:<12}".format("-l"))
            print("Print a flat listing of all chunks in an arena")
            print_header("{:<12}".format("-f [#]"))
            print("Print all fast bins, or only a single fast bin")
            print_header("{:<12}".format("-s [#]"))
            print("Print all small bins, or only a single small bin")
            return

        a_found = f_found = s_found = p_fb = p_sb = p_b = p_l = p_c = 0
        for item in arg.split():
            if a_found == 1:
                arena_address = int(item, 16)
                a_found = 0
                continue
            if f_found == 1:
                f_found = 0
                try:
                    fb_number = int(item)
                except:
                    pass
                continue
            if s_found == 1:
                s_found = 0
                try:
                    sb_number = int(item)
                except:
                    pass
                continue
            if item.find("-a") != -1:
                a_found = 1
            if item.find("f") != -1:
                f_found = 1
                fb_number = None
                p_fb = 1
            if item.find("s") != -1:
                s_found = 1
                sb_number = None
                p_sb = 1
            if item.find("b") != -1:
                p_b = 1
            if item.find("l") != -1:
                p_l = 1
            if item.find("c") != -1:
                p_c = 1

        if arg.find("-a") == -1:
            try:
                main_arena = gdb.selected_frame().read_var('main_arena')
                arena_address = main_arena.address
            except RuntimeError:
                print_error("No gdb frame is currently selected.")
                return
            except ValueError:
                try:
                    res = gdb.execute('x/x &main_arena', to_string=True)
                    arena_address = int(res.strip().split()[0], 16)
                except gdb.error:
                    print_error("Debug glibc was not found.")
                    print_error(
                        "Guessing main_arena address via offset from libc.")

                    #find heap by offset from end of libc in /proc
                    libc_end, heap_begin = read_proc_maps(inferior.pid)

                    if SIZE_SZ == 4:
                        #__malloc_initialize_hook + 0x20
                        #offset seems to be +0x380 on debug glibc,
                        #+0x3a0 otherwise
                        arena_address = libc_end + 0x3a0
                    elif SIZE_SZ == 8:
                        #offset seems to be +0xe80 on debug glibc,
                        #+0xea0 otherwise
                        arena_address = libc_end + 0xea0

                    if libc_end == -1:
                        print_error("Invalid address read via /proc")
                        return

        if arena_address == 0:
            print_error("Invalid arena address (0)")
            return

        ar_ptr = malloc_state(arena_address)

        if len(arg) == 0:
            if ar_ptr.next == 0:
                print_error("No arenas could be correctly guessed.")
                print_error("Nothing was found at {0:#x}".format(
                    ar_ptr.address))
                return

            print_title("Heap Dump")
            print_header("\nArena(s) found:\n")

            try:
                #arena address obtained via read_var
                print("\t arena @ {:#x}".format(
                    int(ar_ptr.address.cast(
                        gdb.lookup_type("unsigned long")))))
            except:
                #arena address obtained via -a
                print("\t arena @ {:#x}".format(int(ar_ptr.address)))

            if ar_ptr.address != ar_ptr.next:
                #we have more than one arena

                curr_arena = malloc_state(ar_ptr.next)
                while (ar_ptr.address != curr_arena.address):
                    print("\t arena @ {:#x}".format(int(curr_arena.address)))
                    curr_arena = malloc_state(curr_arena.next)

                    if curr_arena.address == 0:
                        print_error("No arenas could be correctly found.")
                        break  #breaking infinite loop

            print("")
            return

        try:
            fb_base = ar_ptr.address.cast(gdb.lookup_type("unsigned long")) + 8
        except:
            fb_base = ar_ptr.address + 8
        if SIZE_SZ == 4:
            try:
                sb_base = ar_ptr.address.cast(
                    gdb.lookup_type("unsigned long")) + 56
            except:
                sb_base = ar_ptr.address + 56
        elif SIZE_SZ == 8:
            try:
                sb_base = ar_ptr.address.cast(gdb.lookup_type("unsigned long"))\
                        + 104
            except:
                sb_base = ar_ptr.address + 104

        try:
            mp_ = gdb.selected_frame().read_var('mp_')
            mp_address = mp_.address
        except RuntimeError:
            print_error("No gdb frame is currently selected.")
            return
        except ValueError:
            try:
                res = gdb.execute('x/x &mp_', to_string=True)
                mp_address = int(res.strip().split()[0], 16)
            except gdb.error:
                print_error("Debug glibc could not be found.")
                print_error("Guessing mp_ address via offset from main_arena.")

                if SIZE_SZ == 4:
                    try:
                        mp_address = ar_ptr.address.cast(
                            gdb.lookup_type("unsigned long")) + 0x460
                    except:
                        mp_address = ar_ptr.address + 0x460
                elif SIZE_SZ == 8:  #offset 0x880 untested on 64bit
                    try:
                        mp_address = ar_ptr.address.cast(
                            gdb.lookup_type("unsigned long")) + 0x880
                    except:
                        mp_address = ar_ptr.address + 0x460

        sbrk_base = malloc_par(mp_address).sbrk_base

        if p_fb:
            print_fastbins(inferior, fb_base, fb_number)
            print("")
        if p_sb:
            print_smallbins(inferior, sb_base, sb_number)
            print("")
        if p_b:
            print_bins(inferior, fb_base, sb_base)
            print("")
        if p_l:
            print_flat_listing(ar_ptr, sbrk_base)
            print("")
        if p_c:
            print_compact_listing(ar_ptr, sbrk_base)
            print("")
Exemple #38
0
 def lineno_equals(self, source_line=None, lineno=None):
     if source_line is not None:
         lineno = test_libcython.source_to_lineno[source_line]
     frame = gdb.selected_frame()
     self.assertEqual(libcython.cython_info.lineno(frame), lineno)
Exemple #39
0
 def test_c_step(self):
     self.break_and_run('some_c_function()')
     gdb.execute('cy step', to_string=True)
     self.assertEqual(gdb.selected_frame().name(), 'some_c_function')
Exemple #40
0
 def invoke(self, argument, from_tty):
     gdb.write(gdb.selected_frame().find_sal().symtab.fullname() +
               os.linesep)
Exemple #41
0
def cur_fn():
    return gdb.selected_frame().name()
Exemple #42
0
    def invoke(self, arg, from_tty):
        "Specify an optional arena addr: print_bin_layout main_arena=0x12345"

        if SIZE_SZ == 0:
            retrieve_sizesz()

        if len(arg) == 0:
            print_error("Please specify the free bin to dump")
            return

        try:
            if arg.find("main_arena") == -1:
                main_arena = gdb.selected_frame().read_var('main_arena')
                main_arena_address = main_arena.address
            else:
                arg = arg.split()
                for item in arg:
                    if item.find("main_arena") != -1:
                        if len(item) < 12:
                            print_error("Malformed main_arena parameter")
                            return
                        else:
                            main_arena_address = int(item[11:], 16)
        except RuntimeError:
            print_error("No frame is currently selected.")
            return
        except ValueError:
            print_error("Debug glibc was not found.")
            return

        if main_arena_address == 0:
            print_error("Invalid main_arena address (0)")
            return

        ar_ptr = malloc_state(main_arena_address)
        mutex_lock(ar_ptr)

        print_title("Bin Layout")

        b = bin_at(ar_ptr, int(arg))
        p = malloc_chunk(first(malloc_chunk(b, inuse=False)), inuse=False)
        print_once = True
        print_str = ""
        count = 0

        while p.address != int(b):
            if print_once:
                print_once = False
                print_str += "-->  "
                print_str += color_value("[bin {}]".format(int(arg)))
                count += 1

            print_str += "  <-->  "
            print_str += color_value("{:#x}".format(int(p.address)))
            count += 1
            p = malloc_chunk(first(p), inuse=False)

        if len(print_str) != 0:
            print_str += "  <--"
            print(print_str)
            print("|{}|".format(" " * (len(print_str) - 2 - count * 12)))
            print("{}".format("-" * (len(print_str) - count * 12)))
        else:
            print("Bin {} empty.".format(int(arg)))

        mutex_unlock(ar_ptr)
Exemple #43
0
    def invoke(self, arg, from_tty):
        "Specify an optional arena addr: print_mstats main_arena=0x12345"

        if SIZE_SZ == 0:
            retrieve_sizesz()

        try:
            mp = gdb.selected_frame().read_var('mp_')

            if arg.find("main_arena") == -1:
                main_arena = gdb.selected_frame().read_var('main_arena')
                main_arena_address = main_arena.address
            else:
                arg = arg.split()
                for item in arg:
                    if item.find("main_arena") != -1:
                        if len(item) < 12:
                            print_error("Malformed main_arena parameter")
                            return
                        else:
                            main_arena_address = int(item[11:], 16)
        except RuntimeError:
            print_error("No frame is currently selected.")
            return
        except ValueError:
            print_error("Debug glibc was not found.")
            return

        if main_arena_address == 0:
            print_error("Invalid main_arena address (0)")
            return

        in_use_b = mp['mmapped_mem']
        system_b = in_use_b

        print_title("Malloc Stats")

        arena = 0
        ar_ptr = malloc_state(main_arena_address)
        while (1):
            mutex_lock(ar_ptr)

            # account for top
            avail = chunksize(malloc_chunk(top(ar_ptr), inuse=True, \
                    read_data=False))
            nblocks = 1

            nfastblocks = 0
            fastavail = 0

            # traverse fastbins
            for i in range(NFASTBINS):
                p = fastbin(ar_ptr, i)
                while p != 0:
                    p = malloc_chunk(p, inuse=False)
                    nfastblocks += 1
                    fastavail += chunksize(p)
                    p = p.fd

            avail += fastavail

            # traverse regular bins
            for i in range(1, NBINS):
                b = bin_at(ar_ptr, i)
                p = malloc_chunk(first(malloc_chunk(b, inuse=False)),
                                 inuse=False)

                while p.address != int(b):
                    nblocks += 1
                    avail += chunksize(p)
                    p = malloc_chunk(first(p), inuse=False)

            print_header("Arena {}:\n".format(arena))
            print("{:16} = ".format("system bytes"), end='')
            print_value("{}".format(ar_ptr.max_system_mem), end='\n')
            print("{:16} = ".format("in use bytes"), end='')
            print_value("{}".format(ar_ptr.max_system_mem - avail), end='\n')

            system_b += ar_ptr.max_system_mem
            in_use_b += (ar_ptr.max_system_mem - avail)

            mutex_unlock(ar_ptr)
            if ar_ptr.next == main_arena_address:
                break
            else:
                ar_ptr = malloc_state(ar_ptr.next)
                arena += 1

        print_header("Total (including mmap):\n")
        print("{:16} = ".format("system bytes"), end='')
        print_value("{}".format(system_b), end='\n')
        print("{:16} = ".format("in use bytes"), end='')
        print_value("{}".format(in_use_b), end='\n')
        print("{:16} = ".format("max system bytes"), end='')
        print_value("{}".format(mp['max_total_mem']), end='\n')
        print("{:16} = ".format("max mmap regions"), end='')
        print_value("{}".format(mp['max_n_mmaps']), end='\n')
        print("{:16} = ".format("max mmap bytes"), end='')
        print_value("{}".format(mp['max_mmapped_mem']), end='\n')
import sys
import gdb
import traceback
from subprocess import call

#ulong_ptr_type = gdb.lookup_type("unsigned long int").pointer()
#thread_id_addr = gdb.Value(0x7effec60)
#thread_id_ptr = thread_id_addr.cast(ulong_ptr_type)
#thread_id_raw = long(thread_id_ptr.dereference())
#thread_id_hex = str(hex(thread_id_raw)).rstrip("L\n")
#print thread_id_hex
newest_thread_number = 2
gdb.execute("up 9999")
ulong_ptr_type = gdb.lookup_type("unsigned long int").pointer()
gdb.execute("down 9999")
thread_id_addr = gdb.selected_frame().read_var("newthread")
thread_id_ptr = thread_id_addr.cast(ulong_ptr_type)
gdb.execute("fin")
thread_id = long(thread_id_ptr.dereference())
gdb.execute("thread " + str(newest_thread_number))
tfunc = gdb.selected_frame().function().print_name.rstrip()
client_threads[thread_id] = (tfunc, newest_thread_number)
gdb_threads[newest_thread_number] = (tfunc, thread_id)
print("New thread: id == " + str(thread_id) + ", number == " +
      str(newest_thread_number) + ", tfunc == " + tfunc)
if tfunc == "request_thread_function(void*)":
    print("It works! My time machine works!")
else:
    pass
Exemple #45
0
def context_ghidra(func=None,
                   target=sys.stdout,
                   with_banner=True,
                   width=None,
                   force_show=False):
    banner = [pwndbg.ui.banner("ghidra decompile", target=target, width=width)]

    if config_context_ghidra == "never" and not force_show:
        return []
    elif config_context_ghidra == "if-no-source" and not force_show:
        try:
            with open(gdb.selected_frame().find_sal().symtab.fullname()) as _:
                pass
        except:  # a lot can go wrong in search of source code.
            return [
            ]  # we don't care what, just that it did not work out well...

    filename = gdb.current_progspace().filename
    try:
        r2 = init_radare2(filename)
        # LD         list supported decompilers (e cmd.pdc=?)
        # Outputs for example:: pdc\npdg
        if not "pdg" in r2.cmd("LD").split("\n"):
            return banner + [
                "radare2 plugin r2ghidra-dec must be installed and available from r2"
            ]
    except ImportError:  # no r2pipe present
        return banner + [
            "r2pipe not available, but required for r2->ghidra-bridge"
        ]
    if func is None:
        try:
            func = hex(pwndbg.regs[pwndbg.regs.current.pc])
        except:
            func = "main"
    src = r2.cmdj("pdgj @" + func)
    source = src.get("code", "")
    curline = None
    try:
        cur = pwndbg.regs[pwndbg.regs.current.pc]
    except AttributeError:
        cur = None  # If not running there is no current.pc
    if cur is not None:
        closest = 0
        for off in (a.get("offset", 0) for a in src.get("annotations", [])):
            if abs(cur - closest) > abs(cur - off):
                closest = off
        pos_annotations = sorted([
            a for a in src.get("annotations", []) if a.get("offset") == closest
        ],
                                 key=lambda a: a["start"])
        if pos_annotations:
            curline = source.count("\n", 0, pos_annotations[0]["start"])
    source = source.split("\n")
    # Append --> for the current line if possible
    if curline is not None:
        line = source[curline]
        if line.startswith('    '):
            line = line[4:]
        source[curline] = '--> ' + line
    # Join the source for highlighting
    source = "\n".join(source)
    if pwndbg.config.syntax_highlight:
        # highlighting depends on the file extension to guess the language, so try to get one...
        try:  # try to read the source filename from debug information
            src_filename = gdb.selected_frame().find_sal().symtab.fullname()
        except:  # if non, take the original filename and maybe append .c (just assuming is was c)
            src_filename = filename + ".c" if os.path.basename(filename).find(
                ".") < 0 else filename
        source = H.syntax_highlight(source, src_filename)
    source = source.split("\n")
    return banner + source if with_banner else source
Exemple #46
0
 def stop(self):
     connection_id = str(gdb.selected_frame().read_var('connection'))
     self.plugin.close_connection(connection_id)
     return False
Exemple #47
0
    def print_stackframe(self, frame, index, is_c=False):
        """
        Print a C, Cython or Python stack frame and the line of source code
        if available.
        """
        # do this to prevent the require_cython_frame decorator from
        # raising GdbError when calling self.cy.cy_cvalue.invoke()
        selected_frame = gdb.selected_frame()
        frame.select()

        try:
            source_desc, lineno = self.get_source_desc(frame)
        except NoFunctionNameInFrameError:
            print('#%-2d Unknown Frame (compile with -g)' % index)
            return

        if not is_c and self.is_python_function(frame):
            pyframe = libpython.Frame(frame).get_pyop()
            if pyframe is None or pyframe.is_optimized_out():
                # print this python function as a C function
                return self.print_stackframe(frame, index, is_c=True)

            func_name = pyframe.co_name
            func_cname = 'PyEval_EvalFrameEx'
            func_args = []
        elif self.is_cython_function(frame):
            cyfunc = self.get_cython_function(frame)
            f = lambda arg: self.cy.cy_cvalue.invoke(arg, frame=frame)

            func_name = cyfunc.name
            func_cname = cyfunc.cname
            func_args = []  # [(arg, f(arg)) for arg in cyfunc.arguments]
        else:
            source_desc, lineno = self.get_source_desc(frame)
            func_name = frame.name()
            func_cname = func_name
            func_args = []

        try:
            gdb_value = gdb.parse_and_eval(func_cname)
        except RuntimeError:
            func_address = 0
        else:
            func_address = gdb_value.address
            if not isinstance(func_address, int):
                # Seriously? Why is the address not an int?
                if not isinstance(func_address, (str, bytes)):
                    func_address = str(func_address)
                func_address = int(func_address.split()[0], 0)

        a = ', '.join('%s=%s' % (name, val) for name, val in func_args)
        sys.stdout.write('#%-2d 0x%016x in %s(%s)' %
                         (index, func_address, func_name, a))

        if source_desc.filename is not None:
            sys.stdout.write(' at %s:%s' % (source_desc.filename, lineno))

        sys.stdout.write('\n')

        try:
            sys.stdout.write('    ' + source_desc.get_source(lineno))
        except gdb.GdbError:
            pass

        selected_frame.select()
Exemple #48
0
 def __init__(self, plugin):
     super().__init__(gdb.selected_frame(), internal=True)
     self.plugin = plugin
Exemple #49
0
def gdb79_get_register(name):
    return gdb.selected_frame().read_register(name)
Exemple #50
0
    def invoke(self, arg, from_tty):
        arch = gdb.selected_frame().architecture().name()
        eip_str = "$eip"
        if "x86-64" in arch:
            eip_str = "$rip"
        eip = int(gdb.parse_and_eval(eip_str))
        if eip < 0x10000:
            eip += 0xffff0000

        curr = eip & 0xfffffffc
        back = curr - 0x40000
        step = 4
        found = False
        while curr > back:
            val = self.ord4(curr)
            if val == 0x00005a4d:  # PE image
                pe_image_base = curr
                pe00_base = pe_image_base + self.ord4(curr + 0x3c)
                pe_sig = self.ord4(pe00_base)
                if pe_sig == 0x4550:
                    found = True
            elif val == 0x014C5A56:  # TE image
                found = True

            if found == True: break
            curr -= step
        if not found:
            print("ERROR: could not locate PE/TE header !")
            return

        if val == 0x00005a4d:
            pe_coff_hdr = pe00_base + 4
            pe_num_sections = self.ord2(pe_coff_hdr + 2)
            pe_opt_hdr_base = pe_coff_hdr + 0x14
            pe_opt_hdr_size = self.ord2(pe_coff_hdr + 0x10)

            if pe_opt_hdr_size == 0:
                print("ERROR: optional header size is zero.")
                return

            pe_sig = self.ord2(pe_opt_hdr_base)
            if (pe_sig != 0x010B) and (pe_sig != 0x020B):
                print("ERROR: bad magic number")
                return

            code_off = self.ord4(pe_opt_hdr_base + 0x14)
            pe_num_rva_offs = 0
            pe_data_dir_offs = 0
            if pe_sig == 0x010b:
                # PE32 executable
                pe_num_rva_offs = 0x5c
                pe_data_dir_offs = 0x60
            else:
                # PE32+ executable
                pe_num_rva_offs = 0x6c
                pe_data_dir_offs = 0x70

            num_rva = self.ord4(pe_opt_hdr_base + pe_num_rva_offs)
            if self.ord4(pe_opt_hdr_base + pe_num_rva_offs) < 7:
                print("ERROR: number of RVA < 7")
                return

            pe_debug_dir_entry_offs = self.ord4(pe_opt_hdr_base +
                                                pe_data_dir_offs + 6 * 8)

        else:

            te_header = curr
            print('TE image base at 0x%08X' % te_header)
            te_header_size = 0xa * 0x4
            stripped_size = self.ord2(te_header + 6)
            code_off = self.ord4(te_header + 0xc)
            pe_start_of_file = te_header + te_header_size - stripped_size
            pe_image_base = pe_start_of_file
            pe_debug_dir_entry_offs = self.ord4(te_header + (0x8 * 0x4))

        if self.ord2(pe_image_base + pe_debug_dir_entry_offs + 0xc) != 0x2:
            print('ERROR: no debug info !')
            return

        val = self.ord4(pe_image_base + pe_debug_dir_entry_offs + 0x14)
        if val:
            baseptr = pe_image_base + val
        else:
            baseptr = pe_image_base + self.ord4(pe_image_base +
                                                pe_debug_dir_entry_offs + 0x18)
        sig = self.ord4(baseptr)
        if sig == 0x3031424e:
            baseptr += 0x10
            print("NB10 signature at 0x%X" % baseptr)
        elif sig == 0x53445352:
            baseptr += 0x18
            print("RSDS signature at 0x%X" % baseptr)
        else:
            print("Unknown debug signature")
            return

        text_base = pe_image_base + code_off
        dbgpath = self.gets(baseptr)[0:-3] + 'debug'
        print("Loading symbol %s at 0x%x" % (dbgpath, pe_image_base))
        gdb.execute("symbol-file")
        gdb.execute("add-symbol-file %s 0x%08x" % (dbgpath, text_base))
Exemple #51
0
 def __enter__(self):
     self.oldFrame = gdb.selected_frame()
     self.frame.select()
     return self
Exemple #52
0
 def _get_frame(self, gdbFrame=None):
     return gdbFrame if gdbFrame is not None else gdb.selected_frame()
Exemple #53
0
def get_current_hightlight_source():
    sal = gdb.selected_frame().find_sal()
    filename = sal.symtab.fullname()
    codes = get_hightlight_source(filename)
    return codes
Exemple #54
0
def next():
    # dbug_print("# before next : {} {}".format(cur_fn(), _line()), file=log)
    execute("next")
    # dbug_print("# after  next : {} {}".format(cur_fn(), _line()), file=log)


def step():
    # dbug_print("# before step : {} {}".format(cur_fn(), _line()), file=log)
    execute("step")
    # dbug_print("# after  step : {} {}".format(cur_fn(), _line()), file=log)
    # print("ENTER : ", end='', file=log)
    # print(cur_fn(), file=log)


execute("set pagination off")
break_fn = gdb.selected_frame().function()


outfile = input("\nEnter desired output file name (leave blank for default): ")
if not outfile:
    outfile = "linetrace_{}_{}.log".format(
        break_fn.name.split('(')[0], int(time()))

log = open(outfile, 'w')
print("\nLogging to {}\n".format(outfile))

# Read list of functions and prepare a regex to match any of them
with open("stack.txt") as f:
    break_fn_list = [line.rstrip() for line in f]

break_fn_regex = "(" + "|".join(break_fn_list) + ")\("
Exemple #55
0
    def invoke(self, arg, from_tty):
        argv = gdb.string_to_argv(arg)

        # if no max_depth given, use 0
        if len(argv) > 0:
            max_depth = int(argv[0])
        else:
            max_depth = 0

        # calculate address of the next line in outer function
        frame = gdb.selected_frame()
        pc_older = frame.older().pc()
        symtabline = gdb.find_pc_line(pc_older)
        pc_older_next = symtabline.last + 1

        depth = 0

        stack = []
        stack.append(frame)

        # get current 'pagination'
        if gdb.parameter('pagination') == True:
            pagination = 'on'
        else:
            pagination = 'off'
        gdb.execute('set pagination off')

        try:
            # while our addres not equal to the address of the next line in outer function
            while pc_older_next != gdb.selected_frame().pc():
                pc = gdb.selected_frame().pc()

                if max_depth == 0:
                    gdb.execute('next')
                elif max_depth == -1:
                    # if unlimited depth defined
                    gdb.execute('step')
                else:
                    # if we still on the current frame, then do nothing
                    if gdb.selected_frame() == stack[-1]:
                        pass
                    # if we frame up
                    elif len(stack) > 1 and gdb.selected_frame() == stack[-2]:
                        depth = depth - 1
                        stack.pop()
                    # if we frame down
                    else:
                        depth = depth + 1
                        stack.append(gdb.selected_frame())

                    if depth < max_depth:
                        gdb.execute('step')
                    else:
                        gdb.execute('next')

        except RuntimeError as e:
            error("%s" % e)
            #raise

        # restore 'pagination'
        gdb.execute('set pagination ' + pagination)
Exemple #56
0
 def get_selected_frame(cls):
     _gdbframe = gdb.selected_frame()
     if _gdbframe:
         return Frame(_gdbframe)
     return None
outputs = [
    'meTwo', '""', '"meTwo"', '{meOne, meThree}', 'MyOtherEnum(1)', '5',
    'array = {1, 2, 3, 4, 5}', 'seq(0, 0)', 'seq(0, 10)',
    'array = {"one", "two"}', 'seq(3, 3) = {1, 2, 3}',
    'seq(3, 3) = {"one", "two", "three"}',
    'Table(3, 64) = {[4] = "four", [5] = "five", [6] = "six"}',
    'Table(3, 8) = {["two"] = 2, ["three"] = 3, ["one"] = 1}',
    '{a = 1, b = "some string"}'
]

for i, expected in enumerate(outputs):
    gdb.write(f"{i+1}) expecting: {expected}: ", gdb.STDLOG)
    gdb.flush()

    functionSymbol = gdb.selected_frame().block().function
    assert functionSymbol.line == 41, str(functionSymbol.line)

    if i == 6:
        # myArray is passed as pointer to int to myDebug. I look up myArray up in the stack
        gdb.execute("up")
        raw = gdb.parse_and_eval("myArray")
    elif i == 9:
        # myOtherArray is passed as pointer to int to myDebug. I look up myOtherArray up in the stack
        gdb.execute("up")
        raw = gdb.parse_and_eval("myOtherArray")
    else:
        raw = gdb.parse_and_eval("arg")

    output = str(raw)
Exemple #58
0
def read_global_var(symname):
    return gdb.selected_frame().read_var(symname)
Exemple #59
0
def context_code():
    try:
        # Compute the closest pc and line number
        symtab = gdb.selected_frame().find_sal().symtab
        linetable = symtab.linetable()

        closest_pc = -1
        closest_line = -1
        for line in linetable:
            real_address = ctypes.c_uint64(line.pc).value
            # print("line is %d, address is %s" % (line.line, hex(real_address)))
            if closest_pc < real_address <= pwndbg.regs.pc:
                closest_line = line.line
                closest_pc = real_address

        if closest_line < 0:
            return []

        # Get the full source code
        filename = symtab.fullname()
        source = get_highlight_source(filename)

        # If it starts on line 1, it's not really using the
        # correct source code.
        if not source or closest_line <= 1:
            return []

        n = int(source_code_lines)

        # Compute the line range
        start = max(closest_line - 1 - n // 2, 0)
        end = min(closest_line - 1 + n // 2 + 1, len(source))
        num_width = len(str(end))

        # split the code
        source = source[start:end]

        # Compute the prefix_sign length
        prefix_sign = pwndbg.config.code_prefix
        prefix_width = len(prefix_sign)

        # Format the output
        formatted_source = []
        for line_number, code in enumerate(source, start=start + 1):
            fmt = ' {prefix_sign:{prefix_width}} {line_number:>{num_width}} {code}'
            if pwndbg.config.highlight_source and line_number == closest_line:
                fmt = C.highlight(fmt)

            line = fmt.format(prefix_sign=C.prefix(prefix_sign)
                              if line_number == closest_line else '',
                              prefix_width=prefix_width,
                              line_number=line_number,
                              num_width=num_width,
                              code=code)
            formatted_source.append(line)

        banner = [pwndbg.ui.banner("Source (code)"), 'In file: %s' % filename]
        banner.extend(formatted_source)
        return banner
    except:
        pass

    if not pwndbg.ida.available():
        return []

    # May be None when decompilation failed or user loaded wrong binary in IDA
    n = int(int(int(source_code_lines) /
                2))  # int twice to make it a real int instead of inthook
    code = pwndbg.ida.decompile_context(pwndbg.regs.pc, n)

    if code:
        return [pwndbg.ui.banner("Hexrays pseudocode")] + code.splitlines()
    else:
        return []
Exemple #60
0
 def symval(self, s): return s.value(gdb.selected_frame()) if s.needs_frame else s.value()
 def value(self):