Пример #1
0
def ibreak(debugger, command, result, internal_dict):
	address = iraddress(debugger, command, result, internal_dict)
	returnObject = lldb.SBCommandReturnObject()
	debugger.GetCommandInterpreter().HandleCommand('br set -a %s' % address, returnObject)
	output = returnObject.GetOutput();
	print output
Пример #2
0
    def test_session_save(self):
        raw = ""
        interpreter = self.dbg.GetCommandInterpreter()

        settings = [
            'settings set interpreter.echo-commands true',
            'settings set interpreter.echo-comment-commands true',
            'settings set interpreter.stop-command-source-on-error false'
        ]

        for setting in settings:
            interpreter.HandleCommand(setting, lldb.SBCommandReturnObject())

        inputs = [
            '# This is a comment',  # Comment
            'help session',  # Valid command
            'Lorem ipsum'  # Invalid command
        ]

        for cmd in inputs:
            res = lldb.SBCommandReturnObject()
            interpreter.HandleCommand(cmd, res)
            raw += self.raw_transcript_builder(cmd, res)

        self.assertTrue(interpreter.HasCommands())
        self.assertTrue(len(raw) != 0)

        # Check for error
        cmd = 'session save /root/file'
        interpreter.HandleCommand(cmd, res)
        self.assertFalse(res.Succeeded())
        raw += self.raw_transcript_builder(cmd, res)

        tf = tempfile.NamedTemporaryFile()
        output_file = tf.name

        res = lldb.SBCommandReturnObject()
        interpreter.HandleCommand('session save ' + output_file, res)
        self.assertTrue(res.Succeeded())
        raw += self.raw_transcript_builder(cmd, res)

        with open(output_file, "r") as file:
            content = file.read()
            # Exclude last line, since session won't record it's own output
            lines = raw.splitlines()[:-1]
            for line in lines:
                self.assertIn(line, content)

        td = tempfile.TemporaryDirectory()
        res = lldb.SBCommandReturnObject()
        interpreter.HandleCommand(
            'settings set interpreter.save-session-directory ' + td.name, res)
        self.assertTrue(res.Succeeded())

        res = lldb.SBCommandReturnObject()
        interpreter.HandleCommand('session save', res)
        self.assertTrue(res.Succeeded())
        raw += self.raw_transcript_builder(cmd, res)

        with open(os.path.join(td.name, os.listdir(td.name)[0]), "r") as file:
            content = file.read()
            # Exclude last line, since session won't record it's own output
            lines = raw.splitlines()[:-1]
            for line in lines:
                self.assertIn(line, content)
Пример #3
0
def dclass(debugger, command, result, internal_dict):
    '''
    Dumps all the NSObject inherited classes in the process. If you give it a module, 
    it will dump only the classes within that module. You can also filter out classes 
    to only a certain type and can also generate a header file for a specific class.
  
  Example: 
  
      # Dump ALL the NSObject classes within the process
      (lldb) dclass 

      # Dump all the classes that are a UIViewController within the process
      (lldb) dclass -f UIViewController
      
      # Dump all the classes with the regex case insensitive search "viewcontroller" in the class name
      (lldb) dclass -r (?i)viewCoNtrolLer
      
      # Dump all the classes within the UIKit module
      (lldb) dclass -m UIKit

      # Dump all classes in CKConfettiEffect NSBundle that are UIView subclasses
      (lldb) dclass /System/Library/Messages/iMessageEffects/CKConfettiEffect.bundle/CKConfettiEffect -f UIView
      
      # Generate a header file for the class specified:
      (lldb) dclass -g UIView
      
      # Generate a protocol that you can cast an object to. Ideal when working with private classes at dev time
      (lldb) dclass -P UIView

      # Dump all classes and methods for a particular module, ideal for viewing changes in frameworks over time
      (lldb) dclass -o UIKit

      # Only dump classes whose superclass is of type class and in UIKit module. Ideal for going after specific classes
      (lldb) dclass -s NSObject -m UIKit
    '''

    command_args = shlex.split(command, posix=False)
    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')
        clean_command = None
        # return
    if not args and options.generate_header:
        result.SetError('Need to supply class for option')
        return
    else:
        clean_command = ('').join(args)

    res = lldb.SBCommandReturnObject()
    interpreter = debugger.GetCommandInterpreter()
    target = debugger.GetSelectedTarget()
    if options.dump_code_output:
        directory = '/tmp/{}_{}/'.format(ds.getTarget().executable.basename,
                                         datetime.datetime.now().time())
        os.makedirs(directory)

        modules = ds.getTarget().modules
        if len(args) > 0 and args[0] == '__all':
            os.makedirs(directory + 'PrivateFrameworks')
            os.makedirs(directory + 'Frameworks')
            modules = [
                i for i in ds.getTarget().modules
                if '/usr/lib/' not in i.file.fullpath
                and '__lldb_' not in i.file.fullpath
            ]
            outputMsg = "Dumping all private Objective-C frameworks"
        elif len(args) > 0 and args[0]:
            module = ds.getTarget().module[args[0]]
            if module is None:
                result.SetError(
                    "Unable to open module name '{}', to see list of images use 'image list -b'"
                    .format(args[0]))
                return
            modules = [module]
            outputMsg = "Dumping all private Objective-C frameworks"
        else:
            modules = [
                ds.getTarget().module[ds.getTarget().executable.fullpath]
            ]

        for module in modules:
            command_script = generate_module_header_script(
                options, module.file.fullpath.replace('//', '/'))

            interpreter.HandleCommand(
                'expression -lobjc -O -u0 -- ' + command_script, res)
            # debugger.HandleCommand('expression -lobjc -O -- ' + command_script)
            if '/System/Library/PrivateFrameworks/' in module.file.fullpath:
                subdir = 'PrivateFrameworks/'
            elif '/System/Library/Frameworks/' in module.file.fullpath:
                subdir = 'Frameworks/'
            else:
                subdir = ''

            ds.create_or_touch_filepath(
                directory + subdir + module.file.basename + '.txt',
                res.GetOutput())
        print('Written output to: ' + directory + '... opening file')
        os.system('open -R ' + directory)
        return

    if options.module is not None:
        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(str(options.module)))
            return

    if options.conforms_to_protocol is not None:
        interpreter.HandleCommand(
            'expression -lobjc -O -- (id)NSProtocolFromString(@\"{}\")'.format(
                options.conforms_to_protocol), res)
        if 'nil' in res.GetOutput() or not res.GetOutput():
            result.SetError("No such Protocol name '{}'".format(
                options.conforms_to_protocol))
            return
        res.Clear()

    if options.generate_header or options.generate_protocol:
        command_script = generate_header_script(options, clean_command)
    else:
        command_script = generate_class_dump(debugger, options, clean_command)

    if options.generate_header or options.generate_protocol:
        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
        res.Clear()

        if options.generate_protocol:
            filepath = "/tmp/DS_" + clean_command + "Protocol.h"
        else:
            filepath = "/tmp/" + clean_command + ".h"
        interpreter.HandleCommand('expression -lobjc -O -- ' + command_script,
                                  res)
        # debugger.HandleCommand('expression -lobjc -O -g -- ' + command_script)
        if res.GetError():
            result.SetError(res.GetError())
            return
        contents = res.GetOutput()

        ds.create_or_touch_filepath(filepath, contents)
        print('Written output to: ' + filepath + '... opening file')
        os.system('open -R ' + filepath)
    else:
        msg = "Dumping protocols" if options.search_protocols else "Dumping classes"
        result.AppendMessage(ds.attrStr(msg, 'cyan'))

        interpreter.HandleCommand('expression -lobjc -O -- ' + command_script,
                                  res)
        # debugger.HandleCommand('expression -lobjc -O -g -- ' + command_script)
        if res.GetError():
            result.SetError(ds.attrStr(res.GetError(), 'red'))
            return
        result.AppendMessage(
            ds.attrStr(
                '************************************************************',
                'cyan'))
        if res.Succeeded():
            result.AppendMessage(res.GetOutput())
Пример #4
0
    def do_test(self):
        target = self.createTestTarget()

        # Now create a breakpoint in main.c at the source matching
        # "Set a breakpoint here"
        breakpoint = target.BreakpointCreateBySourceRegex(
            "Set a breakpoint here", lldb.SBFileSpec("main.c"))
        self.assertTrue(breakpoint and breakpoint.GetNumLocations() >= 1,
                        VALID_BREAKPOINT)

        error = lldb.SBError()
        # This is the launch info.  If you want to launch with arguments or
        # environment variables, add them using SetArguments or
        # SetEnvironmentEntries

        launch_info = target.GetLaunchInfo()
        process = target.Launch(launch_info, error)
        self.assertTrue(process, PROCESS_IS_VALID)

        # Did we hit our breakpoint?
        from lldbsuite.test.lldbutil import get_threads_stopped_at_breakpoint
        threads = get_threads_stopped_at_breakpoint(process, breakpoint)
        self.assertEqual(len(threads), 1,
                         "There should be a thread stopped at our breakpoint")

        # The hit count for the breakpoint should be 1.
        self.assertEquals(breakpoint.GetHitCount(), 1)

        frame = threads[0].GetFrameAtIndex(0)
        command_result = lldb.SBCommandReturnObject()
        interp = self.dbg.GetCommandInterpreter()

        # Just get args:
        result = interp.HandleCommand("frame var -l", command_result)
        self.assertEqual(result, lldb.eReturnStatusSuccessFinishResult,
                         "frame var -a didn't succeed")
        output = command_result.GetOutput()
        self.assertIn("argc", output, "Args didn't find argc")
        self.assertIn("argv", output, "Args didn't find argv")
        self.assertNotIn("test_var", output, "Args found a local")
        self.assertNotIn("g_var", output, "Args found a global")

        # Just get locals:
        result = interp.HandleCommand("frame var -a", command_result)
        self.assertEqual(result, lldb.eReturnStatusSuccessFinishResult,
                         "frame var -a didn't succeed")
        output = command_result.GetOutput()
        self.assertNotIn("argc", output, "Locals found argc")
        self.assertNotIn("argv", output, "Locals found argv")
        self.assertIn("test_var", output, "Locals didn't find test_var")
        self.assertNotIn("g_var", output, "Locals found a global")

        # Get the file statics:
        result = interp.HandleCommand("frame var -l -a -g", command_result)
        self.assertEqual(result, lldb.eReturnStatusSuccessFinishResult,
                         "frame var -a didn't succeed")
        output = command_result.GetOutput()
        self.assertNotIn("argc", output, "Globals found argc")
        self.assertNotIn("argv", output, "Globals found argv")
        self.assertNotIn("test_var", output, "Globals found test_var")
        self.assertIn("g_var", output, "Globals didn't find g_var")
