Beispiel #1
0
 def current_line(self):
   if self.is_optimized_out():
     return '(frame information optimized out)'
   filename = self.filename()
   inferior_cwd = '/proc/%d/cwd' % gdb.selected_inferior().pid
   if filename.startswith('/dev/fd/'):
     filename.replace('/dev/fd/',
                      '/proc/%d/fd/' % gdb.selected_inferior().pid,
                      1)
   else:
     filename = os.path.join(inferior_cwd, filename)
   try:
     sourcefile = self.OpenFile(filename)
   except IOError:
     # couldn't find the file, let's try extracting the path from the frame
     filename = self.extract_filename()
     if filename.endswith('.pyc'):
       filename = filename[:-1]
     try:
       sourcefile = self.OpenFile(filename)
     except IOError:
       return '<file not available>'
   for _ in xrange(self.current_line_num()):
     line = sourcefile.readline()
   sourcefile.close()
   return line if line else '<file not available>'
Beispiel #2
0
def _next_instn_jump_len(gdb_frame):
    '-> None means don\'t jump'
    try:
        arch_name = gdb_frame.architecture().name()
    except AttributeError:
        arch_name = None

    if arch_name.startswith('powerpc:'):
        # 'powerpc:common64' on ppc64 big endian
        i = bytes(gdb.selected_inferior().read_memory(gdb.parse_and_eval('$pc'), 4))
        if (i == b'\x7d\x82\x10\x08') or (i == b'\x08\x10\x82\x7d'):
            return 4
        else: # not stopped on a breakpoint instruction
            return None

    triplet = _target_triplet()
    if re.match(r'^arm-', triplet):
        i = bytes(gdb.selected_inferior().read_memory(gdb.parse_and_eval('$pc'), 4))
        if i == b'\xf0\x01\xf0\xe7':
            return 4
        elif i.startswith(b'\x01\xde'):
            return 2
        elif i == b'\xf0\xf7\x00\xa0 ':
            # 'arm_linux_thumb2_le_breakpoint' from arm-linux-tdep.c in GDB 
            return 4
        else: # not stopped on a breakpoint instruction
            return None
    return None
Beispiel #3
0
    def invoke(self, *args):
        self.process.set_inferior(gdb.selected_inferior(), gdb.selected_thread())

        selected_thread = gdb.selected_thread()
        if selected_thread is None:
            raise Exception("You are calling the 'NotifySyscall' function with no thread running. This should never happen because only the catchpoint-syscall should call this function and by definition those require an running thread.")

        my_id = (gdb.selected_inferior().num, selected_thread.num)
        syscall_tracer = self._syscall_tracer_by_invokation_id.get(my_id) 

        am_at_syscall_enter = syscall_tracer is None  # if None no tracing was started so we must be at the enter of a syscall

        if am_at_syscall_enter:
            syscall_tracer = PtraceSyscallPublisher(self.gdb_module, self.process, Opts())
            self._syscall_tracer_by_invokation_id[my_id] = syscall_tracer # save this tracer to be called at the syscall's exit
            syscall_tracer.enter()

        else:
            syscall_tracer = self._syscall_tracer_by_invokation_id[my_id]  # created at the syscall's enter
            syscall_tracer.exit()

            del self._syscall_tracer_by_invokation_id[my_id] # clean up

        # publish the data from the syscall's enter/exit 
        syscall_tracer.publish_syscall()

        return False
Beispiel #4
0
    def setup_tasks(self):
        init_task = gdb.lookup_global_symbol('init_task')
        task_list = init_task.value()['tasks']

        self.pid_to_task_struct = {}

        for task in list_for_each_entry(task_list, init_task.type, 'tasks'):
            thread = gdb.selected_inferior().new_thread((1, task['pid'], 0), task)
            thread.name = task['comm'].string()

        gdb.selected_inferior().executing = False
Beispiel #5
0
        def dereference(self, pointer, target_id=0):
            """
            Recursively dereference a pointer for display
            """
            if isinstance(pointer, six.integer_types):
                fmt = ('<' if self.get_byte_order() == 'little' else '>') + {2: 'H', 4: 'L', 8: 'Q'}[self.get_addr_size()]

                addr = pointer
                chain = []
                # recursively dereference
                while True:
                    try:
                        mem = gdb.selected_inferior().read_memory(addr, self.get_addr_size())
                        (ptr,) = struct.unpack(fmt, mem)
                        if ptr in [x[1] for x in chain]:
                            break
                        chain.append(('pointer', addr))
                        addr = ptr
                    except gdb.MemoryError:
                        log.exception("Dereferencing pointer 0x{:X}".format(addr))
                        break
                    except OverflowError:
                        log.exception("Dereferencing pointer 0x{:X}".format(addr))
                        break

                # get some info for the last pointer
                # first try to resolve a symbol context for the address
                if len(chain):
                    p, addr = chain[-1]
                    output = gdb.execute('info symbol 0x{:x}'.format(addr), to_string=True)
                    log.debug('output = {}'.format(output))
                    if 'No symbol matches' not in output:
                        chain.append(('symbol', output.strip()))
                        log.debug("symbol context: {}".format(str(chain[-1])))
                    else:
                        log.debug("no symbol context, trying as a string")
                        mem = gdb.selected_inferior().read_memory(addr, 2)
                        if ord(mem[0]) <= 127 and ord(mem[0]) != 0:
                            a = []
                            for i in range(0, self.max_string):
                                mem = gdb.selected_inferior().read_memory(addr + i, 1)
                                if ord(mem[0]) == 0 or ord(mem[0]) > 127:
                                    break
                                if isinstance(mem, memoryview):
                                    a.append(mem.tobytes().decode('latin1'))
                                else:
                                    a.append(str(mem))
                            chain.append(('string', ''.join(a)))

                log.debug("chain: {}".format(chain))
            else:
                chain = []

            return chain
Beispiel #6
0
    def setup_tasks(self):
        init_task = gdb.lookup_global_symbol('init_task')
        task_list = init_task.value()['tasks']
        runqueues = gdb.lookup_global_symbol('runqueues')

        rqs = get_percpu_var(runqueues)
        rqscurrs = {long(x["curr"]) : k for (k, x) in rqs.items()}

        self.pid_to_task_struct = {}

        print("Loading tasks...", end='')
        sys.stdout.flush()

        task_count = 0
        tasks = []
        for taskg in list_for_each_entry(task_list, init_task.type, 'tasks'):
            tasks.append(taskg)
            for task in list_for_each_entry(taskg['thread_group'], init_task.type, 'thread_group'):
                tasks.append(task)

        for task in tasks:
            cpu = None
            regs = None
            active = long(task.address) in rqscurrs
            if active:
                cpu = rqscurrs[long(task.address)]
                regs = self.kdump.attr.cpu[cpu].reg

            ltask = LinuxTask(task, active, cpu, regs)
            ptid = (LINUX_KERNEL_PID, task['pid'], 0)
            try:
                thread = gdb.selected_inferior().new_thread(ptid, ltask)
            except gdb.error as e:
                print("Failed to setup task @{:#x}".format(long(task.address)))
                continue
            thread.name = task['comm'].string()

            self.arch.setup_thread_info(thread)
            ltask.attach_thread(thread)
            ltask.set_get_stack_pointer(self.arch.get_stack_pointer)

            crash.cache.tasks.cache_task(ltask)

            task_count += 1
            if task_count % 100 == 0:
                print(".", end='')
                sys.stdout.flush()
        print(" done. ({} tasks total)".format(task_count))

        gdb.selected_inferior().executing = False
