126 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
| #!/usr/bin/env python
 | |
| 
 | |
| """
 | |
| Run lldb disassembler on all the binaries specified by a combination of root dir
 | |
| and path pattern.
 | |
| """
 | |
| 
 | |
| import os, sys, subprocess
 | |
| import re
 | |
| from optparse import OptionParser
 | |
| 
 | |
| # The directory of this Python script as well as the lldb-disasm.py workhorse.
 | |
| scriptPath = None
 | |
| 
 | |
| # The root directory for the SDK symbols.
 | |
| root_dir = None
 | |
| 
 | |
| # The regular expression pattern to match the desired pathname to the binaries.
 | |
| path_pattern = None
 | |
| 
 | |
| # And the re-compiled regular expression object.
 | |
| path_regexp = None
 | |
| 
 | |
| # If specified, number of symbols to disassemble for each qualified binary.
 | |
| num_symbols = -1
 | |
| 
 | |
| # Command template of the invocation of lldb disassembler.
 | |
| template = '%s/lldb-disasm.py -C "platform select remote-ios" -o "-n" -q -e %s -n %s'
 | |
| 
 | |
| # Regular expression for detecting file output for Mach-o binary.
 | |
| mach_o = re.compile('\sMach-O.+binary')
 | |
| def isbinary(path):
 | |
|     file_output = subprocess.Popen(["file", path], 
 | |
|                                    stdout=subprocess.PIPE).stdout.read()
 | |
|     return (mach_o.search(file_output) is not None)
 | |
| 
 | |
| def walk_and_invoke(sdk_root, path_regexp, suffix, num_symbols):
 | |
|     """Look for matched file and invoke lldb disassembly on it."""
 | |
|     global scriptPath
 | |
| 
 | |
|     for root, dirs, files in os.walk(sdk_root, topdown=False):
 | |
|         for name in files:
 | |
|             path = os.path.join(root, name)
 | |
| 
 | |
|             # We're not interested in .h file.
 | |
|             if name.endswith(".h"):
 | |
|                 continue
 | |
|             # Neither a symbolically linked file.
 | |
|             if os.path.islink(path):
 | |
|                 continue
 | |
| 
 | |
|             # We'll be pattern matching based on the path relative to the SDK root.
 | |
|             replaced_path = path.replace(root_dir, "", 1)
 | |
|             # Check regular expression match for the replaced path.
 | |
|             if not path_regexp.search(replaced_path):
 | |
|                 continue
 | |
|             # If a suffix is specified, check it, too.
 | |
|             if suffix and not name.endswith(suffix):
 | |
|                 continue
 | |
|             if not isbinary(path):
 | |
|                 continue
 | |
| 
 | |
|             command = template % (scriptPath, path, num_symbols if num_symbols > 0 else 1000)
 | |
|             print "Running %s" % (command)
 | |
|             os.system(command)
 | |
| 
 | |
| def main():
 | |
|     """Read the root dir and the path spec, invoke lldb-disasm.py on the file."""
 | |
|     global scriptPath
 | |
|     global root_dir
 | |
|     global path_pattern
 | |
|     global path_regexp
 | |
|     global num_symbols
 | |
| 
 | |
|     scriptPath = sys.path[0]
 | |
| 
 | |
|     parser = OptionParser(usage="""\
 | |
| Run lldb disassembler on all the binaries specified by a combination of root dir
 | |
| and path pattern.
 | |
| """)
 | |
|     parser.add_option('-r', '--root-dir',
 | |
|                       type='string', action='store',
 | |
|                       dest='root_dir',
 | |
|                       help='Mandatory: the root directory for the SDK symbols.')
 | |
|     parser.add_option('-p', '--path-pattern',
 | |
|                       type='string', action='store',
 | |
|                       dest='path_pattern',
 | |
|                       help='Mandatory: regular expression pattern for the desired binaries.')
 | |
|     parser.add_option('-s', '--suffix',
 | |
|                       type='string', action='store', default=None,
 | |
|                       dest='suffix',
 | |
|                       help='Specify the suffix of the binaries to look for.')
 | |
|     parser.add_option('-n', '--num-symbols',
 | |
|                       type='int', action='store', default=-1,
 | |
|                       dest='num_symbols',
 | |
|                       help="""The number of symbols to disassemble, if specified.""")
 | |
| 
 | |
| 
 | |
|     opts, args = parser.parse_args()
 | |
|     if not opts.root_dir or not opts.path_pattern:
 | |
|         parser.print_help()
 | |
|         sys.exit(1)
 | |
| 
 | |
|     # Sanity check the root directory.
 | |
|     root_dir = opts.root_dir
 | |
|     root_dir = os.path.abspath(root_dir)
 | |
|     if not os.path.isdir(root_dir):
 | |
|         parser.print_help()
 | |
|         sys.exit(1)
 | |
| 
 | |
|     path_pattern = opts.path_pattern
 | |
|     path_regexp = re.compile(path_pattern)
 | |
|     suffix = opts.suffix
 | |
|     num_symbols = opts.num_symbols
 | |
| 
 | |
|     print "Root directory for SDK symbols:", root_dir
 | |
|     print "Regular expression for the binaries:", path_pattern
 | |
|     print "Suffix of the binaries to look for:", suffix
 | |
|     print "num of symbols to disassemble:", num_symbols
 | |
| 
 | |
|     walk_and_invoke(root_dir, path_regexp, suffix, num_symbols)
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     main()
 |