run-dis.py
4.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/env python
"""
Run lldb disassembler on all the binaries specified by a combination of root dir
and path pattern.
"""
from __future__ import print_function
import os
import sys
import 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()