Beispiel #7
0
  def stop(self):
    buf_size = gdb.parse_and_eval(self.size)

    mod_count = int(math.floor(buf_size * 8 * gdb.parse_and_eval(self.factor)))
    if mod_count < 1: mod_count = 1

    for i in range(0, mod_count):
      offset = random.randint(0,buf_size-1)
      rand_byte = gdb.parse_and_eval('%s + %d' % (self.target, offset))
      buf = gdb.selected_inferior().read_memory(rand_byte, 1)
      orig = struct.unpack('B', buf[0])[0]
      rand_bit = random.randint(0,7)
      update = (orig ^ (1 << rand_bit))
      gdb.selected_inferior().write_memory(rand_byte, chr(update), 1)
    return False
Beispiel #8
0
  def invoke(self, arg='', from_tty=False, sig=0):
    gdb.newest_frame().select()
    regs = [0] * 19
    # parse_and_eval seems to be the only way to access target registers
    for i in range(16):
      regs[i] = int(gdb.parse_and_eval("(unsigned long)$r%d" % i))
    regs[16] = int(gdb.parse_and_eval("(unsigned long)$xpsr"))
    # Don't know how to include other registers in core dump
    prstatus = ARM_prstatus()
    prstatus.pr_cursig = sig
    # Is it possible to include a target register description?
    notes = note_desc("CORE", 1, prstatus.dumps() + struct.pack("<19L", *regs))

    inf = gdb.selected_inferior()
    # How do we query the memory map from GDB?
    # TODO: Use 'info mem'
    ram = inf.read_memory(0x20000000, 128*1024)
    ccmram = inf.read_memory(0x10000000, 64*1024)
    scs = inf.read_memory(0xE000ED00, 0x40)

    core = CoreFile()
    core.set_type(Elf32_Ehdr.ET_CORE)
    core.set_machine(0x28) #ARM
    core.add_program(Elf32_Phdr.PT_NOTE, 0, notes)
    core.add_program(Elf32_Phdr.PT_LOAD, 0x10000000, ccmram)
    core.add_program(Elf32_Phdr.PT_LOAD, 0x20000000, ram)
    core.add_program(Elf32_Phdr.PT_LOAD, 0xE000ED00, scs)

    fn = arg if arg else gcore_file_name.value
    fn += "-" + time.strftime("%y%m%d-%H%M%S")
    core.dump(open(fn, "w"))
    print "(core dumped to %r)" % fn
