예제 #1
0
def iboot_tasks(debugger, command, result, internal_dict):
    """Print the list of tasks maintained by the iBoot runtime"""
    process = debugger.GetSelectedTarget().GetProcess()
    if not process or not process.target:
        print 'Not connected'
        return

    plugin = OperatingSystemPlugIn(process)

    current_task = plugin.get_global('current_task')
    assert current_task is not None
    current_task_addr = current_task.GetValueAsUnsigned()

    tasks = plugin.get_task_dict().itervalues()
    print '  TID     Task  Name              Address'
    print '  ------  ----  ----------------  ------------------'
    for t in tasks:
        task_addr = t.AddressOf().GetValueAsUnsigned()
        current = "*" if task_addr == current_task_addr else " "

        tv = lldb.value(t)
        task_id = int(tv.task_id)
        tid = task_id + plugin.TID_OFFSET
        name = plugin.value_to_str(tv.name.sbvalue)

        print '{} {:#06x}  {:<4}  {:<16}  {:#018x}'.format(current, tid, task_id, name, task_addr)
예제 #2
0
 def summarize_iboot_task(self, task):
     task_value = lldb.value(task)
     return {
         'name': self.value_to_str(task_value.name.sbvalue).ljust(15),
         'tid': int(task_value.task_id) + self.TID_OFFSET,
         'state': 'stopped',
         'stop_reason': 'none'
     }
예제 #3
0
def processStackTraceStringFromAddresses(frameAddresses, target, options=None):
    frame_string = ''
    startAddresses = [
        target.ResolveLoadAddress(f).symbol.addr.GetLoadAddress(target)
        for f in frameAddresses
    ]
    script = generateExecutableMethodsScript(startAddresses)

    # New content start 1
    methods = target.EvaluateExpression(script, ds.genExpressionOptions())
    charPointerType = target.FindFirstType(
        "char").GetPointerType().GetArrayType(len(frameAddresses))
    methods = methods.Cast(charPointerType)
    methodsVal = lldb.value(methods)
    # New content end 1

    # Enumerate each of the SBFrames in address list
    pointerType = target.FindFirstType("char").GetPointerType()
    for index, frameAddr in enumerate(frameAddresses):
        addr = target.ResolveLoadAddress(frameAddr)
        symbol = addr.symbol

        # New content start 2
        if symbol.synthetic:  # 1
            children = methodsVal.sbvalue.GetNumChildren()  # 4
            name = ds.attrStr(symbol.name + r' ... unresolved womp womp',
                              'redd')  # 2

            loadAddr = symbol.addr.GetLoadAddress(target)  # 3
            k = str(methodsVal[index]).split('"')  # 5
            if len(k) >= 2:
                name = ds.attrStr(k[1], 'bold')  # 6
        else:
            name = ds.attrStr(str(symbol.name), 'yellow')  # 7
        # New content end 2

        offset_str = ''
        offset = addr.GetLoadAddress(target) - addr.symbol.addr.GetLoadAddress(
            target)
        if offset > 0:
            offset_str = '+ {}'.format(offset)

        i = ds.attrStr('frame #{:<2}:'.format(index), 'grey')
        if options and options.address:
            frame_string += '{} {}`{} {}\n'.format(
                ds.attrStr(hex(addr.GetLoadAddress(target)), 'grey'),
                ds.attrStr(str(addr.module.file.basename), 'cyan'),
                ds.attrStr(str(name), 'yellow'),
                ds.attrStr(offset_str, 'grey'))
        else:
            frame_string += '{} {} {}`{} {}\n'.format(
                i, ds.attrStr(str(hex(addr.GetLoadAddress(target))), 'grey'),
                ds.attrStr(str(addr.module.file.basename), 'cyan'), name,
                ds.attrStr(str(offset_str), 'grey'))

    return frame_string
예제 #4
0
파일: msl.py 프로젝트: eruesu/dbg-materials
def handle_command(debugger, command, result, internal_dict):
    '''
    msl will produce the stack trace of the most recent deallocations or allocations.
    Make sure to either call enable_logging or set MallocStackLogging environment variable
    '''
    
    command_args = shlex.split(command)
    parser = generateOptionParser()
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return

    cleanCommand = args[0]
    process = debugger.GetSelectedTarget().GetProcess()
    frame = process.GetSelectedThread().GetSelectedFrame()
    target = debugger.GetSelectedTarget()
    script = generateScript(cleanCommand, options)

    # 1
    sbval = frame.EvaluateExpression(script, generateOptions())

    # 2
    if sbval.error.fail: 
        result.AppendMessage(str(sbval.error))
        return

    val = lldb.value(sbval)
    addresses = []
    # 3
    for i in range(val.count.sbvalue.unsigned):
        address = val.addresses[i].sbvalue.unsigned
        sbaddr = target.ResolveLoadAddress(address)
        loadAddr = sbaddr.GetLoadAddress(target)
        addresses.append(loadAddr)

    # 4
    if options.resymbolicate:
        retString = sbt.processStackTraceStringFromAddresses(
                                                    addresses, 
                                                       target)
    else:
        retString = processStackTraceStringFromAddresses(
                                            addresses, 
                                               target)

    # 5
    freeExpr = 'free('+str(val.addresses.sbvalue.unsigned)+')'
    frame.EvaluateExpression(freeExpr, generateOptions())
    result.AppendMessage(retString)
예제 #5
0
def execute_in_lldb(ignore_breakpoints, fetch_dynamic, timeout_value, all_threads, expr):
    frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame();
    if not frame:
        return 'error: invalid frame';
    expr_options = lldb.SBExpressionOptions();
    expr_options.SetIgnoreBreakpoints(ignore_breakpoints);
    expr_options.SetFetchDynamicValue(fetch_dynamic);
    expr_options.SetTimeoutInMicroSeconds(timeout_value*1000*1000); # N second timeout
    expr_options.SetTryAllThreads(all_threads);
    expr_sbvalue = frame.EvaluateExpression(expr, expr_options);
    if expr_sbvalue.error.Success():
        return lldb.value(expr_sbvalue);
    else:
        return expr_sbvalue.error;
예제 #6
0
    def iboot_task_iter(self, head, skip_task=None):
        task_type = self.process.target.FindFirstType('task')
        task_members = { member.name : member for member in task_type.get_members_array() }
        list_offset = task_members['task_list_node'].byte_offset

        if not skip_task is None:
            skip_addr = skip_task.GetValueAsUnsigned()
        else:
            skip_addr = 0
        
        for node in head.AddressOf().linked_list_iter('next'):
            task_addr = node.GetValueAsUnsigned() - list_offset
            if task_addr == skip_addr:
                continue
            task = node.CreateValueFromAddress('task', task_addr, task_type)
            tid = int(lldb.value(task).task_id)
            yield tid, task
예제 #7
0
def execute_in_lldb(ignore_breakpoints, fetch_dynamic, timeout_value,
                    all_threads, expr):
    frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread(
    ).GetSelectedFrame()
    if not frame:
        return 'error: invalid frame'
    expr_options = lldb.SBExpressionOptions()
    expr_options.SetIgnoreBreakpoints(ignore_breakpoints)
    expr_options.SetFetchDynamicValue(fetch_dynamic)
    expr_options.SetTimeoutInMicroSeconds(timeout_value * 1000 * 1000)
    # N second timeout
    expr_options.SetTryAllThreads(all_threads)
    expr_sbvalue = frame.EvaluateExpression(expr, expr_options)
    if expr_sbvalue.error.Success():
        return lldb.value(expr_sbvalue)
    else:
        return expr_sbvalue.error
예제 #8
0
파일: heap.py 프로젝트: Bike/clasp
def dump_stack_history_entries(addr, history):
    # malloc_stack_entry *get_stack_history_for_address (const void * addr)
    expr = 'get_stack_history_for_address((void *)0x%x, %u)' % (addr, history)
    expr_sbvalue = lldb.frame.EvaluateExpression (expr)
    if expr_sbvalue.error.Success():
        if expr_sbvalue.unsigned:
            expr_value = lldb.value(expr_sbvalue)  
            idx = 0;
            stack_history_entry = expr_value[idx]
            while int(stack_history_entry.address) != 0:
                dump_stack_history_entry(stack_history_entry, idx)
                idx = idx + 1
                stack_history_entry = expr_value[idx]
        else:
            print 'error: expression returned => %s' % (expr_sbvalue)
    else:
        print 'error: expression failed "%s" => %s' % (expr, expr_sbvalue.error)