Пример #5
0
    def run_python_os_step_missing_thread(self, do_prune):
        """Test that the Python operating system plugin works correctly"""

        # Our OS plugin does NOT report all threads:
        result = self.dbg.HandleCommand(
            "settings set process.experimental.os-plugin-reports-all-threads false"
        )

        python_os_plugin_path = os.path.join(self.getSourceDir(),
                                             "operating_system.py")
        (target, self.process, thread,
         thread_bkpt) = lldbutil.run_to_source_breakpoint(
             self, "first stop in thread - do a step out", self.main_file)

        main_bkpt = target.BreakpointCreateBySourceRegex(
            'Stop here and do not make a memory thread for thread_1',
            self.main_file)
        self.assertEqual(main_bkpt.GetNumLocations(), 1,
                         "Main breakpoint has one location")

        # There should not be an os thread before we load the plugin:
        self.assertFalse(self.get_os_thread().IsValid(),
                         "No OS thread before loading plugin")

        # Now load the python OS plug-in which should update the thread list and we should have
        # an OS plug-in thread overlaying thread_1 with id 0x111111111
        command = "settings set target.process.python-os-plugin-path '%s'" % python_os_plugin_path
        self.dbg.HandleCommand(command)

        # Verify our OS plug-in threads showed up
        os_thread = self.get_os_thread()
        self.assertTrue(
            os_thread.IsValid(),
            "Make sure we added the thread 0x111111111 after we load the python OS plug-in"
        )

        # Now we are going to step-out.  This should get interrupted by main_bkpt.  We've
        # set up the OS plugin so at this stop, we have lost the OS thread 0x111111111.
        # Make sure both of these are true:
        os_thread.StepOut()

        stopped_threads = lldbutil.get_threads_stopped_at_breakpoint(
            self.process, main_bkpt)
        self.assertEqual(len(stopped_threads), 1, "Stopped at main_bkpt")
        thread = self.process.GetThreadByID(0x111111111)
        self.assertFalse(thread.IsValid(),
                         "No thread 0x111111111 on second stop.")

        # Make sure we still have the thread plans for this thread:
        # First, don't show unreported threads, that should fail:
        command = "thread plan list -t 0x111111111"
        result = lldb.SBCommandReturnObject()
        interp = self.dbg.GetCommandInterpreter()
        interp.HandleCommand(command, result)
        self.assertFalse(result.Succeeded(),
                         "We found no plans for the unreported thread.")
        # Now do it again but with the -u flag:
        command = "thread plan list -u -t 0x111111111"
        result = lldb.SBCommandReturnObject()
        interp.HandleCommand(command, result)
        self.assertTrue(result.Succeeded(),
                        "We found plans for the unreported thread.")

        if do_prune:
            # Prune the thread plan and continue, and we will run to exit.
            interp.HandleCommand("thread plan prune 0x111111111", result)
            self.assertTrue(result.Succeeded(),
                            "Found the plan for 0x111111111 and pruned it")

            # List again, make sure it doesn't work:
            command = "thread plan list -u -t 0x111111111"
            interp.HandleCommand(command, result)
            self.assertFalse(
                result.Succeeded(),
                "We still found plans for the unreported thread.")

            self.process.Continue()
            self.assertState(self.process.GetState(), lldb.eStateExited,
                             "We exited.")
        else:
            # Now we are going to continue, and when we hit the step-out breakpoint, we will
            # put the OS plugin thread back, lldb will recover its ThreadPlanStack, and
            # we will stop with a "step-out" reason.
            self.process.Continue()
            os_thread = self.get_os_thread()
            self.assertTrue(os_thread.IsValid(),
                            "The OS thread is back after continue")
            self.assertIn("step out", os_thread.GetStopDescription(100),
                          "Completed step out plan")
Пример #6
0
    def test_command_abbreviations_and_aliases(self):
        command_interpreter = self.dbg.GetCommandInterpreter()
        self.assertTrue(command_interpreter, VALID_COMMAND_INTERPRETER)
        result = lldb.SBCommandReturnObject()

        # Check that abbreviations are expanded to the full command.
        command_interpreter.ResolveCommand("ap script", result)
        self.assertTrue(result.Succeeded())
        self.assertEqual("apropos script", result.GetOutput())

        command_interpreter.ResolveCommand("h", result)
        self.assertTrue(result.Succeeded())
        self.assertEqual("help", result.GetOutput())

        # Check resolution of abbreviations for multi-word commands.
        command_interpreter.ResolveCommand("lo li", result)
        self.assertTrue(result.Succeeded())
        self.assertEqual("log list", result.GetOutput())

        command_interpreter.ResolveCommand("br s", result)
        self.assertTrue(result.Succeeded())
        self.assertEqual("breakpoint set", result.GetOutput())

        # Try an ambiguous abbreviation.
        # "pl" could be "platform" or "plugin".
        command_interpreter.ResolveCommand("pl", result)
        self.assertFalse(result.Succeeded())
        self.assertTrue(result.GetError().startswith("Ambiguous command"))

        # Make sure an unabbreviated command is not mangled.
        command_interpreter.ResolveCommand(
            "breakpoint set --name main --line 123", result)
        self.assertTrue(result.Succeeded())
        self.assertEqual("breakpoint set --name main --line 123",
                         result.GetOutput())

        # Create some aliases.
        self.runCmd("com a alias com al")
        self.runCmd("alias gurp help")

        # Check that an alias is replaced with the actual command
        command_interpreter.ResolveCommand("gurp target create", result)
        self.assertTrue(result.Succeeded())
        self.assertEqual("help target create", result.GetOutput())

        # Delete the alias and make sure it no longer has an effect.
        self.runCmd("com u gurp")
        command_interpreter.ResolveCommand("gurp", result)
        self.assertFalse(result.Succeeded())

        # Check aliases with text replacement.
        self.runCmd("alias pltty process launch -s -o %1 -e %1")
        command_interpreter.ResolveCommand("pltty /dev/tty0", result)
        self.assertTrue(result.Succeeded())
        self.assertEqual("process launch -s -o /dev/tty0 -e /dev/tty0",
                         result.GetOutput())

        self.runCmd("alias xyzzy breakpoint set -n %1 -l %2")
        command_interpreter.ResolveCommand("xyzzy main 123", result)
        self.assertTrue(result.Succeeded())
        self.assertEqual("breakpoint set -n main -l 123",
                         result.GetOutput().strip())

        # And again, without enough parameters.
        command_interpreter.ResolveCommand("xyzzy main", result)
        self.assertFalse(result.Succeeded())

        # Check a command that wants the raw input.
        command_interpreter.ResolveCommand(r'''sc print("\n\n\tHello!\n")''',
                                           result)
        self.assertTrue(result.Succeeded())
        self.assertEqual(r'''script print("\n\n\tHello!\n")''',
                         result.GetOutput())
Пример #7
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
                    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 += ', po=%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
Пример #8
0
def decryptDump(debugger, command, result, dict):

    MH_MAGIC = 0xFEEDFACE
    MH_CIGAM = 0xCEFAEDFE

    MH_MAGIC_64 = 0xFEEDFACF
    MH_CIGAM_64 = 0xCFFAEDFE

    LC_ENCRYPTION_INFO = 0x21
    LC_ENCRYPTION_INFO_64 = 0x2C
    MACHO_HEADER_SIZE = 28
    MACHO_HEADER_SIZE_64 = 32

    # 解析参数
    usage = 'usage: %prog [options]'
    parser = optparse.OptionParser(prog='decryptDump', usage=usage)
    parser.add_option('-i',
                      '--image',
                      type='string',
                      dest='image',
                      help='The image to be decrypted.')
    parser.add_option('-o',
                      '--output',
                      type='string',
                      dest='output',
                      help='The decrypted file store path.')

    commandList = shlex.split(command)
    try:
        (options, args) = parser.parse_args(commandList)
    except Exception as e:
        print e
        return

    if options.output == None:
        raise Exception(
            "No specified output path,Please use -h to see the instructions.")
    elif options.image == None:
        raise Exception(
            "No module specified,Please use -h to see the instructions.")

    target = debugger.GetSelectedTarget()

    for module in target.modules:
        # print module
        if module.file.basename == options.image:

            image_load_address = module.GetObjectFileHeaderAddress(
            ).GetLoadAddress(target)
            print "INFO: image `%s` loaded at <0x%016x>" % (options.image,
                                                            image_load_address)

            process = target.GetProcess()
            read_res = lldb.SBError()
            macho_memory = process.ReadMemory(image_load_address, 24, read_res)

            prefix = ""
            mach_header_size = 0x0
            encryption_info_cmd = LC_ENCRYPTION_INFO
            encryption_info_description = "LC_ENCRYPTION_INFO"
            cryptoffset = 0
            cryptsize = 0
            cryptid = 0

            if read_res.Success():
                magic, = struct.unpack("<I", macho_memory[0:4])

                print "%x" % (magic)
                print "%x" % (MH_MAGIC_64)

                if magic == MH_MAGIC or magic == MH_MAGIC_64:
                    #小端
                    prefix = '<'
                elif magic == MH_CIGAM or magic == MH_CIGAM_64:
                    #大端
                    prefix = '>'
                else:
                    raise Exception("magic error ===> [0x%4x]" % (magic))

                #64bit
                if magic == MH_CIGAM_64 or magic == MH_MAGIC_64:
                    mach_header_size = MACHO_HEADER_SIZE_64
                    encryption_info_cmd = LC_ENCRYPTION_INFO_64
                    encryption_info_description = 'LC_ENCRYPTION_INFO_64'

                #读取`ncmds`和`sizecmds`
                ncmds, sizecmds = struct.unpack(prefix + '2I',
                                                macho_memory[16:24])
                macho_memory = process.ReadMemory(image_load_address,
                                                  sizecmds + mach_header_size,
                                                  read_res)
                load_command_start = mach_header_size

                #读取各个`loadcommand`,寻找 `LC_ENCRYPTION_INFO` 或 `LC_ENCRYPTION_INFO_64`
                for i in range(ncmds):

                    cmd, cmdsize = struct.unpack(
                        prefix + '2I',
                        macho_memory[load_command_start:load_command_start +
                                     8])
                    if cmd == encryption_info_cmd:
                        load_command_start = load_command_start + 8
                        cryptoffset, cryptsize, cryptid = struct.unpack(
                            prefix + '3I', macho_memory[
                                load_command_start:load_command_start + 12])
                        print "INFO: cryptoffset: 0x%04x\n      cryptsize: 0x%04x\n      cryptid: 0x%04x\n" % (
                            cryptoffset, cryptsize, cryptid)

                        break

                    else:
                        load_command_start = load_command_start + cmdsize

                ci = debugger.GetCommandInterpreter()
                res = lldb.SBCommandReturnObject()
                ci.HandleCommand(
                    "memory read --force --outfile %s --binary --count %d 0x%016X"
                    % (options.output, cryptsize,
                       image_load_address + cryptoffset), res)
                if res.Succeeded():
                    print "INFO: 0x%4x bytes read as binary" % (cryptsize)
                else:
                    print res
            else:
                #读取错误
                print read_res

            #找到了相对应的模块,直接返回
            break