Beispiel #9
0
 def invoke(self, arg, from_tty):
     args = gdb.string_to_argv(arg)
     
     
     # generally, we type "plot someimage" in the GDB commandline
     # where "someimage" is an instance of cv::Mat
     v = gdb.parse_and_eval(args[0])
     
     # the value v is a gdb.Value object of C++
     # code's cv::Mat, we need to translate to
     # a python object under cv2.cv
     image_size =  (v['cols'],v['rows'])
     # print v
     # these two below lines do not work. I don't know why
     # channel = gdb.execute("call "+ args[0] + ".channels()", False, True)
     # channel = v.channels();
     CV_8U =0
     CV_8S =1
     CV_16U=2
     CV_16S=3
     CV_32S=4
     CV_32F=5
     CV_64F=6
     CV_USRTYPE1=7
     CV_CN_MAX = 512
     CV_CN_SHIFT = 3
     CV_MAT_CN_MASK = (CV_CN_MAX - 1) << CV_CN_SHIFT
     flags = v['flags']
     channel = (((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1
     CV_DEPTH_MAX = (1 << CV_CN_SHIFT)
     CV_MAT_DEPTH_MASK = CV_DEPTH_MAX - 1
     depth = (flags) & CV_MAT_DEPTH_MASK
     IPL_DEPTH_SIGN = 0x80000000
     cv_elem_size = (((4<<28)|0x8442211) >> depth*4) & 15
     if (depth == CV_8S or depth == CV_16S or depth == CV_32S):
             mask = IPL_DEPTH_SIGN
     else:
             mask = 0
     ipl_depth = cv_elem_size*8 | mask     
     img = cv.CreateImageHeader(image_size, ipl_depth, channel)
     
     # conver the v['data'] type to "char*" type
     char_type = gdb.lookup_type("char")
     char_pointer_type =char_type.pointer()
     buffer = v['data'].cast(char_pointer_type)
     
     # read bytes from inferior's memory, because
     # we run the opencv-python module in GDB's own process
     # otherwise, we use memory corss processes        
     buf = v['step']['buf']
     bytes = buf[0] * v['rows'] # buf[0] is the step? Not quite sure.
     inferior = gdb.selected_inferior()
     mem = inferior.read_memory(buffer, bytes)
     
     # set the img's raw data
     cv.SetData(img, mem)
     mat = np.asarray(img[:,:])
     
     print ("Type: {}".format(mat.dtype))
     print (mat)
    def invoke(self, arg, from_tty):
        args = gdb.string_to_argv(arg)

        v = gdb.parse_and_eval(args[0])
        strType = gdb.execute("print "+ args[0] + ".type()", False, True)
        # strType contains gdb answers as a string of the form "$2 = 42"
        img = cv.CreateMat(v['rows'], v['cols'], int(strType.split(" ")[2]))

        # convert v['data'] to char*
        char_type = gdb.lookup_type("char")
        char_pointer_type = char_type.pointer()
        buffer = v['data'].cast(char_pointer_type)

        # read bytes from inferior's process memory
        buf = v['step']['buf']
        bytes = buf[0] * v['rows']
        inferior = gdb.selected_inferior()
        mem = inferior.read_memory(buffer, bytes)

        # set the matrix raw data
        cv.SetData(img, mem)

        # save matrix as an xml file and open it with matrix viewer
        cv.Save("/tmp/dump.xml", img, "matrix")
        call(["matrix-viewer", "/tmp/dump.xml"])
Beispiel #11
0
def get_current_inferior(inferior_repository, inferior_factory):
    inferior_num = gdb.selected_inferior().num
    if not inferior_repository.has_inferior(inferior_num):
        inferior = inferior_factory.create_inferior(inferior_num)
        inferior_repository.add_inferior(inferior)

    return inferior_repository.get_inferior(inferior_num)
Beispiel #12
0
def search(searchfor):
    value = searchfor
    size  = None

    i = gdb.selected_inferior()

    maps = pwndbg.vmmap.get()
    hits = []
    for vmmap in maps:
        start = vmmap.vaddr
        end   = start + vmmap.memsz
        while True:
            # No point in searching if we can't read the memory
            if not pwndbg.memory.peek(start):
                break

            start = i.search_memory(start, end - start, searchfor)

            if start is None:
                break

            # For some reason, search_memory will return a positive hit
            # when it's unable to read memory.
            if not pwndbg.memory.peek(start):
                break

            yield start
            start += len(searchfor)
Beispiel #13
0
def print_ucontext(arg, from_tty):
    """print-context: print a ucontext_t* from a signal handler"""

    # Assumes linux/amd64.
    ctxt = gdb.parse_and_eval(arg)
    size_t = "Q"
    stack_t = "Pi" + size_t
    stack_fields = ("ss_sp", "ss_flags", "ss_size")
    mcontext_t = "qqqqqqqqqqqqqqqqqqhhhhqqqq" + "P" + 8 * "Q"
    mcontext_fields = ("R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
                       "RDI", "RSI", "RBP", "RBX", "RDX", "RAX", "RCX",
                       "RSP", "RIP", "EFLAGS", "CS", "GS", "FS", "__pad0",
                       "ERR", "TRAPNO", "OLDMASK", "CR2",
                       "fpregs*") + 8 * ("__reserved1",)
    ucontext_t = "LP" + stack_t + mcontext_t # + uc_sigmask + fpregs
    ucontext_fields = ("uc_flags", "uc_link") + stack_fields + mcontext_fields

    nbytes = struct.calcsize(ucontext_t)
    data = gdb.selected_inferior().read_memory(ctxt, nbytes)
    fields = struct.unpack(ucontext_t, data)

    for field, value in zip(ucontext_fields, fields):
        if field.startswith("__"):
            continue
        print("%-10s %#18x %20d" % (field, value, value))
Beispiel #14
0
  def _update(self):
    # Update name in case it changed
    self.name = self.tp.dereference()['p_name'].string()
    self.regs = list(reg_cache) # Make a copy of the list
    if self.tp == currp:
      self.active = True
      self._update_frame()
      return

    self.active = False
    r13 = self.tp.dereference()['p_ctx']['r13']
    longtype = gdb.lookup_type('unsigned long')
    self.regs[13] = int((r13+1).cast(longtype))
    self.regs[15] = int(r13['lr'].cast(longtype))
    for i in range(4, 12):
      self.regs[i] = int(r13['r%d'%i].cast(longtype))
    self._update_frame()
    # Attempt the nasty unwind out of _port_switch_from_isr
    # get function for pc
    if str(self.block.function) == "_port_switch_from_isr":
      #if here pop exception frame from stack...
      ex_struct = "<8L"
      stack = gdb.selected_inferior().read_memory(self.regs[13],
                                                  struct.calcsize(ex_struct))
      stack = struct.unpack(ex_struct, stack)
      self.regs[:4] = stack[:4]
      self.regs[12] = stack[4]
      self.regs[14] = stack[5]
      self.regs[15] = stack[6]
      self.regs[16] = stack[7]
      # TODO check for extended/standard frame
      self.regs[13] += 0x68 # size of extended frame
      self._update_frame()
    def invoke(self, arg, from_tty):
        argv = gdb.string_to_argv(arg)
        if len(argv) != 2:
            raise gdb.GdbError('hex-dump takes exactly 2 arguments.')
        addr = gdb.parse_and_eval(argv[0]).cast(
            gdb.lookup_type('void').pointer())
        try:
            bytes = int(gdb.parse_and_eval(argv[1]))
        except ValueError:
            raise gdb.GdbError('Byte count numst be an integer value.')

        inferior = gdb.selected_inferior()

        align = gdb.parameter('hex-dump-align')
        width = gdb.parameter('hex-dump-width')
        if width == 0:
            width = 16

        mem = inferior.read_memory(addr, bytes)
        pr_addr = int(str(addr), 16)
        pr_offset = width

        if align:
            pr_offset = width - (pr_addr % width)
            pr_addr -= pr_addr % width

        for group in groups_of(mem, width, pr_offset):
            print '0x%x: ' % (pr_addr,) + '   '*(width - pr_offset),
            print ' '.join(['%02X' % (ord(g),) for g in group]) + \
                '   ' * (width - len(group) if pr_offset == width else 0) + ' ',
            print ' '*(width - pr_offset) +  ''.join(
                [g if isgraph(g) or g == ' ' else '.' for g in group])
            pr_addr += width
            pr_offset = width
Beispiel #16
0
def saveCurrentState(state):
    curr_thread = gdb.selected_thread()
    for thread in gdb.selected_inferior().threads():
        if not thread.num in state:
            thread.switch()
            state[thread.num] = HermitTaskState()
    curr_thread.switch()
Beispiel #17
0
def read(addr, count, partial=False):
    result = b''

    try:
        result = gdb.selected_inferior().read_memory(addr, count)
    except gdb.error as e:
        if not partial:
            raise

        if not hasattr(e, 'message'):
            e.message=str(e)

        stop_addr = int(e.message.split()[-1], 0)
        if stop_addr != addr:
            return read(addr, stop_addr-addr)

        # QEMU will return the start address as the failed
        # read address.  Try moving back a few pages at a time.
        stop_addr = addr + count

        # Move the stop address down to the previous page boundary
        stop_addr &= PAGE_MASK
        while stop_addr > addr:
            result = read(addr, stop_addr-addr)

            if result:
                return result

            # Move down by another page
            stop_addr -= PAGE_SIZE

    # if pwndbg.compat.python3:
        # result = bytes(result)

    return bytearray(result)
Beispiel #18
0
    def stop(self):
        """Method called by GDB when the breakpoint is triggered."""

        # Read the i-th argument of an x86_64 function call
        args = ["$rdi", "$rsi", "$rdx", "$rcx"]
        fmt_addr = int(gdb.parse_and_eval(args[self.fmt_idx]))

        # Parse /proc/<pid>/maps for this process
        proc_map = []
        with open("/proc/%d/maps" % gdb.selected_inferior().pid) as fp:
            proc_map = self._parse_map(fp.read())

        # Find the memory range which contains our format address
        for mapping in proc_map:
            if mapping["start"] <= fmt_addr < mapping["end"]:
                break
        else:
            print "%016x belongs to an unknown memory range" % fmt_addr
            return True

        # Check the memory permissions
        if "w" in mapping["perms"]:
            print "Format string in writable memory!"
            return True

        return False
Beispiel #19
0
	def step_bps(self, selector):
		inf = gdb.selected_inferior()

		bps = []
		for (name, bloc) in self.dbg_map['blocs'].items():
			buf = str(inf.read_memory(bloc['addr'], bloc['size']) )
			il = Decode(bloc['addr'], buf, Decode32Bits)
			if len(il) != len(bloc['insns']):
				raise Exception(
					"decoded instruction list of different size than instruction map: %d != %d" % (
						len(il), len(bloc['insns']) 
					)
				)

			for i in range(0, len(il)): 
				ins = il[i]
				if bloc['insns'][i]['dummy']:
					continue
				if not selector(bloc['insns'][i]['src_lineno'], bloc['insns'][i]['sir_lineno']):
					continue
				bps.append(MultiBP(
					bps, 
					"*0x%08x" % (ins[0])
				))

		return bps
Beispiel #20
0
def get_fragment_instances():
    # Walk the threadlist to find fragment instance ids. Assumes IMPALA-6416, so
    # this will not work with releases older than Impala 2.12. It may be possible
    # to search for FragmentInstanceState::Exec() in the older releases to get
    # to the FInstIDs. Returns a dictionary of FInstID->[gdb thread ID].
    # Note that multiple threads might be doing tasks for the same FInstID.

    fragment_instances = defaultdict(list)
    for thread in gdb.selected_inferior().threads():
        thread.switch()

        f = gdb.newest_frame()
        while f:
            # Skip unresolved frame
            if gdb.Frame.name(f) is None:
                f = gdb.Frame.older(f)
                continue
            if 'impala::Thread::SuperviseThread' in gdb.Frame.name(f):
                gdb.Frame.select(f)
                block = gdb.Frame.block(f)
                gdb.lookup_symbol('thread_debug_info', block)
                tdi = f.read_var('thread_debug_info')
                # No valid thread_debug_info
                if not tdi:
                    break
                hi = long(tdi['instance_id_']['hi'])
                lo = long(tdi['instance_id_']['lo'])
                fi = "%lx:%lx" % (hi, lo)
                if fi != "0:0":
                    fragment_instances[fi.strip('"')].append(thread.num)
                break
            f = gdb.Frame.older(f)
    return fragment_instances
Beispiel #21
0
def update():
    """
    For each running thread, updates the known address range
    for its stack.
    """
    curr_thread = gdb.selected_thread()

    try:
        for thread in gdb.selected_inferior().threads():
            thread.switch()
            sp = pwndbg.regs.sp

            # If we don't already know about this thread, create
            # a new Page mapping for it.
            page = stacks.get(thread.ptid, None)
            if page is None:
                start = pwndbg.memory.find_lower_boundary(sp)
                stop  = find_upper_stack_boundary(sp)
                page  = pwndbg.memory.Page(start, stop-start, 6 if not is_executable() else 7, 0, '[stack]')
                stacks[thread.ptid] = page
                continue
            elif page.objfile is None:
                page.objfile = '[stack]'

            # If we *DO* already know about this thread, just
            # update the lower boundary.
            low = pwndbg.memory.find_lower_boundary(page.vaddr)
            if low != page.vaddr:
                page.memsz  += (page.vaddr - low)
                page.vaddr   = low
    finally:
        curr_thread.switch()
Beispiel #22
0
    def invoke(self, arg, from_tty):
        args = gdb.string_to_argv(arg)

        v = gdb.parse_and_eval(args[0])
        cols, rows = int(v['cols']), int(v['rows'])
        channel, depth = self.decode_flag(v['flags'])
        if depth != CV_8U:
            print("support CV_8U only")
            return

        # conver the v['data'] type to "char*" type
        char_type = gdb.lookup_type("char")
        char_pointer_type = char_type.pointer()
        buffer_ptr = v['data'].cast(char_pointer_type)

        # read bytes from inferior's memory, because
        # we run the opencv-python module in GDB's own process
        # otherwise, we use memory corss processes
        buf = v['step']['buf']
        bytes_cnt = buf[0] * v['rows']
        inferior = gdb.selected_inferior()
        mem = inferior.read_memory(buffer_ptr, bytes_cnt)

        img = np.frombuffer(mem, dtype='uint8', count=int(bytes_cnt))
        img = img.reshape(rows, cols, channel)

        # cv2.startWindowThread()
        cv2.namedWindow('viewer')
        cv2.imshow('viewer', img)
        cv2.waitKey(0)
        cv2.destroyWindow('viewer')
	def stop(self):

		args = ["$ebp+8"]
		fmt_addr = gdb.parse_and_eval(args[self.fmt_idx])
		proc_map = []
		with open("/proc/%d/maps" % gdb.selected_inferior().pid) as fp:
			proc_map = self._parse_map(fp.read())

		for mapping in proc_map:
			if mapping["start"] <= fmt_addr < mapping["end"]:
				break
		else:
			print("%08x belongs to an unknown memory range" % fmt_addr)
			return True

		if "w" in mapping["perms"]:
			print("Format string in writable memory!")
			#gdb.execute('set logging off')	
			#gdb.execute('set logging on')	
			#gdb.execute('set logging overwrite on')	
			gdb.execute('bt -1')
			return True
			#gdb.execute('quit')

		return False
Beispiel #24
0
def all_traces():
    constants = TraceConstants()
    inf = gdb.selected_inferior()
    trace_log = gdb.lookup_global_symbol('trace_log').value()
    max_trace = ulong(gdb.parse_and_eval('max_trace'))
    trace_log = inf.read_memory(trace_log.address, max_trace)
    trace_page_size = ulong(gdb.parse_and_eval('trace_page_size'))
    last = ulong(gdb.lookup_global_symbol('trace_record_last').value()['_M_i'])
    last %= max_trace
    pivot = align_up(last, trace_page_size)
    trace_log = trace_log[pivot:] + trace_log[:pivot]
    last += max_trace - pivot
    backtrace_len = constants.backtrace_len

    i = 0
    while i < last:
        tp_key, thread, time, cpu, flags = struct.unpack('QQQII', trace_log[i:i+32])
        if tp_key == 0:
            i = align_up(i + 8, trace_page_size)
            continue
        tp = gdb.Value(tp_key).cast(gdb.lookup_type('tracepoint_base').pointer())
        sig = sig_to_string(ulong(tp['sig'])) # FIXME: cache
        i += 32

        backtrace = None
        if flags & 1:
            backtrace = struct.unpack('Q' * backtrace_len, trace_log[i:i+8*backtrace_len])
            i += 8 * backtrace_len

        size = struct.calcsize(sig)
        data = struct.unpack(sig, trace_log[i:i+size])
        i += size
        i = align_up(i, 8)
        yield Trace(tp, thread, time, cpu, data, backtrace=backtrace)
Beispiel #25
0
    def invoke(self, arg="", from_tty=False, sig=SIGINT):
        # Iterate over each ChibiOS thread and add a PRSTATUS note descriptor
        # for the general-purposes registers.
        notes = b""
        for t in chibios.thread_cache:
            prstatus = corefile.ARM_prstatus()
            if t.active:  # Only set signal for the running thread
                prstatus.pr_cursig = sig
            prstatus.pr_pid = t.lwp
            # Is it possible to include a target register description?
            notes += corefile.note_desc("CORE", 1, prstatus.dumps() + struct.pack("<19L", *t.regs))

        inf = gdb.selected_inferior()
        # How do we query the memory map from GDB?
        # TODO: Use 'info mem'
        ram = inf.read_memory(0x20000000, 128 * 1024)
        ccmram = inf.read_memory(0x10000000, 64 * 1024)
        scs = inf.read_memory(0xE000ED00, 0x40)

        core = corefile.CoreFile()
        core.set_type(corefile.ET_CORE)
        core.set_machine(0x28)  # ARM
        core.add_program(corefile.PT_NOTE, 0, notes)
        core.add_program(corefile.PT_LOAD, 0x10000000, ccmram)
        core.add_program(corefile.PT_LOAD, 0x20000000, ram)
        core.add_program(corefile.PT_LOAD, 0xE000ED00, scs)

        fn = arg if arg else gcore_file_name.value
        fn += "-" + time.strftime("%y%m%d-%H%M%S")
        core.dump(open(fn, "wb"))
        print("(core dumped to %r)" % fn)
Beispiel #26
0
 def handle_basetype(self, tp_name, p): 
     basetype_dict = {"type": tp_name}
     if tp_name in "bool int long":
         obj = gdb.parse_and_eval("*(PyIntObject *)(%s)" % p) 
         basetype_dict["value"] = str(obj["ob_ival"]) 
     elif tp_name == "float":
         obj = gdb.parse_and_eval("*(PyFloatObject *)(%s)" % p)
         basetype_dict["value"] = str(obj["ob_fval"])
     elif tp_name == "str": 
         obj = gdb.parse_and_eval("*(PyStringObject *)(%s)" % p)
         inferior = gdb.selected_inferior()
         ob_size = int(str(obj["ob_size"]))
         value = inferior.read_memory(int(str(obj["ob_sval"].address), 16), ob_size) 
         basetype_dict["value"] = str(value)
         basetype_dict["length"] = ob_size
     elif tp_name == "bytearray":
         obj = gdb.parse_and_eval("*(PyByteArrayObject *)(%s)" % p)
         basetype.update({
             "value": obj["ob_bytes"].string(),
             "ob_alloc": obj["ob_alloc"].string(),
             "ob_exports": obj["ob_exports"].string()
             }) 
     elif tp_name == "complex":
         obj = gdb.parse_and_eval("*(PyComplexObject *)(%s)" % p)
         basetype_dict["real"] = str(obj["cval"]["real"])
         basetype_dict["image"] = str(obj["cval"]["imag"])
     return basetype_dict                    
Beispiel #27
0
def reactor_threads():
    orig = gdb.selected_thread()
    for t in gdb.selected_inferior().threads():
        t.switch()
        if has_reactor():
            yield t
    orig.switch()
Beispiel #28
0
  def _GetGdbThreadMapping(self, position):
    """Gets a mapping from python tid to gdb thread num.

    There's no way to get the thread ident from a gdb thread.  We only get the
    "ID of the thread, as assigned by GDB", which is completely useless for
    everything except talking to gdb.  So in order to translate between these
    two, we have to execute 'info threads' and parse its output. Note that this
    may only work on linux, and only when python was compiled to use pthreads.
    It may work elsewhere, but we won't guarantee it.

    Args:
      position: array of pid, tid, framedepth specifying the requested position.
    Returns:
      A dictionary of the form {python_tid: gdb_threadnum}.
    """

    if len(gdb.selected_inferior().threads()) == 1:
      # gdb's output for info threads changes and only displays PID. We cheat.
      return {position[1]: 1}
    # example:
    #   8    Thread 0x7f0a637fe700 (LWP 11894) "test.py" 0x00007f0a69563e63 in
    #   select () from /usr/lib64/libc.so.6
    thread_line_regexp = r'\s*\**\s*([0-9]+)\s+[a-zA-Z]+\s+([x0-9a-fA-F]+)\s.*'
    output = gdb.execute('info threads', to_string=True)
    matches = [re.match(thread_line_regexp, line) for line
               in output.split('\n')[1:]]
    return {int(match.group(2), 16): int(match.group(1))
            for match in matches if match}
  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)))
        ))