예제 #9
0
파일: msl.py 프로젝트: lanza/LLDBds
def handle_command(debugger, command, exe_ctx, result, internal_dict):
    '''
    msl 0xadd7E55

    msl or malloc stack logging will take an address and try and obtain the stack trace to 
    when it was created. 

    You will need to set the env var to MallocStackLogging, or execute turn_on_stack_logging(1)
    while the process is active
    '''

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

    cleanCommand = args[0]
    frame = exe_ctx.frame
    target = exe_ctx.target
    script = generateScript(cleanCommand, options)
    sbval = frame.EvaluateExpression(script, generateOptions())

    if sbval.error.fail:
        result.AppendMessage(str(sbval.error))
        return

    val = lldb.value(sbval)
    addresses = []
    for i in range(val.count.sbvalue.unsigned):
        address = val.addresses[i].sbvalue.unsigned
        loadAddr = target.ResolveLoadAddress(address).GetLoadAddress(target)
        addresses.append(loadAddr)
        # stackString = str(target.ResolveLoadAddress(address).symbol)
        # result.AppendMessage(stackString)

    if options.resymbolicate:
        retString = sbt.processStackTraceStringFromAddresses(addresses, target)
    else:
        retString = processStackTraceStringFromAddresses(addresses, target)

    frame.EvaluateExpression(
        'free(' + str(val.addresses.sbvalue.unsigned) + ')', generateOptions())
    result.AppendMessage(retString)
예제 #10
0
def dump_stack_history_entries(result, addr, history):
    # malloc_stack_entry *get_stack_history_for_address (const void * addr)
    expr = 'get_stack_history_for_address((void *)0x%x, %u)' % (addr, history)
    expr_sbvalue = lldb.frame.EvaluateExpression(expr)
    if expr_sbvalue.error.Success():
        if expr_sbvalue.unsigned:
            expr_value = lldb.value(expr_sbvalue)
            idx = 0
            stack_history_entry = expr_value[idx]
            while int(stack_history_entry.address) != 0:
                dump_stack_history_entry(result, stack_history_entry, idx)
                idx = idx + 1
                stack_history_entry = expr_value[idx]
        else:
            result.AppendMessage('"%s" returned zero' % (expr))
    else:
        result.AppendMessage('error: expression failed "%s" => %s' %
                             (expr, expr_sbvalue.error))
예제 #11
0
def processStackTraceStringFromAddresses(frameAddresses, target):
    frame_string = ''
    startAddresses = [
        target.ResolveLoadAddress(f).symbol.addr.GetLoadAddress(target)
        for f in frameAddresses
    ]
    script = generateExecutableMethodsScript(startAddresses)

    # New content start 1
    methods = target.EvaluateExpression(script, generateOptions())
    methodsVal = lldb.value(methods.deref)
    # New content end 1

    # Enumerate each of the SBFrames in address list
    for index, frameAddr in enumerate(frameAddresses):
        addr = target.ResolveLoadAddress(frameAddr)
        symbol = addr.symbol

        # New content start 2
        if symbol.synthetic:  # 1
            children = methodsVal.sbvalue.GetNumChildren()  # 2
            name = symbol.name + r' ... unresolved womp womp'  # 3

            loadAddr = symbol.addr.GetLoadAddress(target)  # 4
            for i in range(children):
                key = long(methodsVal[i].key.sbvalue.description)  # 5
                if key == loadAddr:
                    name = methodsVal[i].value.sbvalue.description  # 6
                    break
        else:
            name = symbol.name  # 7
        # New content end 2

        offset_str = ''
        offset = addr.GetLoadAddress(target) - addr.symbol.addr.GetLoadAddress(
            target)
        if offset > 0:
            offset_str = '+ {}'.format(offset)

        frame_string += 'frame #{:<2}: {} {}`{} {}\n'.format(
            index, hex(addr.GetLoadAddress(target)), addr.module.file.basename,
            name, offset_str)

    return frame_string
예제 #12
0
def handle_command(debugger, command, result, internal_dict):
    '''
    Documentation for how to use msl goes here 
    '''

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

    cleanCommand = args[0]
    frame = debugger.GetSelectedTarget().GetProcess().GetSelectedThread(
    ).GetSelectedFrame()
    target = debugger.GetSelectedTarget()
    script = generateScript(cleanCommand, options)
    sbval = frame.EvaluateExpression(script, generateOptions())

    if sbval.error.fail:
        result.AppendMessage(str(sbval.error))
        return

    val = lldb.value(sbval)
    addresses = []
    for i in range(val.count.sbvalue.unsigned):
        address = val.addresses[i].sbvalue.unsigned
        loadAddr = target.ResolveLoadAddress(address).GetLoadAddress(target)
        addresses.append(loadAddr)
        # stackString = str(target.ResolveLoadAddress(address).symbol)
        # result.AppendMessage(stackString)

    if options.resymbolicate:
        retString = sbt.processStackTraceStringFromAddresses(addresses, target)
    else:
        retString = processStackTraceStringFromAddresses(addresses, target)

    frame.EvaluateExpression(
        'free(' + str(val.addresses.sbvalue.unsigned) + ')', generateOptions())
    result.AppendMessage(retString)
예제 #13
0
    def get_task_dict(self, skip_current=False):
        if self.task_dict is None:
            task_list = self.get_global('task_list')
            assert task_list is not None

            if skip_current:
                skip_task = self.get_global('current_task')
            else:
                skip_task = None

            task_tuples = list(self.iboot_task_iter(task_list, skip_task))
            # The first entry in the list isn't a task, so remove it from the list
            task_tuples = task_tuples[1:]

            # If there aren't any tasks in the list, we must still be
            # in the bootstrap task, which we can get through current_task
            if len(task_tuples) == 0 and not skip_current:
                current_task = self.get_global('current_task').Dereference()
                current_tid = int(lldb.value(current_task).task_id)
                task_tuples = [(current_tid, current_task)]

            self.task_dict = {tid : thread for tid,thread in task_tuples}
        return self.task_dict
예제 #14
0
    def get_register_data(self, tid):
        assert tid >= self.TID_OFFSET
        tasks = self.get_task_dict()
        task = tasks[tid - self.TID_OFFSET]

        task_arch_value = lldb.value(task).arch

        if self.arch == 'arm64':
            regs = task_arch_value.regs.sbvalue
            fp = task_arch_value.fp.sbvalue
            lr = task_arch_value.lr.sbvalue
            sp = task_arch_value.sp.sbvalue
            # We don't know the PC, so use the LR instead to keep LLDB happy
            pc = task_arch_value.lr.sbvalue
            registers = [regs, fp, lr, sp, pc]
        else:
            regs = task_arch_value.regs.sbvalue
            # We don't know the PC, so use the LR instead to keep LLDB happy
            pc = task_arch_value.regs[9].sbvalue
            registers = [regs, pc]

        result = "".join(map(self.value_to_bytes, registers))
        return result