Пример #9
0
 def set_handle(self, signal, pass_signal, stop_at_signal, notify_signal):
     return_obj = lldb.SBCommandReturnObject()
     self.dbg.GetCommandInterpreter().HandleCommand(
             "process handle %s -p %s -s %s -n %s" % (signal, pass_signal, stop_at_signal, notify_signal),
             return_obj)
     self.assertTrue (return_obj.Succeeded() == True, "Setting signal handling failed")
Пример #10
0
    def check_list_output(self,
                          command,
                          active_plans=[],
                          completed_plans=[],
                          discarded_plans=[]):
        # Check the "thread plan list" output against a list of active & completed and discarded plans.
        # If all three check arrays are empty, that means the command is expected to fail.

        interp = self.dbg.GetCommandInterpreter()
        result = lldb.SBCommandReturnObject()

        num_active = len(active_plans)
        num_completed = len(completed_plans)
        num_discarded = len(discarded_plans)

        interp.HandleCommand(command, result)
        print("Command: %s" % (command))
        print(result.GetOutput())

        if num_active == 0 and num_completed == 0 and num_discarded == 0:
            self.assertFalse(
                result.Succeeded(),
                "command: '%s' succeeded when it should have failed: '%s'" %
                (command, result.GetError()))
            return

        self.assertTrue(
            result.Succeeded(),
            "command: '%s' failed: '%s'" % (command, result.GetError()))
        result_arr = result.GetOutput().splitlines()
        num_results = len(result_arr)

        # Match the expected number of elements.
        # Adjust the count for the number of header lines we aren't matching:
        fudge = 0

        if num_completed == 0 and num_discarded == 0:
            # The fudge is 3: Thread header, Active Plan header and base plan
            fudge = 3
        elif num_completed == 0 or num_discarded == 0:
            # The fudge is 4: The above plus either the Completed or Discarded Plan header:
            fudge = 4
        else:
            # The fudge is 5 since we have both headers:
            fudge = 5

        self.assertEqual(
            num_results, num_active + num_completed + num_discarded + fudge,
            "Too many elements in match arrays for: \n%s\n" %
            result.GetOutput())

        # Now iterate through the results array and pick out the results.
        result_idx = 0
        self.assertIn("thread #", result_arr[result_idx],
                      "Found thread header")
        result_idx += 1
        self.assertIn("Active plan stack", result_arr[result_idx],
                      "Found active header")
        result_idx += 1
        self.assertIn("Element 0: Base thread plan", result_arr[result_idx],
                      "Found base plan")
        result_idx += 1

        for text in active_plans:
            self.assertFalse("Completed plan stack" in result_arr[result_idx],
                             "Found Completed header too early.")
            self.assertIn(text, result_arr[result_idx],
                          "Didn't find active plan: %s" % (text))
            result_idx += 1

        if len(completed_plans) > 0:
            self.assertIn("Completed plan stack:", result_arr[result_idx],
                          "Found completed plan stack header")
            result_idx += 1
            for text in completed_plans:
                self.assertIn(text, result_arr[result_idx],
                              "Didn't find completed plan: %s" % (text))
                result_idx += 1

        if len(discarded_plans) > 0:
            self.assertIn("Discarded plan stack:", result_arr[result_idx],
                          "Found discarded plan stack header")
            result_idx += 1
            for text in discarded_plans:
                self.assertIn(text, result_arr[result_idx],
                              "Didn't find completed plan: %s" % (text))
                result_idx += 1
 def is_continue(interpreter, command):
     ret = lldb.SBCommandReturnObject()
     interpreter.ResolveCommand(command, ret)
     return ret.GetOutput() == 'process continue'
Пример #12
0
    def thread_plan_test(self):
        (target, process, thread,
         bkpt) = lldbutil.run_to_source_breakpoint(self,
                                                   "Set a breakpoint here",
                                                   self.main_source_file)

        # Now set a breakpoint in call_me and step over.  We should have
        # two public thread plans
        call_me_bkpt = target.BreakpointCreateBySourceRegex(
            "Set another here", self.main_source_file)
        self.assertTrue(call_me_bkpt.GetNumLocations() > 0,
                        "Set the breakpoint successfully")
        thread.StepOver()
        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, call_me_bkpt)
        self.assertEqual(len(threads), 1,
                         "Hit my breakpoint while stepping over")

        current_id = threads[0].GetIndexID()
        current_tid = threads[0].GetThreadID()
        # Run thread plan list without the -i flag:
        command = "thread plan list %d" % (current_id)
        self.check_list_output(command, ["Stepping over line main.c"], [])

        # Run thread plan list with the -i flag:
        command = "thread plan list -i %d" % (current_id)
        self.check_list_output(
            command, ["Stepping over line main.c", "Stepping out from"])

        # Run thread plan list providing TID, output should be the same:
        command = "thread plan list -t %d" % (current_tid)
        self.check_list_output(command, ["Stepping over line main.c"])

        # Provide both index & tid, and make sure we only print once:
        command = "thread plan list -t %d %d" % (current_tid, current_id)
        self.check_list_output(command, ["Stepping over line main.c"])

        # Try a fake TID, and make sure that fails:
        fake_tid = 0
        for i in range(100, 10000, 100):
            fake_tid = current_tid + i
            thread = process.GetThreadByID(fake_tid)
            if not thread:
                break

        command = "thread plan list -t %d" % (fake_tid)
        self.check_list_output(command)

        # Now continue, and make sure we printed the completed plan:
        process.Continue()
        threads = lldbutil.get_stopped_threads(process,
                                               lldb.eStopReasonPlanComplete)
        self.assertEqual(len(threads), 1, "One thread completed a step")

        # Run thread plan list - there aren't any private plans at this point:
        command = "thread plan list %d" % (current_id)
        self.check_list_output(command, [], ["Stepping over line main.c"])

        # Set another breakpoint that we can run to, to try deleting thread plans.
        second_step_bkpt = target.BreakpointCreateBySourceRegex(
            "Run here to step over again", self.main_source_file)
        self.assertTrue(second_step_bkpt.GetNumLocations() > 0,
                        "Set the breakpoint successfully")
        final_bkpt = target.BreakpointCreateBySourceRegex(
            "Make sure we get here on last continue", self.main_source_file)
        self.assertTrue(final_bkpt.GetNumLocations() > 0,
                        "Set the breakpoint successfully")

        threads = lldbutil.continue_to_breakpoint(process, second_step_bkpt)
        self.assertEqual(len(threads), 1, "Hit the second step breakpoint")

        threads[0].StepOver()
        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, call_me_bkpt)

        result = lldb.SBCommandReturnObject()
        interp = self.dbg.GetCommandInterpreter()
        interp.HandleCommand("thread plan discard 1", result)
        self.assertTrue(
            result.Succeeded(),
            "Deleted the step over plan: %s" % (result.GetOutput()))

        # Make sure the plan gets listed in the discarded plans:
        command = "thread plan list %d" % (current_id)
        self.check_list_output(command, [], [], ["Stepping over line main.c:"])

        process.Continue()
        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, final_bkpt)
        self.assertEqual(len(threads), 1, "Ran to final breakpoint")
        threads = lldbutil.get_stopped_threads(process,
                                               lldb.eStopReasonPlanComplete)
        self.assertEqual(len(threads), 0,
                         "Did NOT complete the step over plan")