Beispiel #30
0
def parse_proc_maps():
    # gdb doesn't have a direct way to tell us if a given address is
    # claimed by some shared library or the executable.  See
    # https://sourceware.org/bugzilla/show_bug.cgi?id=19288
    # In the interest of not requiring a patched gdb, instead we read
    # /proc/.../maps.  This only works locally, but maybe could work
    # remotely using "remote get".  FIXME.
    mapfile = '/proc/' + str(gdb.selected_inferior().pid) + '/maps'
    # Note we only examine executable mappings here.
    matcher = re.compile("^([a-fA-F0-9]+)-([a-fA-F0-9]+)\s+..x.\s+\S+\s+\S+\s+\S*(.*)$")
    mappings = []
    with open(mapfile, "r") as inp:
        for line in inp:
            match = matcher.match(line)
            if not match:
                # Header lines and such.
                continue
            start = match.group(1)
            end = match.group(2)
            name = match.group(3).strip()
            if name is '' or (name.startswith('[') and name is not '[vdso]'):
                # Skip entries not corresponding to a file.
                continue
            mappings.append((long(start, 16), long(end, 16)))
    return mappings
def hexinput(arg, padding=0):
    procs = gdb.selected_inferior()
    arg = shell_unhexlify(arg.replace("0x", "").replace("\n", ""),
                          padding) + "\\x0a"
    pid = procs.pid
    with open('/dev/stdout') as fd:
        tty_path = os.ttyname(fd.fileno())
    emit_str = baseIOCTL.format(tty_path, "c") + \
        " + " + baseIOCTL.format(tty_path, "\\n")
    for i in range(0, len(arg), 4):
        emit_str += " + " + baseIOCTL.format(tty_path, arg[i:i + 4])
    emit_str = "call (void)(" + emit_str + ")"
    SILENT = True
    gdb.execute(emit_str)