예제 #15
0
    def test(self):
        """Exercise some SBValue APIs."""
        d = {'EXE': self.exe_name}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        exe = self.getBuildArtifact(self.exe_name)

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Create the breakpoint inside function 'main'.
        breakpoint = target.BreakpointCreateByLocation('main.c', self.line)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

        # Now launch the process, and do not stop at entry point.
        process = target.LaunchSimple(None, None,
                                      self.get_process_working_directory())
        self.assertTrue(process, PROCESS_IS_VALID)

        # Get Frame #0.
        self.assertTrue(process.GetState() == lldb.eStateStopped)
        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonBreakpoint)
        self.assertTrue(
            thread.IsValid(),
            "There should be a thread stopped due to breakpoint condition")
        frame0 = thread.GetFrameAtIndex(0)

        # Get global variable 'days_of_week'.
        list = target.FindGlobalVariables('days_of_week', 1)
        days_of_week = list.GetValueAtIndex(0)
        self.assertTrue(days_of_week, VALID_VARIABLE)
        self.assertEqual(days_of_week.GetNumChildren(), 7, VALID_VARIABLE)
        self.DebugSBValue(days_of_week)

        # Use this to test the "child" and "children" accessors:
        children = days_of_week.children
        self.assertEqual(len(children), 7, VALID_VARIABLE)
        for i in range(0, len(children)):
            day = days_of_week.child[i]
            list_day = children[i]
            self.assertNotEqual(day, None)
            self.assertNotEqual(list_day, None)
            self.assertEqual(day.GetSummary(), list_day.GetSummary(),
                             VALID_VARIABLE)

        # Spot check the actual value:
        first_day = days_of_week.child[1]
        self.assertEqual(first_day.GetSummary(), '"Monday"', VALID_VARIABLE)

        # Get global variable 'weekdays'.
        list = target.FindGlobalVariables('weekdays', 1)
        weekdays = list.GetValueAtIndex(0)
        self.assertTrue(weekdays, VALID_VARIABLE)
        self.assertTrue(weekdays.GetNumChildren() == 5, VALID_VARIABLE)
        self.DebugSBValue(weekdays)

        # Get global variable 'g_table'.
        list = target.FindGlobalVariables('g_table', 1)
        g_table = list.GetValueAtIndex(0)
        self.assertTrue(g_table, VALID_VARIABLE)
        self.assertTrue(g_table.GetNumChildren() == 2, VALID_VARIABLE)
        self.DebugSBValue(g_table)

        fmt = lldbutil.BasicFormatter()
        cvf = lldbutil.ChildVisitingFormatter(indent_child=2)
        rdf = lldbutil.RecursiveDecentFormatter(indent_child=2)
        if self.TraceOn():
            print(fmt.format(days_of_week))
            print(cvf.format(days_of_week))
            print(cvf.format(weekdays))
            print(rdf.format(g_table))

        # Get variable 'my_int_ptr'.
        value = frame0.FindVariable('my_int_ptr')
        self.assertTrue(value, VALID_VARIABLE)
        self.DebugSBValue(value)

        # Get what 'my_int_ptr' points to.
        pointed = value.GetChildAtIndex(0)
        self.assertTrue(pointed, VALID_VARIABLE)
        self.DebugSBValue(pointed)

        # While we are at it, verify that 'my_int_ptr' points to 'g_my_int'.
        symbol = target.ResolveLoadAddress(int(pointed.GetLocation(),
                                               0)).GetSymbol()
        self.assertTrue(symbol)
        self.expect(symbol.GetName(), exe=False, startstr='g_my_int')

        # Get variable 'str_ptr'.
        value = frame0.FindVariable('str_ptr')
        self.assertTrue(value, VALID_VARIABLE)
        self.DebugSBValue(value)

        # SBValue::TypeIsPointerType() should return true.
        self.assertTrue(value.TypeIsPointerType())

        # Verify the SBValue::GetByteSize() API is working correctly.
        arch = self.getArchitecture()
        if arch == 'i386':
            self.assertTrue(value.GetByteSize() == 4)
        elif arch == 'x86_64':
            self.assertTrue(value.GetByteSize() == 8)

        # Get child at index 5 => 'Friday'.
        child = value.GetChildAtIndex(5, lldb.eNoDynamicValues, True)
        self.assertTrue(child, VALID_VARIABLE)
        self.DebugSBValue(child)

        self.expect(child.GetSummary(), exe=False, substrs=['Friday'])

        # Now try to get at the same variable using GetValueForExpressionPath().
        # These two SBValue objects should have the same value.
        val2 = value.GetValueForExpressionPath('[5]')
        self.assertTrue(val2, VALID_VARIABLE)
        self.DebugSBValue(val2)
        self.assertTrue(child.GetValue() == val2.GetValue()
                        and child.GetSummary() == val2.GetSummary())

        val_i = target.EvaluateExpression('i')
        val_s = target.EvaluateExpression('s')
        val_a = target.EvaluateExpression('a')
        self.assertTrue(
            val_s.GetChildMemberWithName('a').AddressOf(), VALID_VARIABLE)
        self.assertTrue(
            val_a.Cast(val_i.GetType()).AddressOf(), VALID_VARIABLE)

        self.assertTrue(
            int(lldb.value(frame0.FindVariable('uinthex'))) == 3768803088,
            'uinthex == 3768803088')
        self.assertTrue(
            int(lldb.value(frame0.FindVariable('sinthex'))) == -526164208,
            'sinthex == -526164208')

        self.assertTrue(
            frame0.FindVariable('uinthex').GetValueAsUnsigned() == 3768803088,
            'unsigned uinthex == 3768803088')
        self.assertTrue(
            frame0.FindVariable('sinthex').GetValueAsUnsigned() == 3768803088,
            'unsigned sinthex == 3768803088')

        self.assertTrue(
            frame0.FindVariable('uinthex').GetValueAsSigned() == -526164208,
            'signed uinthex == -526164208')
        self.assertTrue(
            frame0.FindVariable('sinthex').GetValueAsSigned() == -526164208,
            'signed sinthex == -526164208')
예제 #16
0
파일: heap.py 프로젝트: Bike/clasp
def heap_search(options, arg_str):
    dylid_load_err = load_dylib()
    if dylid_load_err:
        print dylid_load_err
        return
    expr = None
    arg_str_description = arg_str
    default_memory_format = "Y" # 'Y' is "bytes with ASCII" format
    #memory_chunk_size = 1
    if options.type == 'pointer':
        expr = 'find_pointer_in_heap((void *)%s)' % (arg_str)
        arg_str_description = 'malloc block containing pointer %s' % arg_str
        default_memory_format = "A" # 'A' is "address" format
        #memory_chunk_size = lldb.process.GetAddressByteSize()
    elif options.type == 'cstr':
        expr = 'find_cstring_in_heap("%s")' % arg_str
        arg_str_description = 'malloc block containing "%s"' % arg_str
    elif options.type == 'addr':
        expr = 'find_block_for_address((void *)%s)' % arg_str
        arg_str_description = 'malloc block for %s' % arg_str
    else:
        print 'error: invalid type "%s"\nvalid values are "pointer", "cstr"' % options.type
        return
    
    expr_sbvalue = lldb.frame.EvaluateExpression (expr)
    if expr_sbvalue.error.Success():
        if expr_sbvalue.unsigned:
            match_value = lldb.value(expr_sbvalue)  
            i = 0
            while 1:
                match_entry = match_value[i]; i += 1
                malloc_addr = match_entry.addr.sbvalue.unsigned
                if malloc_addr == 0:
                    break
                malloc_size = int(match_entry.size)
                offset = int(match_entry.offset)
                dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(lldb.eDynamicCanRunTarget)
                # If the type is still 'void *' then we weren't able to figure
                # out a dynamic type for the malloc_addr
                type_name = dynamic_value.type.name
                description = '[%u] %s: addr = 0x%x' % (i, arg_str_description, malloc_addr)
                if offset != 0:
                    description += ' + %u' % (offset)
                description += ', size = %u' % (malloc_size)
                if type_name == 'void *':
                    if options.type == 'pointer' and malloc_size == 4096:
                        error = lldb.SBError()
                        data = bytearray(lldb.process.ReadMemory(malloc_addr, 16, error))
                        if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
                            description += ', type = (AUTORELEASE!)'
                    print description
                else:
                    description += ', type = %s' % (type_name)
                    derefed_dynamic_value = dynamic_value.deref
                    ivar_member = None
                    if derefed_dynamic_value:
                        derefed_dynamic_type = derefed_dynamic_value.type
                        member = derefed_dynamic_type.GetFieldAtIndex(0)
                        search_bases = False
                        if member:
                            if member.GetOffsetInBytes() <= offset:
                                for field_idx in range (derefed_dynamic_type.GetNumberOfFields()):
                                    member = derefed_dynamic_type.GetFieldAtIndex(field_idx)
                                    member_byte_offset = member.GetOffsetInBytes()
                                    if member_byte_offset == offset:
                                        ivar_member = member
                                        break
                            else:
                                search_bases = True
                        else:
                            search_bases = True

                        if not ivar_member and search_bases:
                            for field_idx in range (derefed_dynamic_type.GetNumberOfDirectBaseClasses()):
                                member = derefed_dynamic_type.GetDirectBaseClassAtIndex(field_idx)
                                member_byte_offset = member.GetOffsetInBytes()
                                if member_byte_offset == offset:
                                    ivar_member = member
                                    break
                            if not ivar_member:
                                for field_idx in range (derefed_dynamic_type.GetNumberOfVirtualBaseClasses()):
                                    member = derefed_dynamic_type.GetVirtualBaseClassAtIndex(field_idx)
                                    member_byte_offset = member.GetOffsetInBytes()
                                    if member_byte_offset == offset:
                                        ivar_member = member
                                        break
                    if ivar_member:
                        description +=', ivar = %s' % (ivar_member.name)

                    print description
                    if derefed_dynamic_value:
                        print derefed_dynamic_value
                    if options.print_object_description:
                        desc = dynamic_value.GetObjectDescription()
                        if desc:
                            print '  (%s) 0x%x %s\n' % (type_name, malloc_addr, desc)
                if options.memory:
                    memory_format = options.format
                    if not memory_format:
                        memory_format = default_memory_format
                    cmd_result = lldb.SBCommandReturnObject()
                    #count = malloc_size / memory_chunk_size
                    memory_command = "memory read -f %s 0x%x 0x%x" % (memory_format, malloc_addr, malloc_addr + malloc_size)
                    lldb.debugger.GetCommandInterpreter().HandleCommand(memory_command, cmd_result)
                    print cmd_result.GetOutput()
                if options.stack_history:
                    dump_stack_history_entries(malloc_addr, 1)
                elif options.stack:
                    dump_stack_history_entries(malloc_addr, 0)
        else:
            print '%s %s was not found in any malloc blocks' % (options.type, arg_str)
    else:
        print expr_sbvalue.error
    print     