Пример #13
0
    def test(self):
        """
        Test that lldb correctly fetches the target definition file
        in multiple chunks if the remote server only provides the 
        content in small parts, and the small parts it provides is
        smaller than the maximum packet size that it declared at
        the start of the debug session.  qemu does this.
        """
        class MyResponder(MockGDBServerResponder):
            def qXferRead(self, obj, annex, offset, length):
                if annex == "target.xml":
                    return """<?xml version="1.0"?>
                              <!DOCTYPE feature SYSTEM "gdb-target.dtd">
                              <target version="1.0">
                              <architecture>i386:x86-64</architecture>
                              <xi:include href="i386-64bit-core.xml"/>
                              </target>""", False

                if annex == "i386-64bit-core.xml" and offset == 0:
                    return """<?xml version="1.0"?>
<!-- Copyright (C) 2010-2015 Free Software Foundation, Inc.

     Copying and distribution of this file, with or without modification,
     are permitted in any medium without royalty provided the copyright
     notice and this notice are preserved.  -->

<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.i386.core">
  <flags id="i386_eflags" size="4">
    <field name="CF" start="0" end="0"/>
    <field name="" start="1" end="1"/>
    <field name="PF" start="2" end="2"/>
    <field name="AF" start="4" end="4"/>
    <field name="ZF" start="6" end="6"/>
    <field name="SF" start="7" end="7"/>
    <field name="TF" start="8" end="8"/>
    <field name="IF" start="9" end="9"/>
    <field name="DF" start="10" end="10"/>
    <field name="OF" start="11" end="11"/>
    <field name="NT" start="14" end="14"/>
    <field name="RF" start="16" end="16"/>
    <field name="VM" start="17" end="17"/>
    <field name="AC" start="18" end="18"/>
    <field name="VIF" start="19" end="19"/>
    <field name="VIP" start="20" end="20"/>
    <field name="ID" start="21" end="21"/>
  </flags>

  <reg name="rax" bitsize="64" type="int64"/>
  <reg name="rbx" bitsize="64" type="int64"/>
  <reg name="rcx" bitsize="64" type="int64"/>
  <reg name="rdx" bitsize="64" type="int64"/>
  <reg name="rsi" bitsize="64" type="int64"/>
  <reg name="rdi" bitsize="64" type="int64"/>
  <reg name="rbp" bitsize="64" type="data_ptr"/>
  <reg name="rsp" bitsize="64" type="data_ptr"/>
  <reg name="r8" bitsize="64" type="int64"/>
  <reg name="r9" bitsize="64" type="int64"/>
  <reg name="r10" bitsize="64" type="int64"/>
  <reg name="r11" bitsize="64" type="int64"/>
  <reg name="r12" bitsize="64" type="int64"/>
  <reg name="r13" bitsize="64" type="int64"/>
  <reg name="r14" bitsize="64" type="int64"/>
  <reg name="r15" bitsize="64" type="int64"/>

  <reg name="rip" bitsize="64" type="code_ptr"/>
  <reg name="eflags" bitsize="32" type="i386_eflags"/>
  <reg name="cs" bitsize="32" type="int32"/>
  <reg name="ss" bitsize="32" ty""", True

                if annex == "i386-64bit-core.xml" and offset == 2045:
                    return """pe="int32"/>
  <reg name="ds" bitsize="32" type="int32"/>
  <reg name="es" bitsize="32" type="int32"/>
  <reg name="fs" bitsize="32" type="int32"/>
  <reg name="gs" bitsize="32" type="int32"/>

  <reg name="st0" bitsize="80" type="i387_ext"/>
  <reg name="st1" bitsize="80" type="i387_ext"/>
  <reg name="st2" bitsize="80" type="i387_ext"/>
  <reg name="st3" bitsize="80" type="i387_ext"/>
  <reg name="st4" bitsize="80" type="i387_ext"/>
  <reg name="st5" bitsize="80" type="i387_ext"/>
  <reg name="st6" bitsize="80" type="i387_ext"/>
  <reg name="st7" bitsize="80" type="i387_ext"/>

  <reg name="fctrl" bitsize="32" type="int" group="float"/>
  <reg name="fstat" bitsize="32" type="int" group="float"/>
  <reg name="ftag" bitsize="32" type="int" group="float"/>
  <reg name="fiseg" bitsize="32" type="int" group="float"/>
  <reg name="fioff" bitsize="32" type="int" group="float"/>
  <reg name="foseg" bitsize="32" type="int" group="float"/>
  <reg name="fooff" bitsize="32" type="int" group="float"/>
  <reg name="fop" bitsize="32" type="int" group="float"/>
</feature>""", False

                return None, False

            def readRegister(self, regnum):
                return ""

            def readRegisters(self):
                return "0600000000000000c0b7c00080fffffff021c60080ffffff1a00000000000000020000000000000078b7c00080ffffff203f8ca090ffffff103f8ca090ffffff3025990a80ffffff809698000000000070009f0a80ffffff020000000000000000eae10080ffffff00000000000000001822d74f1a00000078b7c00080ffffff0e12410080ffff004602000011111111222222223333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000"

            def haltReason(self):
                return "T02thread:dead;threads:dead;"

            def qfThreadInfo(self):
                return "mdead"

            def qC(self):
                return ""

            def qSupported(self, client_supported):
                return "PacketSize=1000;qXfer:features:read+"

            def QThreadSuffixSupported(self):
                return "OK"

            def QListThreadsInStopReply(self):
                return "OK"

        self.server.responder = MyResponder()
        if self.TraceOn():
            self.runCmd("log enable gdb-remote packets")
            time.sleep(10)
            self.addTearDownHook(
                lambda: self.runCmd("log disable gdb-remote packets"))

        target = self.dbg.CreateTargetWithFileAndArch(None, None)

        process = self.connect(target)

        if self.TraceOn():
            interp = self.dbg.GetCommandInterpreter()
            result = lldb.SBCommandReturnObject()
            interp.HandleCommand("target list", result)
            print(result.GetOutput())

        rip_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).FindRegister("rip")
        self.assertEqual(rip_valobj.GetValueAsUnsigned(), 0x00ffff800041120e)

        ss_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).FindRegister("ss")
        self.assertEqual(ss_valobj.GetValueAsUnsigned(), 0x22222222)

        if self.TraceOn():
            print("rip is 0x%x" % rip_valobj.GetValueAsUnsigned())
            print("ss is 0x%x" % ss_valobj.GetValueAsUnsigned())
 def getCommandOutput(self, command, command_args=""):
   """ runs cmd in the command interpreter andreturns (status, result) """
   result = lldb.SBCommandReturnObject()
   cmd = "%s %s" % (command, command_args)
   self.commandInterpreter.HandleCommand(cmd, result)
   return (result.Succeeded(), result.GetOutput() if result.Succeeded() else result.GetError())
