[Lldb-commits] [lldb] r186127 - Added a memory.py module that contains a 'memfind' command which allows you to search memory for a byte pattern.

Greg Clayton gclayton at apple.com
Thu Jul 11 15:38:00 PDT 2013


Author: gclayton
Date: Thu Jul 11 17:38:00 2013
New Revision: 186127

URL: http://llvm.org/viewvc/llvm-project?rev=186127&view=rev
Log:
Added a memory.py module that contains a 'memfind' command which allows you to search memory for a byte pattern.


Added:
    lldb/trunk/examples/python/memory.py   (with props)

Added: lldb/trunk/examples/python/memory.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/python/memory.py?rev=186127&view=auto
==============================================================================
--- lldb/trunk/examples/python/memory.py (added)
+++ lldb/trunk/examples/python/memory.py Thu Jul 11 17:38:00 2013
@@ -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'

Propchange: lldb/trunk/examples/python/memory.py
------------------------------------------------------------------------------
    svn:executable = *





More information about the lldb-commits mailing list