class MyScriptedProcess(ScriptedProcess):
    memory_regions = [
        lldb.SBMemoryRegionInfo("stack", 0x1040b2000, 0x1040b4000, 0b110, True,
                                True)
    ]

    stack_memory_dump = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                     'main.stack-dump')

    def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData):
        super().__init__(target, args)

    def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
        for region in self.memory_regions:
            if region.GetRegionBase() <= addr < region.GetRegionEnd():
                return region
        return None

    def get_thread_with_id(self, tid: int):
        return {}

    def get_registers_for_thread(self, tid: int):
        return {}

    def read_memory_at_address(self, addr: int, size: int) -> lldb.SBData:
        data = lldb.SBData()

        with open(self.stack_memory_dump, 'rb') as f:
            stack_mem = f.read(-1)
            if not stack_mem:
                return data

            mem_region = self.get_memory_region_containing_address(addr)

            if not mem_region or addr + size > mem_region.GetRegionEnd():
                return data

            offset = addr - mem_region.GetRegionBase()
            shrunk_stack_mem = stack_mem[offset:offset + size]

            error = lldb.SBError()
            data.SetData(error, shrunk_stack_mem,
                                    self.target.GetByteOrder(),
                                    self.target.GetAddressByteSize())
        return data

    def get_loaded_images(self):
        return self.loaded_images

    def get_process_id(self) -> int:
        return 42

    def should_stop(self) -> bool:
        return True

    def is_alive(self) -> bool:
        return True

    def get_scripted_thread_plugin(self):
        return MyScriptedThread.__module__ + "." + MyScriptedThread.__name__
 def get_memory_region_containing_address(
         self, addr: int) -> lldb.SBMemoryRegionInfo:
     mem_region = lldb.SBMemoryRegionInfo()
     error = self.corefile_process.GetMemoryRegionInfo(addr, mem_region)
     if error.Fail():
         return None
     return mem_region
Exemplo n.º 3
0
    def address_breakpoints(self):
        """Test that breakpoints set on a bad address say they are bad."""
        target, process, thread, bkpt = \
            lldbutil.run_to_source_breakpoint(self,
                                              "Set a breakpoint here",
                                              lldb.SBFileSpec("main.c"))

        # illegal_address will hold (optionally) an address that, if
        # used as a breakpoint, will generate an unresolved breakpoint.
        illegal_address = None

        # Walk through all the memory regions in the process and
        # find an address that is invalid.
        regions = process.GetMemoryRegions()
        for region_idx in range(regions.GetSize()):
            region = lldb.SBMemoryRegionInfo()
            regions.GetMemoryRegionAtIndex(region_idx, region)
            if illegal_address == None or \
                region.GetRegionEnd() > illegal_address:
                illegal_address = region.GetRegionEnd()

        if illegal_address is not None:
            # Now, set a breakpoint at the address we know is illegal.
            bkpt = target.BreakpointCreateByAddress(illegal_address)
            # Verify that breakpoint is not resolved.
            for bp_loc in bkpt:
                self.assertEquals(bp_loc.IsResolved(), False)
        else:
            self.fail(
                "Could not find an illegal address at which to set a bad breakpoint."
            )
Exemplo n.º 4
0
    def test_no_overlapping_regions(self):
        # In the past on Windows we were recording AllocationBase as the base address
        # of the current region, not BaseAddress. So if a range of pages was split
        # into regions you would see several regions with the same base address.
        # This checks that this no longer happens (and it shouldn't happen on any
        # other OS either).
        self.setup_program()

        regions = self.process().GetMemoryRegions()
        num_regions = regions.GetSize()

        if num_regions:
            region = lldb.SBMemoryRegionInfo()
            regions.GetMemoryRegionAtIndex(0, region)
            previous_base = region.GetRegionBase()
            previous_end = region.GetRegionEnd()

            for idx in range(1, regions.GetSize()):
                regions.GetMemoryRegionAtIndex(idx, region)

                # Check that it does not overlap the previous region.
                # This could happen if we got the base addresses or size wrong.
                # Also catches the base addresses being the same.
                region_base = region.GetRegionBase()
                region_end = region.GetRegionEnd()

                self.assertFalse((region_base < previous_end)
                                 and (previous_base < region_end),
                                 "Unexpected overlapping memory region found.")

                previous_base = region_base
                previous_end = region_end