Пример #15
0
    def test(self):
        """
        Test lldb's parsing of SEGGER J-Link v6.54 register
        definition for a Cortex M-4 dev board, and the fact
        that the J-Link only supports g/G for reading/writing
        register AND the J-Link v6.54 doesn't provide anything
        but the general purpose registers."""
        class MyResponder(MockGDBServerResponder):
            def qXferRead(self, obj, annex, offset, length):
                if annex == "target.xml":
                    return """<?xml version="1.0"?>
<!-- Copyright (C) 2008 Free Software Foundation, Inc.

     Copying and distribution of this file, with or without modification,
     are permitted in any medium without royalty provided the copyright
     notice and this notice are preserved.  -->

<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<target version="1.0">
  <architecture>arm</architecture>
  <feature name="org.gnu.gdb.arm.m-profile">
    <reg name="r0" bitsize="32" regnum="0" type="uint32" group="general"/>
    <reg name="r1" bitsize="32" regnum="1" type="uint32" group="general"/>
    <reg name="r2" bitsize="32" regnum="2" type="uint32" group="general"/>
    <reg name="r3" bitsize="32" regnum="3" type="uint32" group="general"/>
    <reg name="r4" bitsize="32" regnum="4" type="uint32" group="general"/>
    <reg name="r5" bitsize="32" regnum="5" type="uint32" group="general"/>
    <reg name="r6" bitsize="32" regnum="6" type="uint32" group="general"/>
    <reg name="r7" bitsize="32" regnum="7" type="uint32" group="general"/>
    <reg name="r8" bitsize="32" regnum="8" type="uint32" group="general"/>
    <reg name="r9" bitsize="32" regnum="9" type="uint32" group="general"/>
    <reg name="r10" bitsize="32" regnum="10" type="uint32" group="general"/>
    <reg name="r11" bitsize="32" regnum="11" type="uint32" group="general"/>
    <reg name="r12" bitsize="32" regnum="12" type="uint32" group="general"/>
    <reg name="sp" bitsize="32" regnum="13" type="data_ptr" group="general"/>
    <reg name="lr" bitsize="32" regnum="14" type="uint32" group="general"/>
    <reg name="pc" bitsize="32" regnum="15" type="code_ptr" group="general"/>
    <reg name="xpsr" bitsize="32" regnum="25" type="uint32" group="general"/>
  </feature>
  <feature name="org.gnu.gdb.arm.m-system">
    <reg name="msp" bitsize="32" regnum="26" type="uint32" group="general"/>
    <reg name="psp" bitsize="32" regnum="27" type="uint32" group="general"/>
    <reg name="primask" bitsize="32" regnum="28" type="uint32" group="general"/>
    <reg name="basepri" bitsize="32" regnum="29" type="uint32" group="general"/>
    <reg name="faultmask" bitsize="32" regnum="30" type="uint32" group="general"/>
    <reg name="control" bitsize="32" regnum="31" type="uint32" group="general"/>
  </feature>
  <feature name="org.gnu.gdb.arm.m-float">
    <reg name="fpscr" bitsize="32" regnum="32" type="uint32" group="float"/>
    <reg name="s0" bitsize="32" regnum="33" type="float" group="float"/>
    <reg name="s1" bitsize="32" regnum="34" type="float" group="float"/>
    <reg name="s2" bitsize="32" regnum="35" type="float" group="float"/>
    <reg name="s3" bitsize="32" regnum="36" type="float" group="float"/>
    <reg name="s4" bitsize="32" regnum="37" type="float" group="float"/>
    <reg name="s5" bitsize="32" regnum="38" type="float" group="float"/>
    <reg name="s6" bitsize="32" regnum="39" type="float" group="float"/>
    <reg name="s7" bitsize="32" regnum="40" type="float" group="float"/>
    <reg name="s8" bitsize="32" regnum="41" type="float" group="float"/>
    <reg name="s9" bitsize="32" regnum="42" type="float" group="float"/>
    <reg name="s10" bitsize="32" regnum="43" type="float" group="float"/>
    <reg name="s11" bitsize="32" regnum="44" type="float" group="float"/>
    <reg name="s12" bitsize="32" regnum="45" type="float" group="float"/>
    <reg name="s13" bitsize="32" regnum="46" type="float" group="float"/>
    <reg name="s14" bitsize="32" regnum="47" type="float" group="float"/>
    <reg name="s15" bitsize="32" regnum="48" type="float" group="float"/>
    <reg name="s16" bitsize="32" regnum="49" type="float" group="float"/>
    <reg name="s17" bitsize="32" regnum="50" type="float" group="float"/>
    <reg name="s18" bitsize="32" regnum="51" type="float" group="float"/>
    <reg name="s19" bitsize="32" regnum="52" type="float" group="float"/>
    <reg name="s20" bitsize="32" regnum="53" type="float" group="float"/>
    <reg name="s21" bitsize="32" regnum="54" type="float" group="float"/>
    <reg name="s22" bitsize="32" regnum="55" type="float" group="float"/>
    <reg name="s23" bitsize="32" regnum="56" type="float" group="float"/>
    <reg name="s24" bitsize="32" regnum="57" type="float" group="float"/>
    <reg name="s25" bitsize="32" regnum="58" type="float" group="float"/>
    <reg name="s26" bitsize="32" regnum="59" type="float" group="float"/>
    <reg name="s27" bitsize="32" regnum="60" type="float" group="float"/>
    <reg name="s28" bitsize="32" regnum="61" type="float" group="float"/>
    <reg name="s29" bitsize="32" regnum="62" type="float" group="float"/>
    <reg name="s30" bitsize="32" regnum="63" type="float" group="float"/>
    <reg name="s31" bitsize="32" regnum="64" type="float" group="float"/>
    <reg name="d0" bitsize="64" regnum="65" type="ieee_double" group="float"/>
    <reg name="d1" bitsize="64" regnum="66" type="ieee_double" group="float"/>
    <reg name="d2" bitsize="64" regnum="67" type="ieee_double" group="float"/>
    <reg name="d3" bitsize="64" regnum="68" type="ieee_double" group="float"/>
    <reg name="d4" bitsize="64" regnum="69" type="ieee_double" group="float"/>
    <reg name="d5" bitsize="64" regnum="70" type="ieee_double" group="float"/>
    <reg name="d6" bitsize="64" regnum="71" type="ieee_double" group="float"/>
    <reg name="d7" bitsize="64" regnum="72" type="ieee_double" group="float"/>
    <reg name="d8" bitsize="64" regnum="73" type="ieee_double" group="float"/>
    <reg name="d9" bitsize="64" regnum="74" type="ieee_double" group="float"/>
    <reg name="d10" bitsize="64" regnum="75" type="ieee_double" group="float"/>
    <reg name="d11" bitsize="64" regnum="76" type="ieee_double" group="float"/>
    <reg name="d12" bitsize="64" regnum="77" type="ieee_double" group="float"/>
    <reg name="d13" bitsize="64" regnum="78" type="ieee_double" group="float"/>
    <reg name="d14" bitsize="64" regnum="79" type="ieee_double" group="float"/>
    <reg name="d15" bitsize="64" regnum="80" type="ieee_double" group="float"/>
  </feature>
</target>""", False
                else:
                    return None, False

            def readRegister(self, regnum):
                return "E01"

            # Initial r1 bytes, in little-endian order
            r1_bytes = "01000000"

            ## readRegisters only provides reg values up through xpsr (0x61000000)
            ## it doesn't send up any of the exception registers or floating point
            ## registers that the above register xml describes.
            def readRegisters(self):
                return "00000000" + self.r1_bytes + "010000000100000001000000000000008c080020a872012000000000a0790120000000008065012041ad0008a0720120692a00089e26000800000061"

            ## the J-Link accepts a register write packet with just the GPRs
            ## defined.
            def writeRegisters(self, registers_hex):
                # Check that lldb returns the full 704 hex-byte register context,
                # or the 136 hex-byte general purpose register reg ctx.
                if len(registers_hex) != 704 and len(register_hex) != 136:
                    return "E06"
                if registers_hex.startswith(
                        "0000000044332211010000000100000001000000000000008c080020a872012000000000a0790120000000008065012041ad0008a0720120692a00089e26000800000061"
                ):
                    self.r1_bytes = "44332211"
                    return "OK"
                else:
                    return "E07"

            def haltReason(self):
                return "S05"

            def qfThreadInfo(self):
                return "mdead"

            def qC(self):
                return ""

            def qSupported(self, client_supported):
                return "PacketSize=4000;qXfer:memory-map:read-;QStartNoAckMode+;hwbreak+;qXfer:features:read+"

            def QThreadSuffixSupported(self):
                return "OK"

            def QListThreadsInStopReply(self):
                return "OK"

        self.server.responder = MyResponder()
        if self.TraceOn():
            self.runCmd("log enable gdb-remote packets")
            self.addTearDownHook(
                lambda: self.runCmd("log disable gdb-remote packets"))

        self.dbg.SetDefaultArchitecture("armv7em")
        target = self.dbg.CreateTargetWithFileAndArch(None, None)

        process = self.connect(target)

        if self.TraceOn():
            interp = self.dbg.GetCommandInterpreter()
            result = lldb.SBCommandReturnObject()
            interp.HandleCommand("target list", result)
            print(result.GetOutput())

        r1_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).FindRegister("r1")
        self.assertEqual(r1_valobj.GetValueAsUnsigned(), 1)

        pc_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).FindRegister("pc")
        self.assertEqual(pc_valobj.GetValueAsUnsigned(), 0x0800269e)

        xpsr_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).FindRegister("xpsr")
        self.assertEqual(xpsr_valobj.GetValueAsUnsigned(), 0x61000000)

        msp_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).FindRegister("msp")
        err = msp_valobj.GetError()
        self.assertTrue(err.Fail(),
                        "lldb should not be able to fetch the msp register")

        val = b'\x11\x22\x33\x44'
        error = lldb.SBError()
        data = lldb.SBData()
        data.SetData(error, val, lldb.eByteOrderBig, 4)
        self.assertEqual(r1_valobj.SetData(data, error), True)
        self.assertTrue(error.Success())

        r1_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).FindRegister("r1")
        self.assertEqual(r1_valobj.GetValueAsUnsigned(), 0x11223344)
Пример #16
0
    def signal_test(self, signal, test_passing):
        """Test that we handle inferior raising signals"""
        exe = os.path.join(os.getcwd(), "a.out")

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

        # launch
        process = self.launch(target, signal)
        signo = process.GetUnixSignals().GetSignalNumberFromName(signal)

        # retrieve default signal disposition
        return_obj = lldb.SBCommandReturnObject()
        self.dbg.GetCommandInterpreter().HandleCommand("process handle %s " % signal, return_obj)
        match = re.match('NAME *PASS *STOP *NOTIFY.*(false|true) *(false|true) *(false|true)',
                return_obj.GetOutput(), re.IGNORECASE | re.DOTALL)
        if not match:
            self.fail('Unable to retrieve default signal disposition.')
        default_pass = match.group(1)
        default_stop = match.group(2)
        default_notify = match.group(3)

        # Make sure we stop at the signal
        self.set_handle(signal, "false", "true", "true")
        process.Continue()
        self.assertEqual(process.GetState(), lldb.eStateStopped)
        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
        self.assertTrue(thread.IsValid(), "Thread should be stopped due to a signal")
        self.assertTrue(thread.GetStopReasonDataCount() >= 1, "There was data in the event.")
        self.assertEqual(thread.GetStopReasonDataAtIndex(0), signo,
                "The stop signal was %s" % signal)

        # Continue until we exit.
        process.Continue()
        self.assertEqual(process.GetState(), lldb.eStateExited)
        self.assertEqual(process.GetExitStatus(), 0)

        # launch again
        process = self.launch(target, signal)

        # Make sure we do not stop at the signal. We should still get the notification.
        self.set_handle(signal, "false", "false", "true")
        self.expect("process continue", substrs=["stopped and restarted", signal])
        self.assertEqual(process.GetState(), lldb.eStateExited)
        self.assertEqual(process.GetExitStatus(), 0)

        # launch again
        process = self.launch(target, signal)

        # Make sure we do not stop at the signal, and we do not get the notification.
        self.set_handle(signal, "false", "false", "false")
        self.expect("process continue", substrs=["stopped and restarted"], matching=False)
        self.assertEqual(process.GetState(), lldb.eStateExited)
        self.assertEqual(process.GetExitStatus(), 0)

        if not test_passing:
            # reset signal handling to default
            self.set_handle(signal, default_pass, default_stop, default_notify)
            return

        # launch again
        process = self.launch(target, signal)

        # Make sure we stop at the signal
        self.set_handle(signal, "true", "true", "true")
        process.Continue()
        self.assertEqual(process.GetState(), lldb.eStateStopped)
        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
        self.assertTrue(thread.IsValid(), "Thread should be stopped due to a signal")
        self.assertTrue(thread.GetStopReasonDataCount() >= 1, "There was data in the event.")
        self.assertEqual(thread.GetStopReasonDataAtIndex(0),
                process.GetUnixSignals().GetSignalNumberFromName(signal),
                "The stop signal was %s" % signal)

        # Continue until we exit. The process should receive the signal.
        process.Continue()
        self.assertEqual(process.GetState(), lldb.eStateExited)
        self.assertEqual(process.GetExitStatus(), signo)

        # launch again
        process = self.launch(target, signal)

        # Make sure we do not stop at the signal. We should still get the notification. Process
        # should receive the signal.
        self.set_handle(signal, "true", "false", "true")
        self.expect("process continue", substrs=["stopped and restarted", signal])
        self.assertEqual(process.GetState(), lldb.eStateExited)
        self.assertEqual(process.GetExitStatus(), signo)

        # launch again
        process = self.launch(target, signal)

        # Make sure we do not stop at the signal, and we do not get the notification. Process
        # should receive the signal.
        self.set_handle(signal, "true", "false", "false")
        self.expect("process continue", substrs=["stopped and restarted"], matching=False)
        self.assertEqual(process.GetState(), lldb.eStateExited)
        self.assertEqual(process.GetExitStatus(), signo)

        # reset signal handling to default
        self.set_handle(signal, default_pass, default_stop, default_notify)