예제 #17
0
def display_match_results (result, options, arg_str_description, expr_sbvalue, print_no_matches = True):
    if expr_sbvalue.error.Success():
        if expr_sbvalue.unsigned:
            match_value = lldb.value(expr_sbvalue)  
            i = 0
            match_idx = 0
            while 1:
                print_entry = True
                match_entry = match_value[i]; i += 1
                if i >= options.max_matches:
                    result.AppendMessage('error: the max number of matches (%u) was reached, use the --max-matches option to get more results' % (options.max_matches))
                    break
                malloc_addr = match_entry.addr.sbvalue.unsigned
                if malloc_addr == 0:
                    break
                malloc_size = int(match_entry.size)
                offset = int(match_entry.offset)
                
                if options.offset >= 0 and options.offset != offset:
                    print_entry = False
                else:                    
                    match_addr = malloc_addr + offset
                    dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(lldb.eDynamicCanRunTarget)
                    description = '[%u] %s: addr = 0x%x' % (match_idx, arg_str_description, malloc_addr)
                    if offset != 0:
                        description += ' + %u' % (offset)
                    description += ', size = %u' % (malloc_size)
                    derefed_dynamic_value = None
                    if dynamic_value.type.name == 'void *':
                        if options.type == 'pointer' and malloc_size == 4096:
                            error = lldb.SBError()
                            data = bytearray(lldb.process.ReadMemory(malloc_addr, 16, error))
                            if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
                                description += ', type = (AUTORELEASE!)'
                    else:
                        derefed_dynamic_value = dynamic_value.deref
                        if derefed_dynamic_value:                        
                            derefed_dynamic_type = derefed_dynamic_value.type
                            derefed_dynamic_type_size = derefed_dynamic_type.size
                            derefed_dynamic_type_name = derefed_dynamic_type.name
                            description += ', type = %s <%u>' % (derefed_dynamic_type_name, derefed_dynamic_type_size)
                            if offset < derefed_dynamic_type_size:
                                member_list = list();
                                get_member_types_for_offset (derefed_dynamic_type, offset, member_list)
                                if member_list:
                                    member_path = ''
                                    for member in member_list:
                                        member_name = member.name
                                        if member_name: 
                                            if member_path:
                                                member_path += '.'
                                            member_path += member_name
                                    if member_path:
                                        if options.ivar_regex_blacklist:
                                            for ivar_regex in options.ivar_regex_blacklist:
                                                if ivar_regex.match(member_path):
                                                    print_entry = False
                                        description += ', ivar = %s' % (member_path)
                if print_entry:
                    match_idx += 1
                    if description:
                        result.AppendMessage(description)
                        if options.print_type and derefed_dynamic_value:
                            result.AppendMessage('%s' % (derefed_dynamic_value))
                        if options.print_object_description and dynamic_value:
                            desc = dynamic_value.GetObjectDescription()
                            if desc:
                                result.AppendMessage(', po=%s' % (desc))
                    if options.memory:
                        cmd_result = lldb.SBCommandReturnObject()
                        memory_command = "memory read -f %s 0x%x 0x%x" % (options.format, malloc_addr, malloc_addr + malloc_size)
                        lldb.debugger.GetCommandInterpreter().HandleCommand(memory_command, cmd_result)
                        result.AppendMessage(cmd_result.GetOutput())
                    if options.stack_history:
                        dump_stack_history_entries(result, malloc_addr, 1)
                    elif options.stack:
                        dump_stack_history_entries(result, malloc_addr, 0)
            return i
        elif print_no_matches:
            result.AppendMessage('no matches found for %s' % (arg_str_description))
    else:
        result.AppendMessage(expr_sbvalue.error )
    return 0
예제 #18
0
파일: heap.py 프로젝트: filcab/lldb
def display_match_results (result, options, arg_str_description, expr_sbvalue, print_no_matches = True):
    if expr_sbvalue.error.Success():
        if expr_sbvalue.unsigned:
            match_value = lldb.value(expr_sbvalue)  
            i = 0
            match_idx = 0
            while 1:
                print_entry = True
                match_entry = match_value[i]; i += 1
                if i >= options.max_matches:
                    result.AppendMessage('error: the max number of matches (%u) was reached, use the --max-matches option to get more results' % (options.max_matches))
                    break
                malloc_addr = match_entry.addr.sbvalue.unsigned
                if malloc_addr == 0:
                    break
                malloc_size = int(match_entry.size)
                offset = int(match_entry.offset)
                
                if options.offset >= 0 and options.offset != offset:
                    print_entry = False
                else:                    
                    match_addr = malloc_addr + offset
                    dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(lldb.eDynamicCanRunTarget)
                    description = '%#x: ' % (match_addr)
                    if options.show_size:
                        description += '<%5u> ' % (malloc_size)
                    if options.show_range:
                        if offset > 0:
                            description += '[%#x - %#x) + %-6u ' % (malloc_addr, malloc_addr + malloc_size, offset)
                        else:
                            description += '[%#x - %#x)' % (malloc_addr, malloc_addr + malloc_size)
                    else:
                        if options.type != 'isa':
                            description += '%#x + %-6u ' % (malloc_addr, offset)
                    derefed_dynamic_value = None
                    if dynamic_value.type.name == 'void *':
                        if options.type == 'pointer' and malloc_size == 4096:
                            error = lldb.SBError()
                            data = bytearray(lldb.process.ReadMemory(malloc_addr, 16, error))
                            if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
                                ptr_size = lldb.target.addr_size
                                thread = lldb.process.ReadUnsignedFromMemory (malloc_addr + 16 + ptr_size, ptr_size, error)
                                #   4 bytes  0xa1a1a1a1
                                #  12 bytes  'AUTORELEASE!'
                                # ptr bytes  autorelease insertion point
                                # ptr bytes  pthread_t
                                # ptr bytes  next colder page
                                # ptr bytes  next hotter page
                                #   4 bytes  this page's depth in the list
                                #   4 bytes  high-water mark
                                description += 'AUTORELEASE! for pthread_t %#x' % (thread)
                            else:
                                description += 'malloc(%u)' % (malloc_size)
                        else:
                            description += 'malloc(%u)' % (malloc_size)
                    else:
                        derefed_dynamic_value = dynamic_value.deref
                        if derefed_dynamic_value:                        
                            derefed_dynamic_type = derefed_dynamic_value.type
                            derefed_dynamic_type_size = derefed_dynamic_type.size
                            derefed_dynamic_type_name = derefed_dynamic_type.name
                            description += derefed_dynamic_type_name
                            if offset < derefed_dynamic_type_size:
                                member_list = list();
                                get_member_types_for_offset (derefed_dynamic_type, offset, member_list)
                                if member_list:
                                    member_path = ''
                                    for member in member_list:
                                        member_name = member.name
                                        if member_name: 
                                            if member_path:
                                                member_path += '.'
                                            member_path += member_name
                                    if member_path:
                                        if options.ivar_regex_blacklist:
                                            for ivar_regex in options.ivar_regex_blacklist:
                                                if ivar_regex.match(member_path):
                                                    print_entry = False
                                        description += '.%s' % (member_path)
                            else:
                                description += '%u bytes after %s' % (offset - derefed_dynamic_type_size, derefed_dynamic_type_name)
                        else:
                            # strip the "*" from the end of the name since we were unable to dereference this
                            description += dynamic_value.type.name[0:-1]
                if print_entry:
                    match_idx += 1
                    result_output = ''
                    if description:
                        result_output += description
                        if options.print_type and derefed_dynamic_value:
                            result_output += '%s' % (derefed_dynamic_value)
                        if options.print_object_description and dynamic_value:
                            desc = dynamic_value.GetObjectDescription()
                            if desc:
                                result_output += '\n%s' % (desc)
                    if result_output:
                        result.AppendMessage(result_output)
                    if options.memory:
                        cmd_result = lldb.SBCommandReturnObject()
                        memory_command = "memory read -f %s 0x%x 0x%x" % (options.format, malloc_addr, malloc_addr + malloc_size)
                        lldb.debugger.GetCommandInterpreter().HandleCommand(memory_command, cmd_result)
                        result.AppendMessage(cmd_result.GetOutput())
                    if options.stack_history:
                        dump_stack_history_entries(result, malloc_addr, 1)
                    elif options.stack:
                        dump_stack_history_entries(result, malloc_addr, 0)
            return i
        elif print_no_matches:
            result.AppendMessage('no matches found for %s' % (arg_str_description))
    else:
        result.AppendMessage(str(expr_sbvalue.error))
    return 0