Beispiel #32
0
    def handle(self, event):
        regs = grabParameterRegs()
        pid = gdb.selected_inferior().pid

        if self.beginOfCall:
            syscall = int(regs[0])
            self.currentSyscall = syscall

            syscallEnter(syscall, regs, pid)
        else:
            syscallExit(self.currentSyscall, regs, pid)
            self.currentSyscall = -1

        self.beginOfCall = not self.beginOfCall
Beispiel #33
0
def test_coredump_command_no_target(gdb_base_fixture, capsys,
                                    settings_coredump_allowed):
    """Test coredump command shows error when no target is connected"""
    import gdb
    from memfault_gdb import MemfaultCoredump

    inferior = gdb.selected_inferior()
    inferior.threads.return_value = []

    cmd = MemfaultCoredump()
    cmd.invoke("--project-key {}".format(TEST_PROJECT_KEY), True)

    stdout = capsys.readouterr().out
    assert "No target" in stdout
Beispiel #34
0
 def __init__(self):
     self.inferior = gdb.selected_inferior()
     self.pid = 0
     self.base_addr = None
     self.efl_map = {}
     self.efl_map['CF'] = 1 << 0
     self.efl_map['PF'] = 1 << 2
     self.efl_map['AF'] = 1 << 4
     self.efl_map['ZF'] = 1 << 6
     self.efl_map['SF'] = 1 << 7
     self.efl_map['TF'] = 1 << 8
     self.efl_map['IF'] = 1 << 9
     self.efl_map['DF'] = 1 << 10
     self.efl_map['OF'] = 1 << 11