Exemplo n.º 5
0
        def check_region(index, start, end, read, write, execute, mapped, name):
            region_info = lldb.SBMemoryRegionInfo()
            self.assertTrue(
                self.process.GetMemoryRegionInfo(start, region_info).Success())
            self.assertEqual(start, region_info.GetRegionBase())
            self.assertEqual(end, region_info.GetRegionEnd())
            self.assertEqual(read, region_info.IsReadable())
            self.assertEqual(write, region_info.IsWritable())
            self.assertEqual(execute, region_info.IsExecutable())
            self.assertEqual(mapped, region_info.IsMapped())
            self.assertEqual(name, region_info.GetName())

            # Ensure we have the same regions as SBMemoryRegionInfoList contains.
            if index >= 0 and index < regions_count:
                region_info_from_list = lldb.SBMemoryRegionInfo()
                self.assertTrue(region_info_list.GetMemoryRegionAtIndex(
                    index, region_info_from_list))
                self.assertEqual(region_info_from_list, region_info)
    def test(self):
        class MyResponder(MockGDBServerResponder):

            def qHostInfo(self):
                return "ptrsize:8;endian:little;vm-page-size:4096;"

            def qMemoryRegionInfo(self, addr):
                if addr == 0:
                    return "start:0;size:100000000;"
                if addr == 0x100000000:
                    return "start:100000000;size:4000;permissions:rx;dirty-pages:;"
                if addr == 0x100004000:
                    return "start:100004000;size:4000;permissions:r;dirty-pages:0x100004000;"
                if addr == 0x1000a2000:
                    return "start:1000a2000;size:5000;permissions:r;dirty-pages:0x1000a2000,0x1000a3000,0x1000a4000,0x1000a5000,0x1000a6000;"

        self.server.responder = MyResponder()
        target = self.dbg.CreateTarget('')
        if self.TraceOn():
          self.runCmd("log enable gdb-remote packets")
          self.addTearDownHook(
                lambda: self.runCmd("log disable gdb-remote packets"))
        process = self.connect(target)

        # A memory region where we don't know anything about dirty pages
        region = lldb.SBMemoryRegionInfo()
        err = process.GetMemoryRegionInfo(0, region)
        self.assertTrue(err.Success())
        self.assertFalse(region.HasDirtyMemoryPageList())
        self.assertEqual(region.GetNumDirtyPages(), 0)
        region.Clear()

        # A memory region with dirty page information -- and zero dirty pages
        err = process.GetMemoryRegionInfo(0x100000000, region)
        self.assertTrue(err.Success())
        self.assertTrue(region.HasDirtyMemoryPageList())
        self.assertEqual(region.GetNumDirtyPages(), 0)
        self.assertEqual(region.GetPageSize(), 4096)
        region.Clear()

        # A memory region with one dirty page
        err = process.GetMemoryRegionInfo(0x100004000, region)
        self.assertTrue(err.Success())
        self.assertTrue(region.HasDirtyMemoryPageList())
        self.assertEqual(region.GetNumDirtyPages(), 1)
        self.assertEqual(region.GetDirtyPageAddressAtIndex(0), 0x100004000)
        region.Clear()

        # A memory region with multple dirty pages
        err = process.GetMemoryRegionInfo(0x1000a2000, region)
        self.assertTrue(err.Success())
        self.assertTrue(region.HasDirtyMemoryPageList())
        self.assertEqual(region.GetNumDirtyPages(), 5)
        self.assertEqual(region.GetDirtyPageAddressAtIndex(4), 0x1000a6000)
        region.Clear()
Exemplo n.º 7
0
 def do_info(self, name):
     meminfo = lldb.SBMemoryRegionInfo()
     if name == 'memory':
         process = self.interpreter.GetProcess()
         minfolist = process.GetMemoryRegions()
         for i in range(10):
             if minfolist.GetMemoryRegionAtIndex(i, meminfo):
                 print('Got %d name: %s' % (i, meminfo.GetName()))
             else:
                 print('Got %d name: %s' % (i, 'failed'))
                 break
Exemplo n.º 8
0
def get_search_regions() :

    memoryRegions = lldb.process.GetMemoryRegions()
    print 'total memory regions: ', memoryRegions.GetSize()
    region = lldb.SBMemoryRegionInfo()

    searchRegions = []
    for i in range(memoryRegions.GetSize()):
        if memoryRegions.GetMemoryRegionAtIndex(i, region):
            if region.IsWritable() and region.IsReadable() and not region.IsExecutable():
                #print '[{0:x},{1:x}]'.format(region.GetRegionBase(), region.GetRegionEnd())
                searchRegions.append((region.GetRegionBase(), region.GetRegionEnd()))

    #sort regions in descending order, so that large regions get processed early 
    searchRegions.sort(key=lambda tup: tup[1] - tup[0], reverse=True)
#    for region in searchRegions :
#        print '{0:x} [{1:x}, {2:x})'.format(region[1]-region[0], region[0], region[1])

    searchRegionCount = len(searchRegions)
    print 'target memory regions: ', searchRegionCount 

    return searchRegions