예제 #19
0
파일: heap.py 프로젝트: ztianjin/lldb
def heap_search(options, arg_str):
    dylid_load_err = load_dylib()
    if dylid_load_err:
        print dylid_load_err
        return
    expr = None
    arg_str_description = arg_str
    default_memory_format = "Y" # 'Y' is "bytes with ASCII" format
    #memory_chunk_size = 1
    if options.type == 'pointer':
        expr = 'find_pointer_in_heap((void *)%s)' % (arg_str)
        arg_str_description = 'malloc block containing pointer %s' % arg_str
        default_memory_format = "A" # 'A' is "address" format
        #memory_chunk_size = lldb.process.GetAddressByteSize()
    elif options.type == 'cstr':
        expr = 'find_cstring_in_heap("%s")' % arg_str
        arg_str_description = 'malloc block containing "%s"' % arg_str
    elif options.type == 'addr':
        expr = 'find_block_for_address((void *)%s)' % arg_str
        arg_str_description = 'malloc block for %s' % arg_str
    else:
        print 'error: invalid type "%s"\nvalid values are "pointer", "cstr"' % options.type
        return
    
    expr_sbvalue = lldb.frame.EvaluateExpression (expr)
    if expr_sbvalue.error.Success():
        if expr_sbvalue.unsigned:
            match_value = lldb.value(expr_sbvalue)  
            i = 0
            while 1:
                match_entry = match_value[i]; i += 1
                malloc_addr = match_entry.addr.sbvalue.unsigned
                if malloc_addr == 0:
                    break
                malloc_size = int(match_entry.size)
                offset = int(match_entry.offset)
                match_addr = malloc_addr + offset
                dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(lldb.eDynamicCanRunTarget)
                description = '[%u] %s: addr = 0x%x' % (i, arg_str_description, malloc_addr)
                if offset != 0:
                    description += ' + %u' % (offset)
                description += ', size = %u' % (malloc_size)
                if dynamic_value.type.name == 'void *':
                    if options.type == 'pointer' and malloc_size == 4096:
                        error = lldb.SBError()
                        data = bytearray(lldb.process.ReadMemory(malloc_addr, 16, error))
                        if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
                            description += ', type = (AUTORELEASE!)'
                    print description
                else:
                    derefed_dynamic_value = dynamic_value.deref
                    if derefed_dynamic_value:                        
                        derefed_dynamic_type = derefed_dynamic_value.type
                        derefed_dynamic_type_size = derefed_dynamic_type.size
                        derefed_dynamic_type_name = derefed_dynamic_type.name
                        description += ', type = %s <%u>' % (derefed_dynamic_type_name, derefed_dynamic_type_size)
                        if offset < derefed_dynamic_type_size:
                            member_list = list();
                            get_member_types_for_offset (derefed_dynamic_type, offset, member_list)
                            if member_list:
                                member_path = ''
                                for member in member_list:
                                    member_name = member.name
                                    if member_name: 
                                        if member_path:
                                            member_path += '.'
                                        member_path += member_name
                                if member_path:
                                    description += ', ivar = %s' % (member_path)
                            print description
                            if derefed_dynamic_value:
                                print derefed_dynamic_value
                            if options.print_object_description:
                                desc = dynamic_value.GetObjectDescription()
                                if desc:
                                    print '  (%s) 0x%x %s\n' % (type_name, malloc_addr, desc)
                if options.memory:
                    memory_format = options.format
                    if not memory_format:
                        memory_format = default_memory_format
                    cmd_result = lldb.SBCommandReturnObject()
                    #count = malloc_size / memory_chunk_size
                    memory_command = "memory read -f %s 0x%x 0x%x" % (memory_format, malloc_addr, malloc_addr + malloc_size)
                    lldb.debugger.GetCommandInterpreter().HandleCommand(memory_command, cmd_result)
                    print cmd_result.GetOutput()
                if options.stack_history:
                    dump_stack_history_entries(malloc_addr, 1)
                elif options.stack:
                    dump_stack_history_entries(malloc_addr, 0)
        else:
            print '%s %s was not found in any malloc blocks' % (options.type, arg_str)
    else:
        print expr_sbvalue.error
    print     
예제 #20
0
def search(debugger, command, exe_ctx, result, internal_dict):
    '''
    Finds all subclasses of a class. This class must by dynamic 
    (aka inherit from a NSObject class). Currently doesn't work 
    with NSString or NSNumber (tagged pointer objects). 

    NOTE: This script will leak memory

Examples:

    # Find all UIViews and subclasses of UIViews
    find UIView

    # Find all UIStatusBar instances
    find UIStatusBar

    # Find all UIViews, ignore subclasses
    find UIView  -e

    # Find all instances of UIViews (and subclasses) where tag == 5
    find UIView -c "[obj tag] == 5"
    '''

    if not ds.isProcStopped():
        result.SetError(
            ds.attrStr(
                'You must have the process suspended in order to execute this command',
                'red'))
        return

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

    if not args:
        result.SetError(
            'Usage: find NSObjectSubclass\n\nUse \'help find\' for more details'
        )
        return

    clean_command = ('').join(args)

    res = lldb.SBCommandReturnObject()
    interpreter = debugger.GetCommandInterpreter()

    if options.module:
        target = exe_ctx.target
        module = target.FindModule(lldb.SBFileSpec(options.module))
        if not module.IsValid():
            result.SetError(
                "Unable to open module name '{}', to see list of images use 'image list -b'"
                .format(options.module))
            return
        options.module = generate_module_search_sections_string(module, target)

    if options.pointer_reference:
        objectiveC_class = '(uintptr_t *){}'.format(clean_command)
        if options.pointer_reference and (options.exact_match or options.module
                                          or options.module
                                          or options.condition
                                          or options.perform_action):
            result.SetError(
                "Can only use the --pointer_reference with --barebones")
    else:

        interpreter.HandleCommand(
            'expression -lobjc -O -- (Class)NSClassFromString(@\"{}\")'.format(
                clean_command), res)
        if 'nil' in res.GetOutput():
            result.SetError(
                'Can\'t find class named "{}". Womp womp...'.format(
                    clean_command))
            return
        objectiveC_class = 'NSClassFromString(@"{}")'.format(clean_command)

    command_script = get_command_script(objectiveC_class, options)
    # print command_script
    # return

    expr_options = lldb.SBExpressionOptions()
    expr_options.SetIgnoreBreakpoints(True)
    expr_options.SetFetchDynamicValue(lldb.eNoDynamicValues)
    expr_options.SetTimeoutInMicroSeconds(30 * 1000 *
                                          1000)  # 30 second timeout
    expr_options.SetTryAllThreads(False)
    expr_options.SetTrapExceptions(False)
    expr_options.SetUnwindOnError(True)
    expr_options.SetGenerateDebugInfo(True)
    expr_options.SetLanguage(lldb.eLanguageTypeObjC_plus_plus)
    expr_options.SetCoerceResultToId(True)
    # expr_options.SetAutoApplyFixIts(True)
    frame = exe_ctx.frame

    if frame is None:
        result.SetError(
            'You must have the process suspended in order to execute this command'
        )
        return
    # debugger.HandleCommand('po ' + command_script)

    # debugger.HandleCommand('expression -lobjc++ -g -O -- ' + command_script)
    # return
    # print(command_script)
    expr_sbvalue = frame.EvaluateExpression(command_script, expr_options)

    if not expr_sbvalue.error.success:
        result.SetError("\n**************************************\nerror: " +
                        str(expr_sbvalue.error))
        return

    val = lldb.value(expr_sbvalue)
    count = val.count.sbvalue.unsigned
    global s
    s = val

    if count > 100:
        result.AppendWarning(
            'Exceeded 100 hits, try narrowing your search with the --condition option'
        )
        count = 100

    if options.pointer_reference:
        for i in range(count):
            v = val.values[i].sbvalue
            offset = val.offsets[i].sbvalue.unsigned
            val_description = ds.attrStr(str(
                v.GetTypeName()), 'cyan') + ' [' + ds.attrStr(
                    str(v.GetValue()), 'yellow') + ']' + ' + ' + ds.attrStr(
                        str(offset), 'yellow')
            result.AppendMessage(val_description)
    else:
        if options.barebones:
            for i in range(count):
                v = val.values[i].sbvalue
                val_description = ds.attrStr(str(
                    v.GetTypeName()), 'cyan') + ' [' + ds.attrStr(
                        str(v.GetValue()), 'yellow') + ']'
                result.AppendMessage(val_description)
        else:
            for i in range(count):
                v = val.values[i].sbvalue
                if not v.description:
                    continue
                desc = v.description
                result.AppendMessage(desc + '\n')
