Exemple #1
0
    def invoke(self, arg, from_tty):
        if arg.find("-h") != -1:
            # print_header("heap ", end="")
            # print("Options:", end="\n\n")
            # print_header("{:<15}".format("-a 0x1234"))
            # print("Specify an arena address")
            print_header("{:<15}".format("heapls"))
            print("Print a flat listing of all chunks in an arena")
            print_header("{:<15}".format("fastbins [#]"))
            print("Print all fast bins, or only a single fast bin")
            print_header("{:<15}".format("smallbins [#]"))
            print("Print all small bins, or only a single small bin")
            print_header("{:<15}".format("freebins"))
            print("Print compact bin listing (only free chunks)")
            print_header("{:<15}".format("heaplsc"))
            print("Print compact arena listing (all chunks)")
            print_header("{:<15}".format("mstats"), end="")
            print("Print memory alloc statistics similar to malloc_stats(3)")
            # print_header("{:<22}".format("print_bin_layout [#]"), end="")
            # print("Print the layout of a particular free bin")
            return

        ptm = ptmalloc(self.dbg)

        if ptm.SIZE_SZ == 0:
            ptm.set_globals()

        # XXX: from old heap command, replace
        main_arena = self.dbg.read_variable("main_arena")
        # XXX: add arena address guessing via offset without symbols
        arena_address = self.dbg.format_address(main_arena.address)
        ar_ptr = malloc_state(arena_address,
                              debugger=self.dbg,
                              version=self.version)

        # XXX: add arena address passing via arg (-a)
        if (len(arg) == 0) and (ar_ptr.next == 0):
            # struct malloc_state may be invalid size (wrong glibc version)
            print_error("No arenas could be found at {:#x}".format(
                ar_ptr.address))
            return

        print("Arena(s) found:", end="\n")
        print("  arena @ ", end="")
        print_header("{:#x}".format(int(ar_ptr.address)), end="\n")

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

            curr_arena = malloc_state(ar_ptr.next,
                                      debugger=self.dbg,
                                      version=self.version)

            while (ar_ptr.address != curr_arena.address):
                print("  arena @ ", end="")
                print_header("{:#x}".format(int(curr_arena.address)), end="\n")
                curr_arena = malloc_state(curr_arena.next,
                                          debugger=self.dbg,
                                          version=self.version)

                if curr_arena.address == 0:
                    print_error("No arenas could be correctly found.")
                    break  # breaking infinite loop