Beispiel #35
0
 def invoke(self, arg, unused_from_tty):
     addr = gdb.parse_and_eval(arg)
     pid = int(gdb.selected_inferior().pid)
     map_name = "/proc/%d/maps" % pid
     with open(map_name, 'r') as map:
         for line in map:
             line = line.rstrip()
             if not line: continue
             match = re.match(r'^(\w+)-(\w+)', line)
             if match:
                 start = int(match.group(1), 16)
                 end = int(match.group(2), 16)
                 if addr >= start and addr < end:
                     print(line)
Beispiel #36
0
def fake_fast(addr, size):
    get_heap_info()
    result = []
    idx = fastbin_idx(size)
    chunk_size = size & 0xfffffffffffffff8
    start = addr - chunk_size
    chunk_data = gdb.selected_inferior().read_memory(start, chunk_size)
    for offset in range(chunk_size - 4):
        fake_size = u32(chunk_data[offset:offset + 4])
        if fastbin_idx(fake_size) == idx:
            if ((fake_size & 2 == 2) and (fake_size & 4 == 4)) or (fake_size & 4 == 0):
                padding = addr - (start + offset - capsize) - capsize * 2
                result.append((start + offset - capsize, padding))
    return result
Beispiel #37
0
def read(addr, count, partial=False):
    """read(addr, count, partial=False) -> bytearray

    Read memory from the program being debugged.

    Arguments:
        addr(int): Address to read
        count(int): Number of bytes to read
        partial(bool): Whether less than ``count`` bytes can be returned

    Returns:
        :class:`bytearray`: The memory at the specified address,
        or ``None``.
    """
    result = b''
    count = max(int(count), 0)

    try:
        result = gdb.selected_inferior().read_memory(addr, count)
    except gdb.error as e:
        if not partial:
            raise

        if not hasattr(e, 'message'):
            e.message=str(e)

        stop_addr = int(e.message.split()[-1], 0)
        if stop_addr != addr:
            return read(addr, stop_addr-addr)

        # QEMU will return the start address as the failed
        # read address.  Try moving back a few pages at a time.
        stop_addr = addr + count

        # Move the stop address down to the previous page boundary
        stop_addr &= PAGE_MASK
        while stop_addr > addr:
            result = read(addr, stop_addr-addr)

            if result:
                return result

            # Move down by another page
            stop_addr -= PAGE_SIZE

    # if pwndbg.compat.python3:
        # result = bytes(result)

    return bytearray(result)
Beispiel #38
0
    def javascript_stack():
        """GDB in-process python supplement."""

        for thread in gdb.selected_inferior().threads():
            try:
                if not thread.is_valid():
                    print("Ignoring invalid thread %d in javascript_stack" %
                          thread.num)
                    continue
                thread.switch()

                # Switch frames so gdb actually knows about the mongo::mozjs namespace. It doesn't
                # actually matter which frame so long as it isn't the top of the stack. This also
                # enables gdb to know about the mongo::mozjs::kCurrentScope thread-local variable
                # when using gdb.parse_and_eval().
                gdb.selected_frame().older().select()
            except gdb.error as err:
                print("Ignoring GDB error '%s' in javascript_stack" % str(err))
                continue

            try:
                # The following block is roughly equivalent to this:
                # namespace mongo::mozjs {
                #   std::atomic<MozJSImplScope*> kCurrentScope = ...;
                # }
                # if (!scope || scope->_inOp == 0) { continue; }
                # print(scope->buildStackString()->c_str());
                atomic_scope = gdb.parse_and_eval(
                    "mongo::mozjs::kCurrentScope")
                ptr = MongoDBJavaScriptStack.atomic_get_ptr(atomic_scope)
                if not ptr:
                    continue

                scope = ptr.dereference()
                if scope['_inOp'] == 0:
                    continue

                gdb.execute('thread', from_tty=False, to_string=False)
                # gdb continues to not support calling methods through Python,
                # so work around it by casting the raw ptr back to its type,
                # and calling the method through execute darkness
                gdb.execute(
                    f'printf "%s\\n", ((mongo::mozjs::MozJSImplScope*)({ptr}))->buildStackString().c_str()',
                    from_tty=False,
                    to_string=False)

            except gdb.error as err:
                print("Ignoring GDB error '%s' in javascript_stack" % str(err))
                continue
    def invoke(self, arg, from_tty):
        args = gdb.string_to_argv(arg)
        var_name = str(args[0])

        picked_obj = gdb.parse_and_eval(args[0])

        buffer, width, height, channels, type, step = gdbiwtype.get_buffer_info(
            picked_obj)

        bytes = get_buffer_size(width, height, channels, type, step)
        inferior = gdb.selected_inferior()
        mem = inferior.read_memory(buffer, bytes)

        lib.plot_binary(mem, var_name, width, height, channels, type, step)
        pass
Beispiel #40
0
    def sigrt_handler(self):
        inf = gdb.selected_inferior()
        self.notifier.cond.acquire()

        if inf.pid != 0:
            res = self.edit(self.modifications)
            if res:
                # Empty the modifications
                while len(self.modifications) > 0:
                    f = self.modifications.pop()

        self.notifier.cond.notify()
        self.notifier.cond.release()

        return res
Beispiel #41
0
    def patch_addr(self, addr, code):
        inf = gdb.selected_inferior()

        if inf.pid == 0:
            print("Target is not running, there is no memory")
            return

        context = self.context
        if context == None:
            context = get_current_arch()

        cmd = ['pwn', 'asm', '-f', 'raw', '-c', context, code]
        opcodes = subprocess.check_output(cmd)

        inf.write_memory(addr, opcodes)
Beispiel #42
0
def shape_object(addr):
    inferior = gdb.selected_inferior()

    # Reeading Shape
    shape_contents = inferior.read_memory(addr, 0x20)

    shape = {}
    shape['base_'] = u64(memview_substr(shape_contents, 0, 8))
    shape['propid_'] = u64(memview_substr(shape_contents, 8, 16))
    shape['slotInfo'] = u32(memview_substr(shape_contents, 16, 20))
    shape['attr'] = u8(memview_substr(shape_contents, 20, 21))
    shape['flags'] = u8(memview_substr(shape_contents, 21, 22))
    shape['parent'] = u64(memview_substr(shape_contents, 24, 32))

    return shape
Beispiel #43
0
    def stop(self, bp):
        fr = gdb.selected_frame()

        block = fr.block()
        while block.function is None:
            block = block.superblock

        file, ptr, len_ = (arg.value(fr) for arg in block if arg.is_argument)

        try:
            buf = gdb.selected_inferior().read_memory(ptr,  len_)
            gdb.execute("set var res = {}".format(self.os_.write(file, buf.tobytes())))
            gdb.execute("set var err = 0")
        except OSError as e:
            gdb.execute("set var err = {}".format(map_errno(int(str(e)), errno, Flags)))