예제 #21
0
def mama(target, options, args, result):
    ret = []
    needle = None
    if len(args):
        needle = exp(" ".join(args))
    arch = trgt()
    expr_options = lldb.SBExpressionOptions()
    expr_options.SetIgnoreBreakpoints(True)
    expr_options.SetFetchDynamicValue(lldb.eNoDynamicValues)
    expr_options.SetTimeoutInMicroSeconds(30 * 1000 *
                                          1000)  # 30 second timeout
    expr_options.SetTryAllThreads(False)
    max_results = 0x1000
    frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread(
    ).GetSelectedFrame()
    expr_sbvalue = frame.EvaluateExpression(
        mach_vm_region_expr() % (arch['extra'](), max_results), expr_options)
    if expr_sbvalue.error.Success():
        result_value = lldb.value(expr_sbvalue)
        starts = []
        malloc_tags = [1, 2, 3, 4, 6, 7, 8, 9, 11, 53, 61]
        for i in range(max_results):
            region_lol = result_value[i]
            start = int(region_lol.addr)
            size = int(region_lol.size)
            user_tag_int = int(region_lol.info.user_tag)
            if user_tag_int in malloc_tags and (not needle or in_region(
                    needle, start, size)):
                starts.append(start)
        _zones = {}
        if len(starts):
            _zones = zone(starts)

        reached_the_end = False
        for i in range(max_results):
            region_lol = result_value[i]
            size = int(region_lol.size)
            start = int(region_lol.addr)
            if start >= arch['shared_region_base']:
                reached_the_end = True
            end = start + size
            info = region_lol.info
            prot = int(info.protection)
            user_tag_int = int(info.user_tag)
            # from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/Kernel.framework/Headers/mach/vm_statistics.h
            # I only put in the ones I ran into
            user_tagz = {
                0: "unknown",
                1: "malloc",
                2: "malloc small",
                3: "malloc large",
                4: "malloc huge",
                # 5: "sbrk",
                6: "realloc",
                7: "malloc tiny",
                8: "malloc large reusable",
                9: "malloc large reused",
                10: "memory analysis tool",
                11: "malloc nano",
                20: "mach msg",
                21: "iokit",
                30: "stack",
                31: "guard",
                32: "shared pmap",
                33: "dylib",
                34: "objc dispatchers",
                35: "unshared pmap",
                40: "appkit",
                41: "foundation",
                42: "core graphics",
                43: "core services",
                44: "java",
                45: "coredata",
                46: "coredata objectids",
                50: "ats",
                51: "layerkit",
                52: "cgimage",
                53: "tcmalloc",
                54: "coregraphics data",
                55: "coregraphics shared",
                56: "coregraphics framebuffers",
                57: "coregraphics backingstores",
                60: "dyld",
                61: "dyld mallco",
                62: "sqlite",
                63: "javascript core heap",
                64: "javascript JIT executable allocator",
                65: "javascript JIT register file",
                66: "GLSL",
                67: "OpenCL",
                68: "core image",
                69: "webcore purgeable buffers",
                70: "imageio",
                71: "coreprofile",
                72: "assetsd / MobileSlideShow",
                73: "kernel alloc once",
                74: "libdispatch",
                75: "accelerate",
                76: "coreui",
                242: "application specific 242",
                251: "application specific 251"
            }
            user_tag = user_tagz.get(user_tag_int)
            if user_tag_int == 30:
                user_tag = "".join([user_tag, thread_for_stack(start, end)])
            if not user_tag:
                print "USER TAG NOT FOUDN: %s" % user_tag_int
            ref_count = int(info.ref_count)
            object_name = int(region_lol.object_name)
            if object_name != 0:
                print "YEHAHA %#x" % object_name
            share_mode = int(info.share_mode)
            share_modez = [
                '????', 'COW', 'PRV', 'NUL', 'ALI', 'SHM', 'ZER', 'S/A',
                'large page'
            ]
            share_mode = share_modez[share_mode]
            if start < arch['shared_region_base']:
                lookup_output = run_command(
                    "target modules lookup -v -a %#x" % start, True)
            elif needle:
                lookup_output = run_command(
                    "target modules lookup -v -a %#x" % needle, True)
            filename = ""
            section = ""
            if lookup_output:
                if user_tag_int != 0 and user_tag_int != 33 and user_tag_int != 35 and user_tag_int != 32:
                    print "oh shit! %d" % user_tag_int
                    break
                filename = re_find(r"file = \"([^\"]*)", lookup_output)
                filename = re.sub(r".*/SDKs", "...", filename)
                filename = re.sub(r".*/iOS DeviceSupport", "...", filename)
                section = re_find(r"__[\w]*", lookup_output)
                if section and filename and user_tag_int == 0:
                    user_tag = ""
            else:
                if user_tag_int == 33:
                    print "noh shit! %#x" % user_tag_int
                    break
            maybe_guard = "guard" if prot == 0 and user_tag_int == 30 else ""
            maybe_unallocated = "" if ref_count else "(zero refcount)"
            maybes = [maybe_guard, maybe_unallocated][not maybe_guard]
            if size == 0xe800000 and user_tag_int == 32 and ref_count == 0:
                reached_the_end = True
            else:
                if not needle or in_region(needle, start, size):
                    _zone = _zones[start] if user_tag_int in malloc_tags else ""
                    ret.append(
                        (start, size,
                         "{:#x} - {:#x} - {:<5s} - {:} SM={:} {:}".format(
                             start, end, human(size), prot_string(prot),
                             share_mode, " ".join(
                                 compact([
                                     section, user_tag, maybes, filename, _zone
                                 ])))))
            if share_mode == "NUL" and ref_count == 0 and prot == 5:
                break
        if not reached_the_end:
            print "didn't reach the end?"
        return ret
    else:
        print "failure, %s" % expr_sbvalue.error
예제 #22
0
    def __call__(self, debugger, command, exe_ctx, result):
        command_args = shlex.split(command, posix=False)
        parser = generate_option_parser()
        debugger.SetAsync(False)
        try:
            (options, args) = parser.parse_args(command_args)
        except:
            result.SetError(parser.usage)
            return

        if not args:
            result.SetError('TODO make this relevant')
            return

        clean_command = ('').join(args)

        target = debugger.GetSelectedTarget()
        expr_options = lldb.SBExpressionOptions()
        expr_options.SetIgnoreBreakpoints(False)
        expr_options.SetFetchDynamicValue(lldb.eDynamicCanRunTarget)
        expr_options.SetTimeoutInMicroSeconds(30 * 1000 *
                                              1000)  # 30 second timeout
        expr_options.SetTryAllThreads(True)
        expr_options.SetUnwindOnError(False)
        expr_options.SetGenerateDebugInfo(True)
        expr_options.SetLanguage(lldb.eLanguageTypeObjC_plus_plus)
        expr_options.SetCoerceResultToId(False)
        frame = debugger.GetSelectedTarget().GetProcess().GetSelectedThread(
        ).GetSelectedFrame()
        if frame is None:
            result.SetError(
                'You must have the process suspended in order to execute this command'
            )
            return
        # debugger.HandleCommand('po ' + command_script)

        command_script = get_command_script(clean_command, options)
        # debugger.HandleCommand('expression -lobjc++ -g -O -- ' + command_script)
        expr_value = frame.EvaluateExpression(command_script, expr_options)

        if not expr_value.error.success:
            result.SetError(str(expr_value.error))
            return

        lldb_stackaddress = lldb.value(expr_value)
        frame_count = lldb_stackaddress.count

        frame_addresses = []
        function_addresses = []
        for i in range(lldb_stackaddress.count):
            val = lldb_stackaddress.addresses[i]

            load_addr = int(val.sbvalue.GetValue())
            frame_addresses.append(load_addr)

            addr = target.ResolveLoadAddress(load_addr)
            print(addr)
            function_addresses.append(
                addr.GetSymbol().GetStartAddress().GetLoadAddress(target))
            # print(addr.GetSymbol().GetStartAddress().GetLoadAddress(target))
            # print(addr.GetLineEntry().GetLine())

        # # debugger.HandleCommand('expression -g -O -lobjc++ -- ' + command_script)
        # print (expr_value)
        print(function_addresses)

        expr_options.SetCoerceResultToId(True)
        class_load_address_script = self.generate_main_executable_class_address_script(
        )
        dict_value = frame.EvaluateExpression(class_load_address_script,
                                              expr_options)