Пример #17
0
    def test(self):
        """
        Test lldb's parsing of the <architecture> tag in the target.xml register
        description packet.
        """
        class MyResponder(MockGDBServerResponder):
            def qXferRead(self, obj, annex, offset, length):
                if annex == "target.xml":
                    return """<?xml version="1.0"?>
                        <target version="1.0">
                          <architecture>i386:x86-64</architecture>
                          <feature name="org.gnu.gdb.i386.core">
    
                         <flags id="i386_eflags" size="4">
                         <field name="CF" start="0" end="0"/>
                         <field name="" start="1" end="1"/>
                         <field name="PF" start="2" end="2"/>
                         <field name="AF" start="4" end="4"/>
                         <field name="ZF" start="6" end="6"/>
                         <field name="SF" start="7" end="7"/>
                         <field name="TF" start="8" end="8"/>
                         <field name="IF" start="9" end="9"/>
                         <field name="DF" start="10" end="10"/>
                         <field name="OF" start="11" end="11"/>
                         <field name="NT" start="14" end="14"/>
                         <field name="RF" start="16" end="16"/>
                         <field name="VM" start="17" end="17"/>
                         <field name="AC" start="18" end="18"/>
                         <field name="VIF" start="19" end="19"/>
                         <field name="VIP" start="20" end="20"/>
                         <field name="ID" start="21" end="21"/>
                         </flags>
    
                            <reg name="rax" bitsize="64" regnum="0" type="int" group="general"/>
                            <reg name="rbx" bitsize="64" regnum="1" type="int" group="general"/>
                            <reg name="rcx" bitsize="64" regnum="2" type="int" group="general"/>
                            <reg name="rdx" bitsize="64" regnum="3" type="int" group="general"/>
                            <reg name="rsi" bitsize="64" regnum="4" type="int" group="general"/>
                            <reg name="rdi" bitsize="64" regnum="5" type="int" group="general"/>
                            <reg name="rbp" bitsize="64" regnum="6" type="data_ptr" group="general"/>
                            <reg name="rsp" bitsize="64" regnum="7" type="data_ptr" group="general"/>
                            <reg name="r8" bitsize="64"  regnum="8" type="int" group="general"/>
                            <reg name="r9" bitsize="64"  regnum="9" type="int" group="general"/>
                            <reg name="r10" bitsize="64" regnum="10" type="int" group="general"/>
                            <reg name="r11" bitsize="64" regnum="11" type="int" group="general"/>
                            <reg name="r12" bitsize="64" regnum="12" type="int" group="general"/>
                            <reg name="r13" bitsize="64" regnum="13" type="int" group="general"/>
                            <reg name="r14" bitsize="64" regnum="14" type="int" group="general"/>
                            <reg name="r15" bitsize="64" regnum="15" type="int" group="general"/>
                            <reg name="rip" bitsize="64" regnum="16" type="code_ptr" group="general"/>
                            <reg name="eflags" bitsize="32" regnum="17" type="i386_eflags" group="general"/>
    
                            <reg name="cs" bitsize="32" regnum="18" type="int" group="general"/>
                            <reg name="ss" bitsize="32" regnum="19" type="int" group="general"/>
                            <reg name="ds" bitsize="32" regnum="20" type="int" group="general"/>
                            <reg name="es" bitsize="32" regnum="21" type="int" group="general"/>
                            <reg name="fs" bitsize="32" regnum="22" type="int" group="general"/>
                            <reg name="gs" bitsize="32" regnum="23" type="int" group="general"/>
    
                            <reg name="st0" bitsize="80" regnum="24" type="i387_ext" group="float"/>
                            <reg name="st1" bitsize="80" regnum="25" type="i387_ext" group="float"/>
                            <reg name="st2" bitsize="80" regnum="26" type="i387_ext" group="float"/>
                            <reg name="st3" bitsize="80" regnum="27" type="i387_ext" group="float"/>
                            <reg name="st4" bitsize="80" regnum="28" type="i387_ext" group="float"/>
                            <reg name="st5" bitsize="80" regnum="29" type="i387_ext" group="float"/>
                            <reg name="st6" bitsize="80" regnum="30" type="i387_ext" group="float"/>
                            <reg name="st7" bitsize="80" regnum="31" type="i387_ext" group="float"/>
    
                            <reg name="fctrl" bitsize="32" regnum="32" type="int" group="float"/>
                            <reg name="fstat" bitsize="32" regnum="33" type="int" group="float"/>
                            <reg name="ftag"  bitsize="32" regnum="34" type="int" group="float"/>
                            <reg name="fiseg" bitsize="32" regnum="35" type="int" group="float"/>
                            <reg name="fioff" bitsize="32" regnum="36" type="int" group="float"/>
                            <reg name="foseg" bitsize="32" regnum="37" type="int" group="float"/>
                            <reg name="fooff" bitsize="32" regnum="38" type="int" group="float"/>
                            <reg name="fop"   bitsize="32" regnum="39" type="int" group="float"/>
                          </feature>
                        </target>""", False
                else:
                    return None, False

            def qC(self):
                return "QC1"

            def haltReason(self):
                return "T05thread:00000001;06:9038d60f00700000;07:98b4062680ffffff;10:c0d7bf1b80ffffff;"

            def readRegister(self, register):
                regs = {
                    0x0: "00b0060000610000",
                    0xa: "68fe471c80ffffff",
                    0xc: "60574a1c80ffffff",
                    0xd: "18f3042680ffffff",
                    0xe: "be8a4d7142000000",
                    0xf: "50df471c80ffffff",
                    0x10: "c0d7bf1b80ffffff"
                }
                if register in regs:
                    return regs[register]
                else:
                    return "0000000000000000"

        self.server.responder = MyResponder()
        interp = self.dbg.GetCommandInterpreter()
        result = lldb.SBCommandReturnObject()
        if self.TraceOn():
            self.runCmd("log enable gdb-remote packets")
            self.addTearDownHook(
                lambda: self.runCmd("log disable gdb-remote packets"))

        target = self.dbg.CreateTarget('')
        self.assertEqual('', target.GetTriple())
        process = self.connect(target)
        if self.TraceOn():
            interp.HandleCommand("target list", result)
            print(result.GetOutput())
        self.assertTrue(
            target.GetTriple().startswith('x86_64-unknown-unknown'))
Пример #18
0
def wait_for_hook_stop():
    while True:
        res = lldb.SBCommandReturnObject()
        lldb.debugger.GetCommandInterpreter().HandleCommand("target stop-hook add -o \"HandleHookStopOnTarget\"", res)
        if res.Succeeded() == True: return
        time.sleep(0.05)
 def test_SBCommandReturnObject(self):
     """SBCommandReturnObject object is valid after default construction."""
     obj = lldb.SBCommandReturnObject()
     if self.TraceOn():
         print obj
     self.assertTrue(obj)
Пример #20
0
def dbgcall(command):
    res = lldb.SBCommandReturnObject()
    lldb.debugger.GetCommandInterpreter().HandleCommand(command, res)
    return res.GetOutput()
Пример #21
0
 def __init__(self):
     self.ci = lldb.debugger.GetCommandInterpreter()
     self.res = lldb.SBCommandReturnObject()