Beispiel #44
0
def is_inferior_running():
    inf = gdb.selected_inferior()
    """
    if m_debug.Debug:
        m_debug.dbg_print("inf.is_valid()=", inf.is_valid())
        m_debug.dbg_print("inf.num=", inf.num)
        m_debug.dbg_print("inf.pid=", inf.pid)
        m_debug.dbg_print("inf.was_attached=", inf.was_attached)
        m_debug.dbg_print("inf.threads()=", inf.threads(), "len(theads()=", len(inf.threads()))
    """

    if inf.pid != 0 and len(inf.threads()) > 0:
        return True
    else:
        return False
Beispiel #45
0
def read_dwords(addr, size):
    proc = gdb.selected_inferior()

    dword_size = get_dword_size()
    ndwords = size * dword_size

    bytearr = read_bytes(addr, ndwords)

    dwords = []
    for i in range(0, ndwords, dword_size):
        dword = bytearr[i]
        for j in range(1, dword_size):
            dword += bytearr[i + j] << j * 8
        dwords.append(dword)
    return dwords
Beispiel #46
0
    def invoke(self, arg, from_tty):
        argv = gdb.string_to_argv(arg)

        addr = gdb.parse_and_eval(argv[0]).cast(
            gdb.lookup_type('void').pointer())
        if len(argv) == 2:
            try:
                bytes = int(gdb.parse_and_eval(argv[1]))
            except ValueError:
                raise gdb.GdbError('Byte count numst be an integer value.')
        else:
            bytes = 512

        inferior = gdb.selected_inferior()

        align = gdb.parameter('hex-dump-align')
        width = gdb.parameter('hex-dump-width')
        if width == 0:
            width = 16

        mem = inferior.read_memory(addr, bytes)
        pr_addr = int(str(addr), 16)
        pr_offset = width

        if align:
            pr_offset = width - (pr_addr % width)
            pr_addr -= pr_addr % width
        start = (pr_addr) & 0xff

        print('                 ', end="")
        print('  '.join(
            ['%01X' % (i & 0x0f, ) for i in range(start, start + width)]),
              end="")
        print(' ', end="")
        print(''.join(
            ['%01X' % (i & 0x0f, ) for i in range(start, start + width)]))

        for group in groups_of(mem, width, pr_offset):
            print('0x%x: ' % (pr_addr, ) + '   ' * (width - pr_offset), end="")
            print (' '.join(['%02X' % (ord(g),) for g in group]) + \
                '   ' * (width - len(group) if pr_offset == width else 0) + ' ', end="")
            print(' ' * (width - pr_offset) + ''.join([
                chr(int.from_bytes(g, byteorder='big')) if isgraph(
                    int.from_bytes(g, byteorder='big')) or g == ' ' else '.'
                for g in group
            ]))
            pr_addr += width
            pr_offset = width
Beispiel #47
0
def find_goroutine(goid):
    """
	find_goroutine attempts to find the goroutine identified by goid.
	It returns a tuple of gdb.Value's representing the stack pointer
	and program counter pointer for the goroutine.

	@param int goid

	@return tuple (gdb.Value, gdb.Value)
	"""
    vp = gdb.lookup_type('void').pointer()
    for ptr in SliceValue(gdb.parse_and_eval("'runtime.allgs'")):
        if ptr['atomicstatus'] == G_DEAD:
            continue
        if ptr['goid'] == goid:
            break
    else:
        return None, None
    # Get the goroutine's saved state.
    pc, sp = ptr['sched']['pc'], ptr['sched']['sp']
    status = ptr['atomicstatus'] & ~G_SCAN
    # Goroutine is not running nor in syscall, so use the info in goroutine
    if status != G_RUNNING and status != G_SYSCALL:
        return pc.cast(vp), sp.cast(vp)

    # If the goroutine is in a syscall, use syscallpc/sp.
    pc, sp = ptr['syscallpc'], ptr['syscallsp']
    if sp != 0:
        return pc.cast(vp), sp.cast(vp)
    # Otherwise, the goroutine is running, so it doesn't have
    # saved scheduler state. Find G's OS thread.
    m = ptr['m']
    if m == 0:
        return None, None
    for thr in gdb.selected_inferior().threads():
        if thr.ptid[1] == m['procid']:
            break
    else:
        return None, None
    # Get scheduler state from the G's OS thread state.
    curthr = gdb.selected_thread()
    try:
        thr.switch()
        pc = gdb.parse_and_eval('$pc')
        sp = gdb.parse_and_eval('$sp')
    finally:
        curthr.switch()
    return pc.cast(vp), sp.cast(vp)
Beispiel #48
0
def nice_str(v, length=None):
  if v == 0:
    return "NULL"
  else:
    inferior = gdb.selected_inferior()
    try:
      readable = inferior.read_memory(v, 1)
    except gdb.MemoryError:
      return "(invalid)"
    try:
      if length is not None:
        return '"%s"' % v.string(length=length)
      else:
        return '"%s"' % v.string()
    except UnicodeDecodeError:
      return "(garbage)"
Beispiel #49
0
        def _state(self):
            """
            Get the state of a given target. Internal use.
            """
            target = gdb.selected_inferior()

            if target.is_valid():
                try:
                    output = gdb.execute('info program', to_string=True)
                    if "not being run" in output:
                        state = "invalid"
                    elif "stopped" in output:
                        state = "stopped"
                except gdb.error, e:
                    if 'Selected thread is running.' == str(e):
                        state = "running"
    def invoke(self, arg, _):
        argv = gdb.string_to_argv(arg)
        (exe, test_input, result_path) = argv

        gdb.execute("file {}".format(exe))
        gdb.Breakpoint("exit")
        gdb.execute("r {} 2>&1 >/dev/null".format(test_input))

        tables = get_tables()

        for (module, (addr, length)) in tables.items():
            mem = gdb.selected_inferior().read_memory(addr, length)

            with open(os.path.join(result_path, module + ".cov"),
                      "wb") as handle:
                handle.write(mem)
Beispiel #51
0
 def select_thread(self, global_num):
     if self.selected_global_num == global_num:
         return
     for thread in gdb.selected_inferior().threads():
         if thread.global_num == global_num:
             thread.switch()
             pkgs = [
                 self.pkg_unselect_thread(self.selected_global_num),
                 self.pkg_select_thread(global_num),
             ]
             self.selected_global_num = global_num
             return self.pkg_transaction(pkgs)
     self.send_error("can't find selected thread")
     #It seems that in gui window show old thread data, because user select unexisted thread.
     #Update this.
     return self.need_update()
    def stop(self):

        gdb.execute('set logging overwrite on')
        gdb.execute('set logging on')
        for i in range(0, 10):
            gdb.execute('x/s *((char **)environ+%d)' % i)
            gdb.execute('set logging off')
            gdb.execute('set logging overwrite off')
            gdb.execute('set logging on')

        gdb.execute('set logging off')

        proc_map = []
        with open("/proc/%d/maps" % gdb.selected_inferior().pid) as fp:
            f = open('procMap.txt', 'w')
            f.write(fp.read())
