3 #----------------------------------------------------------------------
4 # Be sure to add the python path that points to the LLDB shared library.
6 # # To use this in the embedded python interpreter using "lldb" just
7 # import it with the full path using the "command script import"
9 # (lldb) command script import /path/to/cmdtemplate.py
10 #----------------------------------------------------------------------
12 from __future__
import print_function
21 # Just try for LLDB in case PYTHONPATH is already correctly setup
24 lldb_python_dirs
= list()
25 # lldb is not in the PYTHONPATH, try some defaults for the current platform
26 platform_system
= platform
.system()
27 if platform_system
== 'Darwin':
28 # On Darwin, try the currently selected Xcode directory
29 xcode_dir
= subprocess
.check_output("xcode-select --print-path", shell
=True)
31 lldb_python_dirs
.append(
34 '/../SharedFrameworks/LLDB.framework/Resources/Python'))
35 lldb_python_dirs
.append(
36 xcode_dir
+ '/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
37 lldb_python_dirs
.append(
38 '/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
40 for lldb_python_dir
in lldb_python_dirs
:
41 if os
.path
.exists(lldb_python_dir
):
42 if not (sys
.path
.__contains
__(lldb_python_dir
)):
43 sys
.path
.append(lldb_python_dir
)
49 print('imported lldb from: "%s"' % (lldb_python_dir
))
53 print("error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly")
63 def append_data_callback(option
, opt_str
, value
, parser
):
64 if opt_str
== "--uint8":
66 parser
.values
.data
+= struct
.pack('1B', int8
)
67 if opt_str
== "--uint16":
69 parser
.values
.data
+= struct
.pack('1H', int16
)
70 if opt_str
== "--uint32":
72 parser
.values
.data
+= struct
.pack('1I', int32
)
73 if opt_str
== "--uint64":
75 parser
.values
.data
+= struct
.pack('1Q', int64
)
76 if opt_str
== "--int8":
78 parser
.values
.data
+= struct
.pack('1b', int8
)
79 if opt_str
== "--int16":
81 parser
.values
.data
+= struct
.pack('1h', int16
)
82 if opt_str
== "--int32":
84 parser
.values
.data
+= struct
.pack('1i', int32
)
85 if opt_str
== "--int64":
87 parser
.values
.data
+= struct
.pack('1q', int64
)
90 def create_memfind_options():
91 usage
= "usage: %prog [options] STARTADDR [ENDADDR]"
92 description
= '''This command can find data in a specified address range.
93 Options are used to specify the data that is to be looked for and the options
94 can be specified multiple times to look for longer streams of data.
96 parser
= optparse
.OptionParser(
97 description
=description
,
106 help='Specify the byte size to search.',
111 callback
=append_data_callback
,
115 help='Specify a 8 bit signed integer value to search for in memory.',
120 callback
=append_data_callback
,
124 help='Specify a 16 bit signed integer value to search for in memory.',
129 callback
=append_data_callback
,
133 help='Specify a 32 bit signed integer value to search for in memory.',
138 callback
=append_data_callback
,
142 help='Specify a 64 bit signed integer value to search for in memory.',
147 callback
=append_data_callback
,
151 help='Specify a 8 bit unsigned integer value to search for in memory.',
156 callback
=append_data_callback
,
160 help='Specify a 16 bit unsigned integer value to search for in memory.',
165 callback
=append_data_callback
,
169 help='Specify a 32 bit unsigned integer value to search for in memory.',
174 callback
=append_data_callback
,
178 help='Specify a 64 bit unsigned integer value to search for in memory.',
183 def memfind_command(debugger
, command
, result
, dict):
184 # Use the Shell Lexer to properly parse up command options just like a
186 command_args
= shlex
.split(command
)
187 parser
= create_memfind_options()
188 (options
, args
) = parser
.parse_args(command_args
)
190 # (options, args) = parser.parse_args(command_args)
192 # # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
193 # # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
194 # result.SetStatus (lldb.eReturnStatusFailed)
195 # print >>result, "error: option parsing failed" # returning a string is the same as returning an error whose description is the string
197 memfind(debugger
.GetSelectedTarget(), options
, args
, result
)
200 def print_error(str, show_usage
, result
):
201 print(str, file=result
)
203 print(create_memfind_options().format_help(), file=result
)
206 def memfind(target
, options
, args
, result
):
212 "error: --size must be specified if there is no ENDADDR argument",
216 start_addr
= int(args
[0], 0)
218 if options
.size
!= 0:
220 "error: --size can't be specified with an ENDADDR argument",
224 start_addr
= int(args
[0], 0)
225 end_addr
= int(args
[1], 0)
226 if start_addr
>= end_addr
:
228 "error: inavlid memory range [%#x - %#x)" %
229 (start_addr
, end_addr
), True, result
)
231 options
.size
= end_addr
- start_addr
233 print_error("error: memfind takes 1 or 2 arguments", True, result
)
237 print('error: no data specified to search for', file=result
)
241 print('error: invalid target', file=result
)
243 process
= target
.process
245 print('error: invalid process', file=result
)
248 error
= lldb
.SBError()
249 bytes
= process
.ReadMemory(start_addr
, options
.size
, error
)
252 print("Searching memory range [%#x - %#x) for" % (
253 start_addr
, end_addr
), end
=' ', file=result
)
254 for byte
in options
.data
:
255 print('%2.2x' % ord(byte
), end
=' ', file=result
)
258 match_index
= string
.find(bytes
, options
.data
)
259 while match_index
!= -1:
260 num_matches
= num_matches
+ 1
261 print('%#x: %#x + %u' % (start_addr
+
262 match_index
, start_addr
, match_index
), file=result
)
263 match_index
= string
.find(bytes
, options
.data
, match_index
+ 1)
266 print("error: no matches found", file=result
)
268 print('error: %s' % (error
.GetCString()), file=result
)
271 if __name__
== '__main__':
272 print('error: this script is designed to be used within the embedded script interpreter in LLDB')
273 elif getattr(lldb
, 'debugger', None):
274 memfind_command
.__doc
__ = create_memfind_options().format_help()
275 lldb
.debugger
.HandleCommand(
276 'command script add -f memory.memfind_command memfind')
277 print('"memfind" command installed, use the "--help" option for detailed help')