Пример #22
0
    def test(self):
        """
        Test lldb's parsing of the <architecture> tag in the target.xml register
        description packet.
        """
        class MyResponder(MockGDBServerResponder):
            def qXferRead(self, obj, annex, offset, length):
                if annex == "target.xml":
                    return """<?xml version="1.0"?><!DOCTYPE target SYSTEM "gdb-target.dtd"><target><architecture>i386:x86-64</architecture><xi:include href="i386-64bit.xml"/></target>""", False

                if annex == "i386-64bit.xml":
                    return """<?xml version="1.0"?>
<!-- Copyright (C) 2010-2017 Free Software Foundation, Inc.

     Copying and distribution of this file, with or without modification,
     are permitted in any medium without royalty provided the copyright
     notice and this notice are preserved.  -->

<!-- I386 64bit -->

<!DOCTYPE target SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.i386.64bit">
  <xi:include href="i386-64bit-core.xml"/>
  <xi:include href="i386-64bit-sse.xml"/>
</feature>""", False

                if annex == "i386-64bit-core.xml":
                    return """<?xml version="1.0"?>
<!-- Copyright (C) 2010-2015 Free Software Foundation, Inc.

     Copying and distribution of this file, with or without modification,
     are permitted in any medium without royalty provided the copyright
     notice and this notice are preserved.  -->

<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.i386.core">
  <flags id="i386_eflags" size="4">
    <field name="CF" start="0" end="0"/>
    <field name="" start="1" end="1"/>
    <field name="PF" start="2" end="2"/>
    <field name="AF" start="4" end="4"/>
    <field name="ZF" start="6" end="6"/>
    <field name="SF" start="7" end="7"/>
    <field name="TF" start="8" end="8"/>
    <field name="IF" start="9" end="9"/>
    <field name="DF" start="10" end="10"/>
    <field name="OF" start="11" end="11"/>
    <field name="NT" start="14" end="14"/>
    <field name="RF" start="16" end="16"/>
    <field name="VM" start="17" end="17"/>
    <field name="AC" start="18" end="18"/>
    <field name="VIF" start="19" end="19"/>
    <field name="VIP" start="20" end="20"/>
    <field name="ID" start="21" end="21"/>
  </flags>

  <reg name="rax" bitsize="64" type="int64"/>
  <reg name="rbx" bitsize="64" type="int64"/>
  <reg name="rcx" bitsize="64" type="int64"/>
  <reg name="rdx" bitsize="64" type="int64"/>
  <reg name="rsi" bitsize="64" type="int64"/>
  <reg name="rdi" bitsize="64" type="int64"/>
  <reg name="rbp" bitsize="64" type="data_ptr"/>
  <reg name="rsp" bitsize="64" type="data_ptr"/>
  <reg name="r8" bitsize="64" type="int64"/>
  <reg name="r9" bitsize="64" type="int64"/>
  <reg name="r10" bitsize="64" type="int64"/>
  <reg name="r11" bitsize="64" type="int64"/>
  <reg name="r12" bitsize="64" type="int64"/>
  <reg name="r13" bitsize="64" type="int64"/>
  <reg name="r14" bitsize="64" type="int64"/>
  <reg name="r15" bitsize="64" type="int64"/>

  <reg name="rip" bitsize="64" type="code_ptr"/>
  <reg name="eflags" bitsize="32" type="i386_eflags"/>
  <reg name="cs" bitsize="32" type="int32"/>
  <reg name="ss" bitsize="32" type="int32"/>
  <reg name="ds" bitsize="32" type="int32"/>
  <reg name="es" bitsize="32" type="int32"/>
  <reg name="fs" bitsize="32" type="int32"/>
  <reg name="gs" bitsize="32" type="int32"/>

  <reg name="st0" bitsize="80" type="i387_ext"/>
  <reg name="st1" bitsize="80" type="i387_ext"/>
  <reg name="st2" bitsize="80" type="i387_ext"/>
  <reg name="st3" bitsize="80" type="i387_ext"/>
  <reg name="st4" bitsize="80" type="i387_ext"/>
  <reg name="st5" bitsize="80" type="i387_ext"/>
  <reg name="st6" bitsize="80" type="i387_ext"/>
  <reg name="st7" bitsize="80" type="i387_ext"/>

  <reg name="fctrl" bitsize="32" type="int" group="float"/>
  <reg name="fstat" bitsize="32" type="int" group="float"/>
  <reg name="ftag" bitsize="32" type="int" group="float"/>
  <reg name="fiseg" bitsize="32" type="int" group="float"/>
  <reg name="fioff" bitsize="32" type="int" group="float"/>
  <reg name="foseg" bitsize="32" type="int" group="float"/>
  <reg name="fooff" bitsize="32" type="int" group="float"/>
  <reg name="fop" bitsize="32" type="int" group="float"/>
</feature>""", False

                if annex == "i386-64bit-sse.xml":
                    return """<?xml version="1.0"?>
<!-- Copyright (C) 2010-2017 Free Software Foundation, Inc.

     Copying and distribution of this file, with or without modification,
     are permitted in any medium without royalty provided the copyright
     notice and this notice are preserved.  -->

<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.i386.64bit.sse">
  <vector id="v4f" type="ieee_single" count="4"/>
  <vector id="v2d" type="ieee_double" count="2"/>
  <vector id="v16i8" type="int8" count="16"/>
  <vector id="v8i16" type="int16" count="8"/>
  <vector id="v4i32" type="int32" count="4"/>
  <vector id="v2i64" type="int64" count="2"/>
  <union id="vec128">
    <field name="v4_float" type="v4f"/>
    <field name="v2_double" type="v2d"/>
    <field name="v16_int8" type="v16i8"/>
    <field name="v8_int16" type="v8i16"/>
    <field name="v4_int32" type="v4i32"/>
    <field name="v2_int64" type="v2i64"/>
    <field name="uint128" type="uint128"/>
  </union>
  <flags id="i386_mxcsr" size="4">
    <field name="IE" start="0" end="0"/>
    <field name="DE" start="1" end="1"/>
    <field name="ZE" start="2" end="2"/>
    <field name="OE" start="3" end="3"/>
    <field name="UE" start="4" end="4"/>
    <field name="PE" start="5" end="5"/>
    <field name="DAZ" start="6" end="6"/>
    <field name="IM" start="7" end="7"/>
    <field name="DM" start="8" end="8"/>
    <field name="ZM" start="9" end="9"/>
    <field name="OM" start="10" end="10"/>
    <field name="UM" start="11" end="11"/>
    <field name="PM" start="12" end="12"/>
    <field name="FZ" start="15" end="15"/>
  </flags>

  <reg name="xmm0" bitsize="128" type="vec128" regnum="40"/>
  <reg name="xmm1" bitsize="128" type="vec128"/>
  <reg name="xmm2" bitsize="128" type="vec128"/>
  <reg name="xmm3" bitsize="128" type="vec128"/>
  <reg name="xmm4" bitsize="128" type="vec128"/>
  <reg name="xmm5" bitsize="128" type="vec128"/>
  <reg name="xmm6" bitsize="128" type="vec128"/>
  <reg name="xmm7" bitsize="128" type="vec128"/>
  <reg name="xmm8" bitsize="128" type="vec128"/>
  <reg name="xmm9" bitsize="128" type="vec128"/>
  <reg name="xmm10" bitsize="128" type="vec128"/>
  <reg name="xmm11" bitsize="128" type="vec128"/>
  <reg name="xmm12" bitsize="128" type="vec128"/>
  <reg name="xmm13" bitsize="128" type="vec128"/>
  <reg name="xmm14" bitsize="128" type="vec128"/>
  <reg name="xmm15" bitsize="128" type="vec128"/>

  <reg name="mxcsr" bitsize="32" type="i386_mxcsr" group="vector"/>
</feature>""", False

                return None, False

            def readRegister(self, regnum):
                return ""

            def readRegisters(self):
                return "0600000000000000c0b7c00080fffffff021c60080ffffff1a00000000000000020000000000000078b7c00080ffffff203f8ca090ffffff103f8ca090ffffff3025990a80ffffff809698000000000070009f0a80ffffff020000000000000000eae10080ffffff00000000000000001822d74f1a00000078b7c00080ffffff0e12410080ffff004602000008000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000"

            def haltReason(self):
                return "T02thread:dead;threads:dead;"

            def qfThreadInfo(self):
                return "mdead"

            def qC(self):
                return ""

            def qSupported(self, client_supported):
                return "PacketSize=4000;qXfer:features:read+"

            def QThreadSuffixSupported(self):
                return "OK"

            def QListThreadsInStopReply(self):
                return "OK"

        self.server.responder = MyResponder()
        if self.TraceOn():
            self.runCmd("log enable gdb-remote packets")
            self.addTearDownHook(
                lambda: self.runCmd("log disable gdb-remote packets"))

        target = self.dbg.CreateTargetWithFileAndArch(None, None)

        process = self.connect(target)

        if self.TraceOn():
            interp = self.dbg.GetCommandInterpreter()
            result = lldb.SBCommandReturnObject()
            interp.HandleCommand("target list", result)
            print(result.GetOutput())

        rip_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).FindRegister("rip")
        self.assertEqual(rip_valobj.GetValueAsUnsigned(), 0x00ffff800041120e)

        r15_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).FindRegister("r15")
        self.assertEqual(r15_valobj.GetValueAsUnsigned(), 0xffffff8000c0b778)

        mxcsr_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).FindRegister("mxcsr")
        self.assertEqual(mxcsr_valobj.GetValueAsUnsigned(), 0x00001f80)

        gpr_reg_set_name = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).GetRegisters().GetValueAtIndex(0).GetName()
        self.assertEqual(gpr_reg_set_name, "general")

        float_reg_set_name = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).GetRegisters().GetValueAtIndex(1).GetName()
        self.assertEqual(float_reg_set_name, "float")

        vector_reg_set_name = process.GetThreadAtIndex(0).GetFrameAtIndex(
            0).GetRegisters().GetValueAtIndex(2).GetName()
        self.assertEqual(vector_reg_set_name, "vector")

        if self.TraceOn():
            print("rip is 0x%x" % rip_valobj.GetValueAsUnsigned())
            print("r15 is 0x%x" % r15_valobj.GetValueAsUnsigned())
            print("mxcsr is 0x%x" % mxcsr_valobj.GetValueAsUnsigned())
Пример #23
0
def image_lookup_addr(addr):
    res = lldb.SBCommandReturnObject()
    lldb.debugger.GetCommandInterpreter().HandleCommand(
        "image lookup --address 0x%x" % addr, res)
    return res.GetOutput()
Пример #24
0
 def foo(cmd):
     ret = lldb.SBCommandReturnObject()
     self.driver.getCommandInterpreter().HandleCommand(cmd, ret)
Пример #25
0
    def test_get_objc_dynamic_vals(self):
        """Test fetching ObjC dynamic values."""
        if self.getArchitecture() == 'i386':
            # rdar://problem/9946499
            self.skipTest("Dynamic types for ObjC V1 runtime not implemented")

        self.build()
        exe = self.getBuildArtifact("a.out")

        # Create a target from the debugger.

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Set up our breakpoints:

        handle_SourceBase_bkpt = target.BreakpointCreateByLocation(
            self.source_name, self.handle_SourceBase)
        self.assertTrue(
            handle_SourceBase_bkpt
            and handle_SourceBase_bkpt.GetNumLocations() == 1,
            VALID_BREAKPOINT)

        main_before_setProperty_bkpt = target.BreakpointCreateByLocation(
            self.source_name, self.main_before_setProperty_line)
        self.assertTrue(
            main_before_setProperty_bkpt
            and main_before_setProperty_bkpt.GetNumLocations() == 1,
            VALID_BREAKPOINT)

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

        self.assertTrue(process.GetState() == lldb.eStateStopped,
                        PROCESS_STOPPED)

        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, main_before_setProperty_bkpt)
        self.assertTrue(len(threads) == 1)
        thread = threads[0]

        #
        #  At this point, myObserver has a Source pointer that is actually a KVO swizzled SourceDerived
        #  make sure we can get that properly:

        frame = thread.GetFrameAtIndex(0)
        myObserver = frame.FindVariable('myObserver',
                                        lldb.eDynamicCanRunTarget)
        self.assertTrue(myObserver)
        myObserver_source = myObserver.GetChildMemberWithName(
            '_source', lldb.eDynamicCanRunTarget)
        self.examine_SourceDerived_ptr(myObserver_source)

        #
        # Make sure a static value can be correctly turned into a dynamic
        # value.

        frame = thread.GetFrameAtIndex(0)
        myObserver_static = frame.FindVariable('myObserver',
                                               lldb.eNoDynamicValues)
        self.assertTrue(myObserver_static)
        myObserver = myObserver_static.GetDynamicValue(
            lldb.eDynamicCanRunTarget)
        myObserver_source = myObserver.GetChildMemberWithName(
            '_source', lldb.eDynamicCanRunTarget)
        self.examine_SourceDerived_ptr(myObserver_source)

        # The "frame var" code uses another path to get into children, so let's
        # make sure that works as well:

        result = lldb.SBCommandReturnObject()

        self.expect('frame var -d run-target myObserver->_source',
                    'frame var finds its way into a child member',
                    patterns=['\(SourceDerived \*\)'])

        # check that our ObjC GetISA() does a good job at hiding KVO swizzled
        # classes

        self.expect('frame var -d run-target myObserver->_source -T',
                    'the KVO-ed class is hidden',
                    substrs=['SourceDerived'])

        self.expect('frame var -d run-target myObserver->_source -T',
                    'the KVO-ed class is hidden',
                    matching=False,
                    substrs=['NSKVONotify'])

        # This test is not entirely related to the main thrust of this test case, but since we're here,
        # try stepping into setProperty, and make sure we get into the version
        # in Source:

        thread.StepInto()

        threads = lldbutil.get_stopped_threads(process,
                                               lldb.eStopReasonPlanComplete)
        self.assertTrue(len(threads) == 1)
        line_entry = threads[0].GetFrameAtIndex(0).GetLineEntry()

        self.assertEqual(line_entry.GetLine(), self.set_property_line)
        self.assertEqual(line_entry.GetFileSpec().GetFilename(),
                         self.source_name)

        # Okay, back to the main business.  Continue to the handle_SourceBase
        # and make sure we get the correct dynamic value.

        threads = lldbutil.continue_to_breakpoint(process,
                                                  handle_SourceBase_bkpt)
        self.assertTrue(len(threads) == 1)
        thread = threads[0]

        frame = thread.GetFrameAtIndex(0)

        # Get "object" using FindVariable:

        noDynamic = lldb.eNoDynamicValues
        useDynamic = lldb.eDynamicCanRunTarget

        object_static = frame.FindVariable('object', noDynamic)
        object_dynamic = frame.FindVariable('object', useDynamic)

        # Delete this object to make sure that this doesn't cause havoc with
        # the dynamic object that depends on it.
        del (object_static)

        self.examine_SourceDerived_ptr(object_dynamic)

        # Get "this" using FindValue, make sure that works too:
        object_static = frame.FindValue('object',
                                        lldb.eValueTypeVariableArgument,
                                        noDynamic)
        object_dynamic = frame.FindValue('object',
                                         lldb.eValueTypeVariableArgument,
                                         useDynamic)
        del (object_static)
        self.examine_SourceDerived_ptr(object_dynamic)

        # Get "this" using the EvaluateExpression:
        object_static = frame.EvaluateExpression('object', noDynamic)
        object_dynamic = frame.EvaluateExpression('object', useDynamic)
        del (object_static)
        self.examine_SourceDerived_ptr(object_dynamic)

        # Continue again to the handle_SourceBase and make sure we get the correct dynamic value.
        # This one looks exactly the same, but in fact this is an "un-KVO'ed" version of SourceBase, so
        # its isa pointer points to SourceBase not NSKVOSourceBase or
        # whatever...

        threads = lldbutil.continue_to_breakpoint(process,
                                                  handle_SourceBase_bkpt)
        self.assertTrue(len(threads) == 1)
        thread = threads[0]

        frame = thread.GetFrameAtIndex(0)

        # Get "object" using FindVariable:

        object_static = frame.FindVariable('object', noDynamic)
        object_dynamic = frame.FindVariable('object', useDynamic)

        # Delete this object to make sure that this doesn't cause havoc with
        # the dynamic object that depends on it.
        del (object_static)

        self.examine_SourceDerived_ptr(object_dynamic)
