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 #----------------------------------------------------------------------
19 # Just try for LLDB in case PYTHONPATH is already correctly setup
22 lldb_python_dirs
= list()
23 # lldb is not in the PYTHONPATH, try some defaults for the current platform
24 platform_system
= platform
.system()
25 if platform_system
== 'Darwin':
26 # On Darwin, try the currently selected Xcode directory
27 xcode_dir
= subprocess
.check_output("xcode-select --print-path", shell
=True)
29 lldb_python_dirs
.append(
32 '/../SharedFrameworks/LLDB.framework/Resources/Python'))
33 lldb_python_dirs
.append(
34 xcode_dir
+ '/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
35 lldb_python_dirs
.append(
36 '/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
38 for lldb_python_dir
in lldb_python_dirs
:
39 if os
.path
.exists(lldb_python_dir
):
40 if not (sys
.path
.__contains
__(lldb_python_dir
)):
41 sys
.path
.append(lldb_python_dir
)
47 print('imported lldb from: "%s"' % (lldb_python_dir
))
51 print("error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly")
61 def append_data_callback(option
, opt_str
, value
, parser
):
62 if opt_str
== "--uint8":
64 parser
.values
.data
+= struct
.pack('1B', int8
)
65 if opt_str
== "--uint16":
67 parser
.values
.data
+= struct
.pack('1H', int16
)
68 if opt_str
== "--uint32":
70 parser
.values
.data
+= struct
.pack('1I', int32
)
71 if opt_str
== "--uint64":
73 parser
.values
.data
+= struct
.pack('1Q', int64
)
74 if opt_str
== "--int8":
76 parser
.values
.data
+= struct
.pack('1b', int8
)
77 if opt_str
== "--int16":
79 parser
.values
.data
+= struct
.pack('1h', int16
)
80 if opt_str
== "--int32":
82 parser
.values
.data
+= struct
.pack('1i', int32
)
83 if opt_str
== "--int64":
85 parser
.values
.data
+= struct
.pack('1q', int64
)
88 def create_memfind_options():
89 usage
= "usage: %prog [options] STARTADDR [ENDADDR]"
90 description
= '''This command can find data in a specified address range.
91 Options are used to specify the data that is to be looked for and the options
92 can be specified multiple times to look for longer streams of data.
94 parser
= optparse
.OptionParser(
95 description
=description
,
104 help='Specify the byte size to search.',
109 callback
=append_data_callback
,
113 help='Specify a 8 bit signed integer value to search for in memory.',
118 callback
=append_data_callback
,
122 help='Specify a 16 bit signed integer value to search for in memory.',
127 callback
=append_data_callback
,
131 help='Specify a 32 bit signed integer value to search for in memory.',
136 callback
=append_data_callback
,
140 help='Specify a 64 bit signed integer value to search for in memory.',
145 callback
=append_data_callback
,
149 help='Specify a 8 bit unsigned integer value to search for in memory.',
154 callback
=append_data_callback
,
158 help='Specify a 16 bit unsigned integer value to search for in memory.',
163 callback
=append_data_callback
,
167 help='Specify a 32 bit unsigned integer value to search for in memory.',
172 callback
=append_data_callback
,
176 help='Specify a 64 bit unsigned integer value to search for in memory.',
181 def memfind_command(debugger
, command
, result
, dict):
182 # Use the Shell Lexer to properly parse up command options just like a
184 command_args
= shlex
.split(command
)
185 parser
= create_memfind_options()
186 (options
, args
) = parser
.parse_args(command_args
)
188 # (options, args) = parser.parse_args(command_args)
190 # # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
191 # # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
192 # result.SetStatus (lldb.eReturnStatusFailed)
193 # print >>result, "error: option parsing failed" # returning a string is the same as returning an error whose description is the string
195 memfind(debugger
.GetSelectedTarget(), options
, args
, result
)
198 def print_error(str, show_usage
, result
):
199 print(str, file=result
)
201 print(create_memfind_options().format_help(), file=result
)
204 def memfind(target
, options
, args
, result
):
210 "error: --size must be specified if there is no ENDADDR argument",
214 start_addr
= int(args
[0], 0)
216 if options
.size
!= 0:
218 "error: --size can't be specified with an ENDADDR argument",
222 start_addr
= int(args
[0], 0)
223 end_addr
= int(args
[1], 0)
224 if start_addr
>= end_addr
:
226 "error: inavlid memory range [%#x - %#x)" %
227 (start_addr
, end_addr
), True, result
)
229 options
.size
= end_addr
- start_addr
231 print_error("error: memfind takes 1 or 2 arguments", True, result
)
235 print('error: no data specified to search for', file=result
)
239 print('error: invalid target', file=result
)
241 process
= target
.process
243 print('error: invalid process', file=result
)
246 error
= lldb
.SBError()
247 bytes
= process
.ReadMemory(start_addr
, options
.size
, error
)
250 print("Searching memory range [%#x - %#x) for" % (
251 start_addr
, end_addr
), end
=' ', file=result
)
252 for byte
in options
.data
:
253 print('%2.2x' % ord(byte
), end
=' ', file=result
)
256 match_index
= string
.find(bytes
, options
.data
)
257 while match_index
!= -1:
258 num_matches
= num_matches
+ 1
259 print('%#x: %#x + %u' % (start_addr
+
260 match_index
, start_addr
, match_index
), file=result
)
261 match_index
= string
.find(bytes
, options
.data
, match_index
+ 1)
264 print("error: no matches found", file=result
)
266 print('error: %s' % (error
.GetCString()), file=result
)
269 if __name__
== '__main__':
270 print('error: this script is designed to be used within the embedded script interpreter in LLDB')
272 def __lldb_init_module(debugger
, internal_dict
):
273 memfind_command
.__doc
__ = create_memfind_options().format_help()
274 debugger
.HandleCommand(
275 'command script add -o -f memory.memfind_command memfind')
276 print('"memfind" command installed, use the "--help" option for detailed help')