예제 #23
0
파일: heapsearch.py 프로젝트: timor/clasp
def heap_search(options, arg_str):
    dylid_load_err = load_dylib()
    if dylid_load_err:
        print dylid_load_err
        return
    expr = None
    arg_str_description = arg_str
    default_memory_format = "Y"  # 'Y' is "bytes with ASCII" format
    #memory_chunk_size = 1
    if options.type == 'pointer':
        expr = 'find_pointer_in_heap((void *)%s)' % (arg_str)
        arg_str_description = 'malloc block containing pointer %s' % arg_str
        default_memory_format = "A"  # 'A' is "address" format
        #memory_chunk_size = lldb.process.GetAddressByteSize()
    elif options.type == 'cstr':
        expr = 'find_cstring_in_heap("%s")' % arg_str
        arg_str_description = 'malloc block containing "%s"' % arg_str
    elif options.type == 'addr':
        expr = 'find_block_for_address((void *)%s)' % arg_str
        arg_str_description = 'malloc block for %s' % arg_str
    else:
        print 'error: invalid type "%s"\nvalid values are "pointer", "cstr"' % options.type
        return

    expr_sbvalue = lldb.frame.EvaluateExpression(expr)
    if expr_sbvalue.error.Success():
        if expr_sbvalue.unsigned:
            match_value = lldb.value(expr_sbvalue)
            i = 0
            while 1:
                match_entry = match_value[i]
                i += 1
                malloc_addr = match_entry.addr.sbvalue.unsigned
                if malloc_addr == 0:
                    break
                malloc_size = int(match_entry.size)
                offset = int(match_entry.offset)
                dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(
                    lldb.eDynamicCanRunTarget)
                # If the type is still 'void *' then we weren't able to figure
                # out a dynamic type for the malloc_addr
                type_name = dynamic_value.type.name
                description = '[%u] %s: addr = 0x%x' % (i, arg_str_description,
                                                        malloc_addr)
                if offset != 0:
                    description += ' + %u' % (offset)
                description += ', size = %u' % (malloc_size)
                if type_name == 'void *':
                    if options.type == 'pointer' and malloc_size == 4096:
                        error = lldb.SBError()
                        data = bytearray(
                            lldb.process.ReadMemory(malloc_addr, 16, error))
                        if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
                            description += ', type = (AUTORELEASE!)'
                    print description
                else:
                    description += ', type = %s' % (type_name)
                    derefed_dynamic_value = dynamic_value.deref
                    ivar_member = None
                    if derefed_dynamic_value:
                        derefed_dynamic_type = derefed_dynamic_value.type
                        member = derefed_dynamic_type.GetFieldAtIndex(0)
                        search_bases = False
                        if member:
                            if member.GetOffsetInBytes() <= offset:
                                for field_idx in range(derefed_dynamic_type.
                                                       GetNumberOfFields()):
                                    member = derefed_dynamic_type.GetFieldAtIndex(
                                        field_idx)
                                    member_byte_offset = member.GetOffsetInBytes(
                                    )
                                    if member_byte_offset == offset:
                                        ivar_member = member
                                        break
                            else:
                                search_bases = True
                        else:
                            search_bases = True

                        if not ivar_member and search_bases:
                            for field_idx in range(
                                    derefed_dynamic_type.
                                    GetNumberOfDirectBaseClasses()):
                                member = derefed_dynamic_type.GetDirectBaseClassAtIndex(
                                    field_idx)
                                member_byte_offset = member.GetOffsetInBytes()
                                if member_byte_offset == offset:
                                    ivar_member = member
                                    break
                            if not ivar_member:
                                for field_idx in range(
                                        derefed_dynamic_type.
                                        GetNumberOfVirtualBaseClasses()):
                                    member = derefed_dynamic_type.GetVirtualBaseClassAtIndex(
                                        field_idx)
                                    member_byte_offset = member.GetOffsetInBytes(
                                    )
                                    if member_byte_offset == offset:
                                        ivar_member = member
                                        break
                    if ivar_member:
                        description += ', ivar = %s' % (ivar_member.name)

                    print description
                    if derefed_dynamic_value:
                        print derefed_dynamic_value
                    if options.print_object_description:
                        desc = dynamic_value.GetObjectDescription()
                        if desc:
                            print '  (%s) 0x%x %s\n' % (type_name, malloc_addr,
                                                        desc)
                if options.memory:
                    memory_format = options.format
                    if not memory_format:
                        memory_format = default_memory_format
                    cmd_result = lldb.SBCommandReturnObject()
                    #count = malloc_size / memory_chunk_size
                    memory_command = "memory read -f %s 0x%x 0x%x" % (
                        memory_format, malloc_addr, malloc_addr + malloc_size)
                    lldb.debugger.GetCommandInterpreter().HandleCommand(
                        memory_command, cmd_result)
                    print cmd_result.GetOutput()
                if options.stack_history:
                    dump_stack_history_entries(malloc_addr, 1)
                elif options.stack:
                    dump_stack_history_entries(malloc_addr, 0)
        else:
            print '%s %s was not found in any malloc blocks' % (options.type,
                                                                arg_str)
    else:
        print expr_sbvalue.error
    print
예제 #24
0
def display_match_results(result,
                          options,
                          arg_str_description,
                          expr_sbvalue,
                          print_no_matches=True):
    if expr_sbvalue.error.Success():
        if expr_sbvalue.unsigned:
            match_value = lldb.value(expr_sbvalue)
            i = 0
            match_idx = 0
            while 1:
                print_entry = True
                match_entry = match_value[i]
                i += 1
                if i >= options.max_matches:
                    result.AppendMessage(
                        'error: the max number of matches (%u) was reached, use the --max-matches option to get more results'
                        % (options.max_matches))
                    break
                malloc_addr = match_entry.addr.sbvalue.unsigned
                if malloc_addr == 0:
                    break
                malloc_size = int(match_entry.size)
                offset = int(match_entry.offset)

                if options.offset >= 0 and options.offset != offset:
                    print_entry = False
                else:
                    match_addr = malloc_addr + offset
                    dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(
                        lldb.eDynamicCanRunTarget)
                    description = '%#x: ' % (match_addr)
                    if options.show_size:
                        description += '<%5u> ' % (malloc_size)
                    if options.show_range:
                        if offset > 0:
                            description += '[%#x - %#x) + %-6u ' % (
                                malloc_addr, malloc_addr + malloc_size, offset)
                        else:
                            description += '[%#x - %#x)' % (
                                malloc_addr, malloc_addr + malloc_size)
                    else:
                        if options.type != 'isa':
                            description += '%#x + %-6u ' % (malloc_addr,
                                                            offset)
                    derefed_dynamic_value = None
                    if dynamic_value.type.name == 'void *':
                        if options.type == 'pointer' and malloc_size == 4096:
                            error = lldb.SBError()
                            data = bytearray(
                                lldb.process.ReadMemory(
                                    malloc_addr, 16, error))
                            if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
                                ptr_size = lldb.target.addr_size
                                thread = lldb.process.ReadUnsignedFromMemory(
                                    malloc_addr + 16 + ptr_size, ptr_size,
                                    error)
                                #   4 bytes  0xa1a1a1a1
                                #  12 bytes  'AUTORELEASE!'
                                # ptr bytes  autorelease insertion point
                                # ptr bytes  pthread_t
                                # ptr bytes  next colder page
                                # ptr bytes  next hotter page
                                #   4 bytes  this page's depth in the list
                                #   4 bytes  high-water mark
                                description += 'AUTORELEASE! for pthread_t %#x' % (
                                    thread)
                            else:
                                description += 'malloc(%u)' % (malloc_size)
                        else:
                            description += 'malloc(%u)' % (malloc_size)
                    else:
                        derefed_dynamic_value = dynamic_value.deref
                        if derefed_dynamic_value:
                            derefed_dynamic_type = derefed_dynamic_value.type
                            derefed_dynamic_type_size = derefed_dynamic_type.size
                            derefed_dynamic_type_name = derefed_dynamic_type.name
                            description += derefed_dynamic_type_name
                            if offset < derefed_dynamic_type_size:
                                member_list = list()
                                get_member_types_for_offset(
                                    derefed_dynamic_type, offset, member_list)
                                if member_list:
                                    member_path = ''
                                    for member in member_list:
                                        member_name = member.name
                                        if member_name:
                                            if member_path:
                                                member_path += '.'
                                            member_path += member_name
                                    if member_path:
                                        if options.ivar_regex_blacklist:
                                            for ivar_regex in options.ivar_regex_blacklist:
                                                if ivar_regex.match(
                                                        member_path):
                                                    print_entry = False
                                        description += '.%s' % (member_path)
                            else:
                                description += '%u bytes after %s' % (
                                    offset - derefed_dynamic_type_size,
                                    derefed_dynamic_type_name)
                        else:
                            # strip the "*" from the end of the name since we were unable to dereference this
                            description += dynamic_value.type.name[0:-1]
                if print_entry:
                    match_idx += 1
                    result_output = ''
                    if description:
                        result_output += description
                        if options.print_type and derefed_dynamic_value:
                            result_output += '%s' % (derefed_dynamic_value)
                        if options.print_object_description and dynamic_value:
                            desc = dynamic_value.GetObjectDescription()
                            if desc:
                                result_output += '\n%s' % (desc)
                    if result_output:
                        result.AppendMessage(result_output)
                    if options.memory:
                        cmd_result = lldb.SBCommandReturnObject()
                        memory_command = "memory read -f %s 0x%x 0x%x" % (
                            options.format, malloc_addr,
                            malloc_addr + malloc_size)
                        lldb.debugger.GetCommandInterpreter().HandleCommand(
                            memory_command, cmd_result)
                        result.AppendMessage(cmd_result.GetOutput())
                    if options.stack_history:
                        dump_stack_history_entries(result, malloc_addr, 1)
                    elif options.stack:
                        dump_stack_history_entries(result, malloc_addr, 0)
            return i
        elif print_no_matches:
            result.AppendMessage('no matches found for %s' %
                                 (arg_str_description))
    else:
        result.AppendMessage(str(expr_sbvalue.error))
    return 0