Exemplo n.º 9
0
    def get_all_memory_sections(self):
        # currently missing stack and heap.. great i know
        # lldb-devs mentions how its not possible, but vmmap does it :(

        process = self.get_current_process()
    
        region_list = process.GetMemoryRegions()

        maps = []
        for i in range(region_list.GetSize()):
            region = lldb.SBMemoryRegionInfo()

            region_list.GetMemoryRegionAtIndex(i, region)

            begin_address = region.GetRegionBase()
            end_address = region.GetRegionEnd() - 1
            name = region.GetName() 
            if name is None:
                name = ''
            perm_str = ''

            maps.append(MemoryMap(begin_address, end_address, region.IsReadable(), region.IsWritable(), region.IsExecutable(), name))

        return maps
Exemplo n.º 10
0
    def check_memory_regions(self, process, region_count):
        region_list = process.GetMemoryRegions()
        self.assertEqual(region_list.GetSize(), region_count)

        region = lldb.SBMemoryRegionInfo()

        # Check we have the right number of regions.
        self.assertEqual(region_list.GetSize(), region_count)

        # Check that getting a region beyond the last in the list fails.
        self.assertFalse(
            region_list.GetMemoryRegionAtIndex(region_count, region))

        # Check each region is valid.
        for i in range(region_list.GetSize()):
            # Check we can actually get this region.
            self.assertTrue(region_list.GetMemoryRegionAtIndex(i, region))

            # Every region in the list should be mapped.
            self.assertTrue(region.IsMapped())

            # Test the address at the start of a region returns it's enclosing
            # region.
            begin_address = region.GetRegionBase()
            region_at_begin = lldb.SBMemoryRegionInfo()
            error = process.GetMemoryRegionInfo(begin_address, region_at_begin)
            self.assertEqual(region, region_at_begin)

            # Test an address in the middle of a region returns it's enclosing
            # region.
            middle_address = (region.GetRegionBase() +
                              region.GetRegionEnd()) // 2
            region_at_middle = lldb.SBMemoryRegionInfo()
            error = process.GetMemoryRegionInfo(middle_address,
                                                region_at_middle)
            self.assertEqual(region, region_at_middle)

            # Test the address at the end of a region returns it's enclosing
            # region.
            end_address = region.GetRegionEnd() - 1
            region_at_end = lldb.SBMemoryRegionInfo()
            error = process.GetMemoryRegionInfo(end_address, region_at_end)
            self.assertEqual(region, region_at_end)

            # Check that quering the end address does not return this region but
            # the next one.
            next_region = lldb.SBMemoryRegionInfo()
            error = process.GetMemoryRegionInfo(region.GetRegionEnd(),
                                                next_region)
            self.assertNotEqual(region, next_region)
            self.assertEqual(region.GetRegionEnd(),
                             next_region.GetRegionBase())

        # Check that query beyond the last region returns an unmapped region
        # that ends at LLDB_INVALID_ADDRESS
        last_region = lldb.SBMemoryRegionInfo()
        region_list.GetMemoryRegionAtIndex(region_count - 1, last_region)
        end_region = lldb.SBMemoryRegionInfo()
        error = process.GetMemoryRegionInfo(last_region.GetRegionEnd(),
                                            end_region)
        self.assertFalse(end_region.IsMapped())
        self.assertEqual(last_region.GetRegionEnd(),
                         end_region.GetRegionBase())
        self.assertEqual(end_region.GetRegionEnd(), lldb.LLDB_INVALID_ADDRESS)
Exemplo n.º 11
0
Arquivo: info.py Projeto: zcutlip/LLDB
def handle_command(debugger, command, exe_ctx, result, internal_dict):
    '''
    Documentation for how to use info goes here 
    '''

    command_args = shlex.split(command, posix=False)
    parser = generate_option_parser()
    target = debugger.GetSelectedTarget()

    try:
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return


    if len(args) != 1:
        result.SetError("Expects an address")
        return        

    try:
        if args[0].startswith("0x") or args[0].startswith("0X"):
            address = int(args[0], 16)
        else:
            address = int(args[0], 10)

    except ValueError:
        frame = target.GetProcess().GetSelectedThread().GetSelectedFrame()
        val = frame.var(args[0])
        if val.IsValid() == False:
            result.SetError("can't parse \"{}\"".format(args[0]))
            return

        
        if options.address_of:
            derefVal = val.AddressOf()
            if derefVal.IsValid() == False:
                result.SetError("can't deref \"{}\"".format(args[0]))
                return
            address = derefVal.unsigned
        else:
            address = val.unsigned
        # else:
        #     result.SetError("info expects a pointer, try \"info &{}\"".format(args[0]))
        #     return


    addr = target.ResolveLoadAddress(address)
    res = lldb.SBCommandReturnObject()
    interpreter = debugger.GetCommandInterpreter()


    returnDescription = ""
    foundAddress = False

    if addr.GetSection().IsValid():
        foundAddress, returnDescription = tryMachOAddress(addr, target, options)

    if foundAddress == False:
        foundAddress, returnDescription = tryHeapAddress(addr, target, options)

    if foundAddress == False:
        foundAddress, returnDescription = tryStackAddress(addr, target, options)        

    memString = ""
    if options.verbose:
        memRegion = lldb.SBMemoryRegionInfo()
        if target.GetProcess().GetMemoryRegionInfo(address, memRegion).success:
            memString = hex(memRegion.GetRegionBase()) + "-" + hex(memRegion.GetRegionEnd())
            memString += " {}{}{}".format("R" if memRegion.IsReadable() else "-", "W" if memRegion.IsWritable() else "-", "X" if memRegion.IsExecutable() else "-")

    if foundAddress:
        result.AppendMessage('{}{}, {} {}'.format("&" if options.address_of else "", args[0],returnDescription, memString))
    else:
        result.AppendMessage("Couldn't find address, reverting to \"image lookup -a {}\"".format(addr))
        debugger.HandleCommand("image lookup -v -a {}".format(addr))