Beispiel #53
0
    def _GetTag(self):
      """Helper for .children() and .to_string().

      We don't know the order in which they'll be called.
      """
      if self.asdl_tag is None:
        # Get address of value and look at first 16 bits
        obj = self.val.dereference()  # location of part_value_t

        # Read the uint16_t tag
        tag_mem = gdb.selected_inferior().read_memory(obj.address, 2)

        # Unpack 2 bytes into an integer
        (self.asdl_tag,) = struct.unpack('H', tag_mem)

      return self.asdl_tag
Beispiel #54
0
    def __init__(self):
        self.inferior = gdb.selected_inferior()

        # Pagination is not helpful here
        gdb.execute("set pagination off")
        # Connect to our target
        gdb.execute("att 1")
        # Load everything into gdb and run
        gdb.execute("load")
        gdb.execute("b main")
        gdb.execute("run")
        # Stopped at the top of main. Go to tc_main via tc_prelude
        gdb.execute("del 1")
        gdb.execute("b tc_main")
        gdb.execute("set $pc=tc_prelude")
        gdb.execute("c")
Beispiel #55
0
def get_thread_list_str():
    start_pos = 0
    thread_desc = ""
    conn = gdb.selected_inferior().connection
    if not isinstance(conn, gdb.RemoteTargetConnection):
        raise gdb.GdbError("connection is the wrong type")
    while True:
        str = conn.send_packet("qXfer:threads:read::%d,200" %
                               start_pos).decode("ascii")
        start_pos += 200
        c = str[0]
        str = str[1:]
        thread_desc += str
        if c == "l":
            break
    return thread_desc
Beispiel #56
0
    def invoke(self, arg, _from_tty):
        stacks = {}
        if not arg:
            arg = 'bt'  # default to 'bt'

        current_thread = gdb.selected_thread()
        try:
            for thread in gdb.selected_inferior().threads():
                if not thread.is_valid():
                    continue
                thread.switch()
                self._process_thread_stack(arg, stacks, thread)
            self._dump_unique_stacks(stacks)
        finally:
            if current_thread and current_thread.is_valid():
                current_thread.switch()
Beispiel #57
0
    def invoke(self, arg, from_tty):
        # print('Invoke %s %s' %(arg, from_tty))
        argv = gdb.string_to_argv(arg)
        if len(argv) != 2:
            raise gdb.GdbError('hex-dump takes exactly 2 arguments.')
        addr = gdb.parse_and_eval(argv[0]).cast(
            gdb.lookup_type('void').pointer())
        try:
            bytes = int(gdb.parse_and_eval(argv[1]))
        except ValueError:
            raise gdb.GdbError('Byte count numst be an integer value.')

        inferior = gdb.selected_inferior()

        align = False  # gdb.parameter('hex-dump-align')
        width = 16  # gdb.parameter('hex-dump-width')
        if width == 0:
            width = 16

        mem = inferior.read_memory(addr, bytes)
        pr_addr = int(str(addr), 16)
        pr_offset = width

        if align:
            pr_offset = width - (pr_addr % width)
            pr_addr -= pr_addr % width

        for group in groups_of(mem, width, pr_offset):
            print '0x%x: ' % (pr_addr, ) + '   ' * (width - pr_offset),

            x = 0
            if pr_offset == width:
                x = width - len(group)
            print ' '.join(['%02X' % (ord(g),) for g in group]) + \
                '   ' * x + ' ',
            #                '   ' * (width - len(group) if pr_offset == width else 0) + ' ',

            for g in group:
                if isgraph(g) or g == ' ':
                    l.apppend(g)
                else:
                    l.append('.')
            print ' ' * (width - pr_offset) + ''.join(l)

            #                [g if isgraph(g) or g == ' ' else '.' for g in group])
            pr_addr += width
            pr_offset = width
Beispiel #58
0
def search(searchfor,
           mapping=None,
           start=None,
           end=None,
           executable=False,
           writable=False):
    value = searchfor
    size = None

    i = gdb.selected_inferior()

    maps = pwndbg.vmmap.get()
    hits = []

    if end and start:
        maps = [m for m in maps if start <= m < end]

    if executable:
        maps = [m for m in maps if m.execute]

    if writable:
        maps = [m for m in maps if m.write]

    for vmmap in maps:
        start = vmmap.vaddr
        end = start + vmmap.memsz

        if mapping and mapping not in vmmap.objfile:
            continue

        while True:
            # No point in searching if we can't read the memory
            if not pwndbg.memory.peek(start):
                break

            start = i.search_memory(start, end - start, searchfor)

            if start is None:
                break

            # For some reason, search_memory will return a positive hit
            # when it's unable to read memory.
            if not pwndbg.memory.peek(start):
                break

            yield start
            start += len(searchfor)
Beispiel #59
0
def update():
    """
    For each running thread, updates the known address range
    for its stack.
    """
    curr_thread = gdb.selected_thread()
    try:
        for thread in gdb.selected_inferior().threads():
            thread.switch()
            sp = pwndbg.regs.sp

            # Skip if sp is None or 0
            # (it might be 0 if we debug a qemu kernel)
            if not sp:
                continue

            sp_low = sp & ~(0xFFF)
            sp_low -= 0x1000

            # If we don't already know about this thread, create
            # a new Page mapping for it.
            page = stacks.get(thread.ptid, None)
            if page is None:
                start = sp_low
                stop = find_upper_stack_boundary(sp)
                page = pwndbg.memory.Page(start, stop - start,
                                          6 if not is_executable() else 7, 0,
                                          "[stack]")
                stacks[thread.ptid] = page
                continue
            elif page.objfile is None:
                pid, tid, _ = thread.ptid
                if pid == tid:
                    page.objfile = "[stack]"
                else:
                    page.objfile = "[stack:%i]" % tid

            # If we *DO* already know about this thread, just
            # update the lower boundary if it got any lower.
            low = min(page.vaddr, sp_low)
            if low != page.vaddr:
                page.memsz += page.vaddr - low
                page.vaddr = low
    finally:
        if curr_thread:
            curr_thread.switch()
Beispiel #60
0
    def __init__(self, addr, pc=None, inferior=None):
        self.addr = addr
        self.pc = pc
        self.inferior = inferior
        if inferior is None:
            self.inferior = gdb.selected_inferior()

        items = [None] * self.ITEMS_SIZE
        for frame_item in self.items_info:
            items[frame_item.id_number] = self.read_item(frame_item)
        self.items = items

        self.is_valid_frame = self.validate()
        self.is_valid_js_frame = self.is_valid_frame and self.js_validate()

        if self.is_valid_js_frame:
            self.codeBlock = CodeBlock(self.items[self.CODEBLOCK])