예제 #25
0
def display_match_results(result,
                          options,
                          arg_str_description,
                          expr_sbvalue,
                          print_no_matches=True):
    if expr_sbvalue.error.Success():
        if expr_sbvalue.unsigned:
            match_value = lldb.value(expr_sbvalue)
            i = 0
            match_idx = 0
            while 1:
                print_entry = True
                match_entry = match_value[i]
                i += 1
                if i >= options.max_matches:
                    result.AppendMessage(
                        'error: the max number of matches (%u) was reached, use the --max-matches option to get more results'
                        % (options.max_matches))
                    break
                malloc_addr = match_entry.addr.sbvalue.unsigned
                if malloc_addr == 0:
                    break
                malloc_size = int(match_entry.size)
                offset = int(match_entry.offset)

                if options.offset >= 0 and options.offset != offset:
                    print_entry = False
                else:
                    match_addr = malloc_addr + offset
                    dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(
                        lldb.eDynamicCanRunTarget)
                    description = '[%u] %s: addr = 0x%x' % (
                        match_idx, arg_str_description, malloc_addr)
                    if offset != 0:
                        description += ' + %u' % (offset)
                    description += ', size = %u' % (malloc_size)
                    derefed_dynamic_value = None
                    if dynamic_value.type.name == 'void *':
                        if options.type == 'pointer' and malloc_size == 4096:
                            error = lldb.SBError()
                            data = bytearray(
                                lldb.process.ReadMemory(
                                    malloc_addr, 16, error))
                            if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
                                description += ', type = (AUTORELEASE!)'
                    else:
                        derefed_dynamic_value = dynamic_value.deref
                        if derefed_dynamic_value:
                            derefed_dynamic_type = derefed_dynamic_value.type
                            derefed_dynamic_type_size = derefed_dynamic_type.size
                            derefed_dynamic_type_name = derefed_dynamic_type.name
                            description += ', type = %s <%u>' % (
                                derefed_dynamic_type_name,
                                derefed_dynamic_type_size)
                            if offset < derefed_dynamic_type_size:
                                member_list = list()
                                get_member_types_for_offset(
                                    derefed_dynamic_type, offset, member_list)
                                if member_list:
                                    member_path = ''
                                    for member in member_list:
                                        member_name = member.name
                                        if member_name:
                                            if member_path:
                                                member_path += '.'
                                            member_path += member_name
                                    if member_path:
                                        if options.ivar_regex_blacklist:
                                            for ivar_regex in options.ivar_regex_blacklist:
                                                if ivar_regex.match(
                                                        member_path):
                                                    print_entry = False
                                        description += ', ivar = %s' % (
                                            member_path)
                if print_entry:
                    match_idx += 1
                    if description:
                        result.AppendMessage(description)
                        if options.print_type and derefed_dynamic_value:
                            result.AppendMessage('%s' %
                                                 (derefed_dynamic_value))
                        if options.print_object_description and dynamic_value:
                            desc = dynamic_value.GetObjectDescription()
                            if desc:
                                result.AppendMessage(', po=%s' % (desc))
                    if options.memory:
                        cmd_result = lldb.SBCommandReturnObject()
                        memory_command = "memory read -f %s 0x%x 0x%x" % (
                            options.format, malloc_addr,
                            malloc_addr + malloc_size)
                        lldb.debugger.GetCommandInterpreter().HandleCommand(
                            memory_command, cmd_result)
                        result.AppendMessage(cmd_result.GetOutput())
                    if options.stack_history:
                        dump_stack_history_entries(result, malloc_addr, 1)
                    elif options.stack:
                        dump_stack_history_entries(result, malloc_addr, 0)
            return i
        elif print_no_matches:
            result.AppendMessage('no matches found for %s' %
                                 (arg_str_description))
    else:
        result.AppendMessage(expr_sbvalue.error)
    return 0
예제 #26
0
    def test(self):
        """Exercise some SBValue APIs."""
        d = {'EXE': self.exe_name}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        exe = os.path.join(os.getcwd(), self.exe_name)

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Create the breakpoint inside function 'main'.
        breakpoint = target.BreakpointCreateByLocation('main.c', self.line)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

        # Now launch the process, and do not stop at entry point.
        process = target.LaunchSimple(
            None, None, self.get_process_working_directory())
        self.assertTrue(process, PROCESS_IS_VALID)

        # Get Frame #0.
        self.assertTrue(process.GetState() == lldb.eStateStopped)
        thread = lldbutil.get_stopped_thread(
            process, lldb.eStopReasonBreakpoint)
        self.assertTrue(
            thread.IsValid(),
            "There should be a thread stopped due to breakpoint condition")
        frame0 = thread.GetFrameAtIndex(0)

        # Get global variable 'days_of_week'.
        list = target.FindGlobalVariables('days_of_week', 1)
        days_of_week = list.GetValueAtIndex(0)
        self.assertTrue(days_of_week, VALID_VARIABLE)
        self.assertTrue(days_of_week.GetNumChildren() == 7, VALID_VARIABLE)
        self.DebugSBValue(days_of_week)

        # Get global variable 'weekdays'.
        list = target.FindGlobalVariables('weekdays', 1)
        weekdays = list.GetValueAtIndex(0)
        self.assertTrue(weekdays, VALID_VARIABLE)
        self.assertTrue(weekdays.GetNumChildren() == 5, VALID_VARIABLE)
        self.DebugSBValue(weekdays)

        # Get global variable 'g_table'.
        list = target.FindGlobalVariables('g_table', 1)
        g_table = list.GetValueAtIndex(0)
        self.assertTrue(g_table, VALID_VARIABLE)
        self.assertTrue(g_table.GetNumChildren() == 2, VALID_VARIABLE)
        self.DebugSBValue(g_table)

        fmt = lldbutil.BasicFormatter()
        cvf = lldbutil.ChildVisitingFormatter(indent_child=2)
        rdf = lldbutil.RecursiveDecentFormatter(indent_child=2)
        if self.TraceOn():
            print(fmt.format(days_of_week))
            print(cvf.format(days_of_week))
            print(cvf.format(weekdays))
            print(rdf.format(g_table))

        # Get variable 'my_int_ptr'.
        value = frame0.FindVariable('my_int_ptr')
        self.assertTrue(value, VALID_VARIABLE)
        self.DebugSBValue(value)

        # Get what 'my_int_ptr' points to.
        pointed = value.GetChildAtIndex(0)
        self.assertTrue(pointed, VALID_VARIABLE)
        self.DebugSBValue(pointed)

        # While we are at it, verify that 'my_int_ptr' points to 'g_my_int'.
        symbol = target.ResolveLoadAddress(
            int(pointed.GetLocation(), 0)).GetSymbol()
        self.assertTrue(symbol)
        self.expect(symbol.GetName(), exe=False,
                    startstr='g_my_int')

        # Get variable 'str_ptr'.
        value = frame0.FindVariable('str_ptr')
        self.assertTrue(value, VALID_VARIABLE)
        self.DebugSBValue(value)

        # SBValue::TypeIsPointerType() should return true.
        self.assertTrue(value.TypeIsPointerType())

        # Verify the SBValue::GetByteSize() API is working correctly.
        arch = self.getArchitecture()
        if arch == 'i386':
            self.assertTrue(value.GetByteSize() == 4)
        elif arch == 'x86_64':
            self.assertTrue(value.GetByteSize() == 8)

        # Get child at index 5 => 'Friday'.
        child = value.GetChildAtIndex(5, lldb.eNoDynamicValues, True)
        self.assertTrue(child, VALID_VARIABLE)
        self.DebugSBValue(child)

        self.expect(child.GetSummary(), exe=False,
                    substrs=['Friday'])

        # Now try to get at the same variable using GetValueForExpressionPath().
        # These two SBValue objects should have the same value.
        val2 = value.GetValueForExpressionPath('[5]')
        self.assertTrue(val2, VALID_VARIABLE)
        self.DebugSBValue(val2)
        self.assertTrue(child.GetValue() == val2.GetValue() and
                        child.GetSummary() == val2.GetSummary())

        val_i = target.EvaluateExpression('i')
        val_s = target.EvaluateExpression('s')
        val_a = target.EvaluateExpression('a')
        self.assertTrue(
            val_s.GetChildMemberWithName('a').AddressOf(),
            VALID_VARIABLE)
        self.assertTrue(
            val_a.Cast(
                val_i.GetType()).AddressOf(),
            VALID_VARIABLE)

        self.assertTrue(int(lldb.value(frame0.FindVariable('uinthex')))
                        == 3768803088, 'uinthex == 3768803088')
        self.assertTrue(int(lldb.value(frame0.FindVariable('sinthex')))
                        == -526164208, 'sinthex == -526164208')

        self.assertTrue(
            frame0.FindVariable('uinthex').GetValueAsUnsigned() == 3768803088,
            'unsigned uinthex == 3768803088')
        self.assertTrue(
            frame0.FindVariable('sinthex').GetValueAsUnsigned() == 3768803088,
            'unsigned sinthex == 3768803088')

        self.assertTrue(
            frame0.FindVariable('uinthex').GetValueAsSigned() == -
            526164208,
            'signed uinthex == -526164208')
        self.assertTrue(
            frame0.FindVariable('sinthex').GetValueAsSigned() == -
            526164208,
            'signed sinthex == -526164208')