Пример #26
0
def delete_breakpoint(name):
    res = lldb.SBCommandReturnObject()
    getTarget().GetDebugger().GetCommandInterpreter().HandleCommand(
        'break delete %s' % name, res)
    if res.Succeeded() != True:
        print(res.GetError())
Пример #27
0
def search(debugger, command, 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"
    '''

    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 = debugger.GetSelectedTarget()
        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)


    interpreter.HandleCommand('po (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)

    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 (True)
    expr_options.SetUnwindOnError(True)
    expr_options.SetGenerateDebugInfo(True)
    expr_options.SetLanguage (lldb.eLanguageTypeObjC_plus_plus)
    expr_options.SetCoerceResultToId(True)
    # expr_options.SetAutoApplyFixIts(True)
    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)

    # debugger.HandleCommand('expression -lobjc++ -g -O -- ' + command_script)
    expr_sbvalue = frame.EvaluateExpression (command_script, expr_options)
    count = expr_sbvalue.GetNumChildren() # Actually goes up to 2^32 but this is more than enough    

    if not expr_sbvalue.error.success:
        result.SetError("\n***************************************\nerror: " + str(expr_sbvalue.error))
    else:
        if count > 1000:
            result.AppendWarning('Exceeded 1000 hits, try narrowing your search with the --condition option')
            result.AppendMessage (expr_sbvalue)
        else:
            if options.barebones:                
                for val in expr_sbvalue:
                    val_description = str(val.GetTypeName()) + ' [' + str(val.GetValue())  + ']'
                    result.AppendMessage(val_description)
            else:
                result.AppendMessage(expr_sbvalue.description)
Пример #28
0
def dump_memory(addr, size):
    res = lldb.SBCommandReturnObject()
    interpreter = getTarget().GetDebugger().GetCommandInterpreter()
    interpreter.HandleCommand('memory read %d -c %d' % (addr, size), res)
    return res.GetOutput()
Пример #29
0
    def call_function(self):
        """Test calling function that hits a signal and restarts."""
        exe_name = "a.out"
        exe = os.path.join(os.getcwd(), exe_name)

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)
        empty = lldb.SBFileSpec()
        breakpoint = target.BreakpointCreateBySourceRegex('Stop here in main.',self.main_source_spec)
        self.assertTrue(breakpoint.GetNumLocations() > 0, VALID_BREAKPOINT)

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

        self.assertTrue(process, PROCESS_IS_VALID)

        # Frame #0 should be at our breakpoint.
        threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
        
        self.assertTrue(len(threads) == 1)
        self.thread = threads[0]
        
        # Make sure the SIGCHLD behavior is pass/no-stop/no-notify:
        return_obj = lldb.SBCommandReturnObject()
        self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 0 -p 1 -n 0", return_obj)
        self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, no-stop")

        # The sigchld_no variable should be 0 at this point.
        self.sigchld_no = target.FindFirstGlobalVariable("sigchld_no")
        self.assertTrue (self.sigchld_no.IsValid(), "Got a value for sigchld_no")

        self.start_sigchld_no = self.sigchld_no.GetValueAsSigned (-1)
        self.assertTrue (self.start_sigchld_no != -1, "Got an actual value for sigchld_no")

        options = lldb.SBExpressionOptions()
        options.SetUnwindOnError(True)

        frame = self.thread.GetFrameAtIndex(0)
        # Store away the PC to check that the functions unwind to the right place after calls
        self.orig_frame_pc = frame.GetPC()

        num_sigchld = 30
        value = frame.EvaluateExpression ("call_me (%d)"%(num_sigchld), options)
        self.assertTrue (value.IsValid())
        self.assertTrue (value.GetError().Success() == True)
        self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld)

        self.check_after_call(num_sigchld)

        # Okay, now try with a breakpoint in the called code in the case where
        # we are ignoring breakpoint hits.
        handler_bkpt = target.BreakpointCreateBySourceRegex("Got sigchld %d.", self.main_source_spec)
        self.assertTrue (handler_bkpt.GetNumLocations() > 0)
        options.SetIgnoreBreakpoints(True)
        options.SetUnwindOnError(True)

        value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options)

        self.assertTrue (value.IsValid() and value.GetError().Success() == True)
        self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld)
        self.check_after_call(num_sigchld)

        # Now set the signal to print but not stop and make sure that calling still works:
        self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 0 -p 1 -n 1", return_obj)
        self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, no-stop, notify")

        value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options)

        self.assertTrue (value.IsValid() and value.GetError().Success() == True)
        self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld)
        self.check_after_call(num_sigchld)

        # Now set this unwind on error to false, and make sure that we still complete the call:
        options.SetUnwindOnError(False)
        value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options)

        self.assertTrue (value.IsValid() and value.GetError().Success() == True)
        self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld)
        self.check_after_call(num_sigchld)

        # Okay, now set UnwindOnError to true, and then make the signal behavior to stop
        # and see that now we do stop at the signal point:
        
        self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 1 -p 1 -n 1", return_obj)
        self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, stop, notify")
        
        value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options)
        self.assertTrue (value.IsValid() and value.GetError().Success() == False)
        
        # Set signal handling back to no-stop, and continue and we should end up back in out starting frame:
        self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 0 -p 1 -n 1", return_obj)
        self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, no-stop, notify")

        error = process.Continue()
        self.assertTrue (error.Success(), "Continuing after stopping for signal succeeds.")
        
        frame = self.thread.GetFrameAtIndex(0)
        self.assertTrue (frame.GetPC() == self.orig_frame_pc, "Continuing returned to the place we started.")
Пример #30
0
    def test(self):
        """Test calling std::String member function."""
        self.build()

        exe_name = "a.out"
        exe = os.path.join(os.getcwd(), exe_name)

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        breakpoint = target.BreakpointCreateBySourceRegex(
            'stop here in main.', self.main_source_spec)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)
        self.runCmd("breakpoint list")

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

        self.assertTrue(process, PROCESS_IS_VALID)

        # Frame #0 should be on self.step_out_of_malloc.
        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, breakpoint)

        self.assertTrue(len(threads) == 1)
        thread = threads[0]

        # First set the timeout too short, and make sure we fail.
        options = lldb.SBExpressionOptions()
        options.SetTimeoutInMicroSeconds(10)
        options.SetUnwindOnError(True)

        frame = thread.GetFrameAtIndex(0)

        value = frame.EvaluateExpression("wait_a_while (50000)", options)
        self.assertTrue(value.IsValid())
        self.assertFalse(value.GetError().Success())

        # Now do the same thing with the command line command, and make sure it works too.
        interp = self.dbg.GetCommandInterpreter()

        result = lldb.SBCommandReturnObject()
        return_value = interp.HandleCommand(
            "expr -t 100 -u true -- wait_a_while(50000)", result)
        self.assertTrue(return_value == lldb.eReturnStatusFailed)

        # Okay, now do it again with long enough time outs:

        options.SetTimeoutInMicroSeconds(1000000)
        value = frame.EvaluateExpression("wait_a_while (1000)", options)
        self.assertTrue(value.IsValid())
        self.assertTrue(value.GetError().Success() == True)

        # Now do the same thingwith the command line command, and make sure it works too.
        interp = self.dbg.GetCommandInterpreter()

        result = lldb.SBCommandReturnObject()
        return_value = interp.HandleCommand(
            "expr -t 1000000 -u true -- wait_a_while(1000)", result)
        self.assertTrue(return_value == lldb.eReturnStatusSuccessFinishResult)

        # Finally set the one thread timeout and make sure that doesn't change things much:

        options.SetTimeoutInMicroSeconds(1000000)
        options.SetOneThreadTimeoutInMicroSeconds(500000)
        value = frame.EvaluateExpression("wait_a_while (1000)", options)
        self.assertTrue(value.IsValid())
        self.assertTrue(value.GetError().Success() == True)