Exemplo n.º 12
0
def dump_process_memory(output_dir):
    # Segment information dictionary
    raw_segment_list = []
    raw_memory_list = []
    
    # 1st pass:
    # Loop over the segments, fill in the segment info dictionary
    for module in lldb.target.module_iter():
        for seg_ea in module.section_iter():
            seg_info = {'module': module.file.GetFilename() }
            seg_info['start'], seg_info['end'], seg_size, seg_info['name'] = get_section_info(seg_ea)
            # TODO: Ugly hack for -1 LONG address on 32-bit
            if seg_info['start'] >= sys.maxint or seg_size <= 0:
                print "Throwing away page: {}".format(seg_info['name'])     
                continue

            # Page-align segment
            seg_info['start'] = ALIGN_PAGE_DOWN(seg_info['start'])
            seg_info['end'] = ALIGN_PAGE_UP(seg_info['end'])
            print("Appending: {}".format(seg_info['name']))
            raw_segment_list.append(seg_info)

    # Add the stack memory region (just hardcode 0x1000 around the current SP)
    sp = lldb.frame.GetSP()
    start_sp = ALIGN_PAGE_DOWN(sp)
    raw_segment_list.append({'start': start_sp, 'end': start_sp + 0x1000, 'name': 'STACK'})

    # Write the original memory to file for debugging
    index_file = open(os.path.join(output_dir, DEBUG_MEM_FILE_NAME), 'w')
    index_file.write(json.dumps(raw_segment_list, indent=4))
    index_file.close()    

    # Loop over raw memory regions 
    mem_info = lldb.SBMemoryRegionInfo()
    start_addr = -1
    next_region_addr = 0
    while next_region_addr > start_addr:
        err = lldb.process.GetMemoryRegionInfo(next_region_addr, mem_info)
        # TODO: Should check err.success.  If False, what do we do?
        if not err.success:
            break
        next_region_addr = mem_info.GetRegionEnd()
        if next_region_addr >= sys.maxsize:
            break

        start_addr = mem_info.GetRegionBase()
        end_addr = mem_info.GetRegionEnd()

        # Unknown region name
        region_name = 'UNKNOWN'

        # Ignore regions that aren't even mapped
        if mem_info.IsMapped() and mem_info.IsReadable():
            mem_info_obj = {'start': start_addr, 'end': end_addr, 'name': region_name, 'permissions': {
                "r": mem_info.IsReadable(),
                "w": mem_info.IsWritable(),
                "x": mem_info.IsExecutable()
            }}

            raw_memory_list.append(mem_info_obj)

    final_segment_list = overlap_alignments(raw_segment_list, raw_memory_list)

    for seg_info in final_segment_list:
        try:
            seg_info['content_file'] = ''
            start_addr = seg_info['start']
            end_addr = seg_info['end']
            region_name = seg_info['name']
            # Compress and dump the content to a file
            err = lldb.SBError()
            seg_content = lldb.process.ReadMemory(start_addr, end_addr - start_addr, err)
            if(seg_content == None):
                print("Segment empty: @0x{0:016x} (size:UNKNOWN) {1}".format(start_addr, region_name))
                seg_info['content_file'] = ''
            else:
                print("Dumping segment @0x{0:016x} (size:0x{1:x}): {2} [{3}]".format(start_addr, len(seg_content), region_name, repr(seg_info['permissions'])))
                compressed_seg_content = zlib.compress(seg_content)
                md5_sum = hashlib.md5(compressed_seg_content).hexdigest() + ".bin"
                seg_info['content_file'] = md5_sum
                
                # Write the compressed contents to disk
                out_file = open(os.path.join(output_dir, md5_sum), 'wb')
                out_file.write(compressed_seg_content)
                out_file.close()
    
        except:
            print("Exception reading segment ({}): {}".format(region_name, sys.exc_info()[0]))
            
    return final_segment_list