Exemple #2
0
    def invoke(self, arg, from_tty):
        "Specify an optional arena addr: print_mstats main_arena=0x12345"

        ptm = ptmalloc(debugger=self.dbg)

        if ptm.SIZE_SZ == 0:
            ptm.set_globals()

        try:
            # XXX: add mp_ address guessing via offset without symbols
            mp = self.dbg.read_variable("mp_")

            if arg.find("main_arena") == -1:
                main_arena = self.dbg.read_variable("main_arena")
                main_arena_address = self.dbg.format_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("Malloc Stats", end="\n\n")

        arena = 0
        ar_ptr = malloc_state(main_arena_address,
                              debugger=self.dbg,
                              version=self.version)
        while (1):
            ptm.mutex_lock(ar_ptr)

            # account for top
            avail = ptm.chunksize(
                malloc_chunk(ptm.top(ar_ptr),
                             inuse=True,
                             read_data=False,
                             debugger=self.dbg))
            nblocks = 1

            nfastblocks = 0
            fastavail = 0

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

            avail += fastavail

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

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

            print_header("Arena {}:".format(arena), end="\n")
            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)

            ptm.mutex_unlock(ar_ptr)
            if ar_ptr.next == main_arena_address:
                break
            else:
                next_addr = self.dbg.format_address(ar_ptr.next)
                ar_ptr = malloc_state(next_addr,
                                      debugger=self.dbg,
                                      version=self.version)
                arena += 1

        print_header("\nTotal (including mmap):", end="\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')

        # XXX: max_total_mem removed in 2.24
        try:
            # catch the error before we print anything
            print_value("{}".format(mp['max_total_mem']), end='\n')
            print("{:16} = ".format("max system bytes"), end='')
        except gdb.error:
            pass

        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')
Exemple #3
0
    def invoke(self, arg, from_tty):
        "Specify an optional arena addr: print_mstats main_arena=0x12345"

        ptm = ptmalloc(debugger=self.dbg)

        if ptm.SIZE_SZ == 0:
            ptm.set_globals()

        try:
            # XXX: add mp_ address guessing via offset without symbols
            mp = self.dbg.read_variable("mp_")

            if arg.find("main_arena") == -1:
                main_arena = self.dbg.read_variable("main_arena")
                main_arena_address = self.dbg.format_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("Malloc Stats", end="\n\n")

        arena = 0
        ar_ptr = malloc_state(main_arena_address, debugger=self.dbg,
                              version=self.version)
        while(1):
            ptm.mutex_lock(ar_ptr)

            # account for top
            avail = ptm.chunksize(malloc_chunk(ptm.top(ar_ptr), inuse=True,
                                  read_data=False, debugger=self.dbg))
            nblocks = 1

            nfastblocks = 0
            fastavail = 0

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

            avail += fastavail

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

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

            print_header("Arena {}:".format(arena), end="\n")
            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)

            ptm.mutex_unlock(ar_ptr)
            if ar_ptr.next == main_arena_address:
                break
            else:
                next_addr = self.dbg.format_address(ar_ptr.next)
                ar_ptr = malloc_state(next_addr, debugger=self.dbg,
                                      version=self.version)
                arena += 1

        print_header("\nTotal (including mmap):", end="\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')

        # XXX: max_total_mem removed in 2.24
        try:
            # catch the error before we print anything
            val = mp['max_total_mem']

            print("{:16} = ".format("max system bytes"), end='')
            print_value("{}".format(val), end='\n')
        except gdb.error:
            pass

        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')
Exemple #4
0
    def invoke(self, arg, from_tty):
        "modified from jp's phrack printing"

        ptm = ptmalloc(debugger=self.dbg)

        if ptm.SIZE_SZ == 0:
            ptm.set_globals()

        # XXX: from old heap command, replace
        main_arena = self.dbg.read_variable("main_arena")
        arena_address = self.dbg.format_address(main_arena.address)
        ar_ptr = malloc_state(arena_address, debugger=self.dbg,
                              version=self.version)
        # 8 bytes into struct malloc_state on both 32/64bit
        # XXX: fixme for glibc <= 2.19 with THREAD_STATS
        fastbinsY = int(ar_ptr.address) + 8
        fb_base = fastbinsY

        # mchunkptr bins in struct malloc_state
        if ptm.SIZE_SZ == 4:
            bins_offset = 4 + 4 + 40 + 4 + 4  # 56
            sb_base = int(ar_ptr.address) + bins_offset
        elif ptm.SIZE_SZ == 8:
            bins_offset = 4 + 4 + 80 + 8 + 8  # 104
            sb_base = int(ar_ptr.address) + bins_offset

        # print_title("Heap Dump")

        for fb in range(0, ptm.NFASTBINS):
            print_once = True
            p = malloc_chunk(fb_base - (2 * ptm.SIZE_SZ) + fb * ptm.SIZE_SZ,
                             inuse=False, debugger=self.dbg)

            while (p.fd != 0):
                if p.fd is None:
                    break

                if print_once:
                    print_once = False
                    if fb > 0:
                        print("")
                    print_header("fast bin {}".format(fb), end="")
                    print(" @ ", end="")
                    print_value("{:#x}".format(p.fd), end="")

                print("\n\tfree chunk @ ", end="")
                print_value("{:#x} ".format(int(p.fd)))
                print("- size ", end="")
                p = malloc_chunk(p.fd, inuse=False, debugger=self.dbg)
                print("{:#x}".format(int(ptm.chunksize(p))), end="")

        for i in range(1, ptm.NBINS):
            print_once = True

            b = sb_base + i * 2 * ptm.SIZE_SZ - 4 * ptm.SIZE_SZ
            first = ptm.first(malloc_chunk(b, inuse=False, debugger=self.dbg))
            p = malloc_chunk(first, inuse=False, debugger=self.dbg)

            while p.address != int(b):
                if print_once:
                    print("")
                    print_once = False

                    if i == 1:
                        print_header("unsorted bin", end="")
                    else:
                        print_header("small bin {}".format(i))

                    print(" @ ", end="")
                    print_value("{:#x}".format(int(b) + 2 * ptm.SIZE_SZ),
                                end="")

                print("\n\tfree chunk @ ", end="")
                print_value("{:#x} ".format(int(p.address)))
                print("- size ", end="")
                print("{:#x}".format(int(ptm.chunksize(p))), end="")
                p = malloc_chunk(ptm.first(p), inuse=False, debugger=self.dbg)

        print("")
Exemple #5
0
    def invoke(self, arg, from_tty):
        # XXX: self.dbg.string_to_argv
        if arg.find("-h") != -1:
            # print_header("heap ", end="")
            # print("Options:", end="\n\n")
            # print_header("{:<15}".format("-a 0x1234"))
            # print("Specify an arena address")
            print_header("{:<15}".format("heapls"))
            print("Print a flat listing of all chunks in an arena")
            print_header("{:<15}".format("fastbins [#]"))
            print("Print all fast bins, or only a single fast bin")
            print_header("{:<15}".format("smallbins [#]"))
            print("Print all small bins, or only a single small bin")
            print_header("{:<15}".format("freebins"))
            print("Print compact bin listing (only free chunks)")
            print_header("{:<15}".format("heaplsc"))
            print("Print compact arena listing (all chunks)")
            print_header("{:<15}".format("mstats"), end="")
            print("Print memory alloc statistics similar to malloc_stats(3)")
            # print_header("{:<22}".format("print_bin_layout [#]"), end="")
            # print("Print the layout of a particular free bin")
            return

        ptm = ptmalloc(self.dbg)

        if ptm.SIZE_SZ == 0:
            ptm.set_globals()

        # XXX: from old heap command, replace
        main_arena = self.dbg.read_variable("main_arena")
        # XXX: add arena address guessing via offset without symbols
        arena_address = self.dbg.format_address(main_arena.address)
        ar_ptr = malloc_state(arena_address, debugger=self.dbg,
                              version=self.version)

        # XXX: add arena address passing via arg (-a)
        if (len(arg) == 0) and (ar_ptr.next == 0):
            # struct malloc_state may be invalid size (wrong glibc version)
            print_error("No arenas could be found at {:#x}".format(
                        ar_ptr.address))
            return

        print("Arena(s) found:", end="\n")
        print("  arena @ ", end="")
        print_header("{:#x}".format(int(ar_ptr.address)), end="\n")

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

            curr_arena = malloc_state(ar_ptr.next, debugger=self.dbg,
                                      version=self.version)

            while (ar_ptr.address != curr_arena.address):
                print("  arena @ ", end="")
                print_header("{:#x}".format(int(curr_arena.address)), end="\n")
                curr_arena = malloc_state(curr_arena.next, debugger=self.dbg,
                                          version=self.version)

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