diff options
Diffstat (limited to 'examples/python/memory.py')
| -rwxr-xr-x | examples/python/memory.py | 181 | 
1 files changed, 181 insertions, 0 deletions
diff --git a/examples/python/memory.py b/examples/python/memory.py new file mode 100755 index 000000000000..ae78e24e2e29 --- /dev/null +++ b/examples/python/memory.py @@ -0,0 +1,181 @@ +#!/usr/bin/python + +#---------------------------------------------------------------------- +# Be sure to add the python path that points to the LLDB shared library. +# +# # To use this in the embedded python interpreter using "lldb" just +# import it with the full path using the "command script import"  +# command +#   (lldb) command script import /path/to/cmdtemplate.py +#---------------------------------------------------------------------- + +import commands +import platform +import os +import re +import sys + +try:  +    # Just try for LLDB in case PYTHONPATH is already correctly setup +    import lldb +except ImportError: +    lldb_python_dirs = list() +    # lldb is not in the PYTHONPATH, try some defaults for the current platform +    platform_system = platform.system() +    if platform_system == 'Darwin': +        # On Darwin, try the currently selected Xcode directory +        xcode_dir = commands.getoutput("xcode-select --print-path") +        if xcode_dir: +            lldb_python_dirs.append(os.path.realpath(xcode_dir + '/../SharedFrameworks/LLDB.framework/Resources/Python')) +            lldb_python_dirs.append(xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python') +        lldb_python_dirs.append('/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python') +    success = False +    for lldb_python_dir in lldb_python_dirs: +        if os.path.exists(lldb_python_dir): +            if not (sys.path.__contains__(lldb_python_dir)): +                sys.path.append(lldb_python_dir) +                try:  +                    import lldb +                except ImportError: +                    pass +                else: +                    print 'imported lldb from: "%s"' % (lldb_python_dir) +                    success = True +                    break +    if not success: +        print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly" +        sys.exit(1) + +import commands +import optparse +import shlex +import string +import struct +import time + +def append_data_callback(option, opt_str, value, parser): +    if opt_str == "--uint8": +        int8 = int(value, 0) +        parser.values.data += struct.pack('1B',int8) +    if opt_str == "--uint16": +        int16 = int(value, 0) +        parser.values.data += struct.pack('1H',int16) +    if opt_str == "--uint32": +        int32 = int(value, 0) +        parser.values.data += struct.pack('1I',int32) +    if opt_str == "--uint64": +        int64 = int(value, 0) +        parser.values.data += struct.pack('1Q',int64) +    if opt_str == "--int8": +        int8 = int(value, 0) +        parser.values.data += struct.pack('1b',int8) +    if opt_str == "--int16": +        int16 = int(value, 0) +        parser.values.data += struct.pack('1h',int16) +    if opt_str == "--int32": +        int32 = int(value, 0) +        parser.values.data += struct.pack('1i',int32) +    if opt_str == "--int64": +        int64 = int(value, 0) +        parser.values.data += struct.pack('1q',int64) + +def create_memfind_options(): +    usage = "usage: %prog [options] STARTADDR [ENDADDR]" +    description='''This command can find data in a specified address range.  +Options are used to specify the data that is to be looked for and the options +can be specified multiple times to look for longer streams of data. +''' +    parser = optparse.OptionParser(description=description, prog='memfind',usage=usage) +    parser.add_option('-s', '--size', type='int', metavar='BYTESIZE', dest='size', help='Specify the byte size to search.', default=0) +    parser.add_option('--int8', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 8 bit signed integer value to search for in memory.', default='') +    parser.add_option('--int16', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 16 bit signed integer value to search for in memory.', default='') +    parser.add_option('--int32', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 32 bit signed integer value to search for in memory.', default='') +    parser.add_option('--int64', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 64 bit signed integer value to search for in memory.', default='') +    parser.add_option('--uint8', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 8 bit unsigned integer value to search for in memory.', default='') +    parser.add_option('--uint16', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 16 bit unsigned integer value to search for in memory.', default='') +    parser.add_option('--uint32', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 32 bit unsigned integer value to search for in memory.', default='') +    parser.add_option('--uint64', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 64 bit unsigned integer value to search for in memory.', default='') +    return parser +     +def memfind_command (debugger, command, result, dict): +    # Use the Shell Lexer to properly parse up command options just like a  +    # shell would +    command_args = shlex.split(command) +    parser = create_memfind_options() +    (options, args) = parser.parse_args(command_args) +    # try: +    #     (options, args) = parser.parse_args(command_args) +    # except: +    #     # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit +    #     # (courtesy of OptParse dealing with argument errors by throwing SystemExit) +    #     result.SetStatus (lldb.eReturnStatusFailed) +    #     print >>result, "error: option parsing failed" # returning a string is the same as returning an error whose description is the string +    #     return +    memfind (debugger.GetSelectedTarget(), options, args, result) +     +def print_error(str, show_usage, result): +    print >>result, str +    if show_usage: +        print >>result, create_memfind_options().format_help() + +def memfind (target, options, args, result): +    num_args = len(args) +    start_addr = 0 +    if num_args == 1: +        if options.size > 0: +            print_error ("error: --size must be specified if there is no ENDADDR argument", True, result) +            return +        start_addr = int(args[0], 0) +    elif num_args == 2: +        if options.size != 0: +            print_error ("error: --size can't be specified with an ENDADDR argument", True, result) +            return +        start_addr = int(args[0], 0) +        end_addr = int(args[1], 0) +        if start_addr >= end_addr: +            print_error ("error: inavlid memory range [%#x - %#x)" % (start_addr, end_addr), True, result) +            return +        options.size = end_addr - start_addr +    else: +        print_error ("error: memfind takes 1 or 2 arguments", True, result) +        return +     +    if not options.data: +        print >>result, 'error: no data specified to search for' +        return +         +    if not target: +        print >>result, 'error: invalid target' +        return +    process = target.process +    if not process: +        print >>result, 'error: invalid process' +        return +     +    error = lldb.SBError() +    bytes = process.ReadMemory (start_addr, options.size, error) +    if error.Success(): +        num_matches = 0 +        print >>result, "Searching memory range [%#x - %#x) for" % (start_addr, end_addr), +        for byte in options.data: +            print >>result, '%2.2x' % ord(byte), +        print >>result +         +        match_index = string.find(bytes, options.data) +        while match_index != -1: +            num_matches = num_matches + 1 +            print >>result, '%#x: %#x + %u' % (start_addr + match_index, start_addr, match_index) +            match_index = string.find(bytes, options.data, match_index + 1) +             +        if num_matches == 0: +            print >>result, "error: no matches found" +    else: +        print >>result, 'error: %s' % (error.GetCString()) +         + +if __name__ == '__main__': +    print 'error: this script is designed to be used within the embedded script interpreter in LLDB' +elif getattr(lldb, 'debugger', None): +    memfind_command.__doc__ = create_memfind_options().format_help() +    lldb.debugger.HandleCommand('command script add -f memory.memfind_command memfind') +    print '"memfind" command installed, use the "--help" option for detailed help'  | 
