hilda 3.0.0__tar.gz → 3.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hilda-3.0.0 → hilda-3.1.0}/.github/workflows/python-app.yml +1 -1
- {hilda-3.0.0 → hilda-3.1.0}/PKG-INFO +92 -162
- {hilda-3.0.0 → hilda-3.1.0}/README.md +89 -160
- {hilda-3.0.0 → hilda-3.1.0}/hilda/_version.py +2 -2
- {hilda-3.0.0 → hilda-3.1.0}/hilda/breakpoints.py +27 -4
- hilda-3.1.0/hilda/decorators.py +45 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/hilda_client.py +2 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/launch_lldb.py +29 -12
- {hilda-3.0.0 → hilda-3.1.0}/hilda/symbol.py +3 -0
- hilda-3.1.0/hilda/watchpoints.py +269 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda.egg-info/PKG-INFO +92 -162
- {hilda-3.0.0 → hilda-3.1.0}/hilda.egg-info/SOURCES.txt +2 -1
- {hilda-3.0.0 → hilda-3.1.0}/tests/conftest.py +1 -1
- hilda-3.0.0/hilda/hilda_ascii_art.html +0 -40
- {hilda-3.0.0 → hilda-3.1.0}/.github/workflows/python-publish.yml +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/.gitignore +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/.pre-commit-config.yaml +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/LICENSE +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/gifs/.gitattributes +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/gifs/ui.png +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/gifs/xpc_print_message.gif +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/__init__.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/__main__.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/cli.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/common.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/exceptions.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/ipython_extensions/events.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/ipython_extensions/keybindings.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/ipython_extensions/magics.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/lldb_entrypoint.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/lldb_importer.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c/from_ns_to_json.m +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c/get_objectivec_class_by_module.m +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c/get_objectivec_class_description.m +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c/get_objectivec_symbol_data.m +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c/lsof.m +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c/to_ns_from_json.m +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c_class.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c_symbol.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/registers.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/__init__.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/boringssl.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/collections.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/dyld.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/fs_utils.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/libmalloc.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/mach/CFRunLoopServiceMachPort_hooks.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/mach/__init__.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/macho/__init__.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/macho/all_image_infos.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/macho/apple_version.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/macho/image_info.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/macho/macho.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/macho/macho_load_commands.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/remotepairingd.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/syslog.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/uuid.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/xpc.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/symbols_jar.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/ui/colors.json +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/ui/ui_manager.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda/ui/views.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda.egg-info/dependency_links.txt +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda.egg-info/entry_points.txt +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda.egg-info/requires.txt +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/hilda.egg-info/top_level.txt +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/pyproject.toml +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/requirements.txt +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/setup.cfg +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/tests/__init__.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/tests/test_hilda_client/test_from_ns.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/tests/test_hilda_client/test_hilda_client.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/tests/test_hilda_client/test_monitor.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/tests/test_hilda_client/test_ns.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/tests/test_hilda_client/test_rebind_symbols.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/tests/test_hilda_client/test_registers.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/tests/test_snippets/test_xpc.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/tests/test_symbols/test_objective_c_class.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/tests/test_symbols/test_objective_c_symbol.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/tests/test_symbols/test_symbol.py +0 -0
- {hilda-3.0.0 → hilda-3.1.0}/tests/test_symbols/test_symbols_jar.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: hilda
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.1.0
|
|
4
4
|
Summary: LLDB wrapped and empowered by iPython's features
|
|
5
5
|
Author-email: doronz88 <doron88@gmail.com>, matan <matan1008@gmail.com>, netanel cohen <netanelc305@protonmail.com>
|
|
6
6
|
Maintainer-email: doronz88 <doron88@gmail.com>, matan <matan1008@gmail.com>, netanel cohen <netanelc305@protonmail.com>
|
|
@@ -55,6 +55,7 @@ Requires-Dist: inquirer3
|
|
|
55
55
|
Requires-Dist: traitlets
|
|
56
56
|
Provides-Extra: test
|
|
57
57
|
Requires-Dist: pytest; extra == "test"
|
|
58
|
+
Dynamic: license-file
|
|
58
59
|
|
|
59
60
|
# Hilda
|
|
60
61
|
|
|
@@ -152,165 +153,94 @@ You can may start a Hilda interactive shell by invoking any of the subcommand:
|
|
|
152
153
|
|
|
153
154
|
### Inside a Hilda shell
|
|
154
155
|
|
|
155
|
-
Upon starting Hilda
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
- `
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
- `
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
- `
|
|
176
|
-
|
|
177
|
-
- `
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
- `
|
|
184
|
-
|
|
185
|
-
- `peek`
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
- `
|
|
194
|
-
|
|
195
|
-
- `
|
|
196
|
-
|
|
197
|
-
- `
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
- `
|
|
204
|
-
|
|
205
|
-
- `
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
- `
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
force a return from function with the specified value
|
|
244
|
-
name=some_value
|
|
245
|
-
use `some_name` instead of the symbol name automatically extracted from the calling frame
|
|
246
|
-
override=True
|
|
247
|
-
override previous break point at same location
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
- `show_current_source`
|
|
251
|
-
- print current source code if possible
|
|
252
|
-
- `finish`
|
|
253
|
-
- Run current frame till its end.
|
|
254
|
-
- `step_into`
|
|
255
|
-
- Step into current instruction.
|
|
256
|
-
- `step_over`
|
|
257
|
-
- Step over current instruction.
|
|
258
|
-
- `breakpoints.clear`
|
|
259
|
-
- Remove all breakpoints
|
|
260
|
-
- `breakpoints.remove`
|
|
261
|
-
- Remove a single breakpoint
|
|
262
|
-
- `force_return`
|
|
263
|
-
- Prematurely return from a stack frame, short-circuiting exection of newer frames and optionally
|
|
264
|
-
yielding a specified value.
|
|
265
|
-
- `proc_info`
|
|
266
|
-
- Print information about currently running mapped process.
|
|
267
|
-
- `print_proc_entitlements`
|
|
268
|
-
- Get the plist embedded inside the process' __LINKEDIT section.
|
|
269
|
-
- `bp` or `breakpoints.add`
|
|
270
|
-
- Add a breakpoint
|
|
271
|
-
- `breakpoints.show`
|
|
272
|
-
- Show existing breakpoints
|
|
273
|
-
- `po`
|
|
274
|
-
- Print given object using LLDB's po command
|
|
275
|
-
Can also run big chunks of native code:
|
|
276
|
-
|
|
277
|
-
po('NSMutableString *s = [NSMutableString string]; [s appendString:@"abc"]; [s description]')
|
|
278
|
-
- `globalize_symbols`
|
|
279
|
-
- Make all symbols in python's global scope
|
|
280
|
-
- `jump`
|
|
281
|
-
- jump to given symbol
|
|
282
|
-
- `lldb_handle_command`
|
|
283
|
-
- Execute an LLDB command
|
|
284
|
-
For example:
|
|
285
|
-
lldb_handle_command('register read')
|
|
286
|
-
- `objc_get_class`
|
|
287
|
-
- Get ObjC class object
|
|
288
|
-
- `CFSTR`
|
|
289
|
-
- Create CFStringRef object from given string
|
|
290
|
-
- `ns`
|
|
291
|
-
- Create NSObject from given data
|
|
292
|
-
- `from_ns`
|
|
293
|
-
- Create python object from NS object.
|
|
294
|
-
- `evaluate_expression`
|
|
295
|
-
- Wrapper for LLDB's EvaluateExpression.
|
|
296
|
-
Used for quick code snippets.
|
|
297
|
-
|
|
298
|
-
Feel free to use local variables inside the expression using format string.
|
|
299
|
-
For example:
|
|
300
|
-
currentDevice = objc_get_class('UIDevice').currentDevice
|
|
301
|
-
evaluate_expression(f'[[{currentDevice} systemName] hasPrefix:@"2"]')
|
|
302
|
-
- `import_module`
|
|
303
|
-
- Import & reload given python module (intended mainly for external snippets)
|
|
304
|
-
- `unwind`
|
|
305
|
-
- Unwind the stack (useful when get_evaluation_unwind() == False)
|
|
306
|
-
- `set_selected_thread`
|
|
307
|
-
- sets the currently selected thread, which is used in other parts of the program, such as displaying disassembly or
|
|
308
|
-
checking registers.
|
|
309
|
-
This ensures the application focuses on the specified thread for these operations.
|
|
310
|
-
- `wait_for_module`
|
|
311
|
-
- Wait for a module to be loaded (`dlopen`) by checking if given expression is contained within its filename
|
|
312
|
-
|
|
313
|
-
All these methods are available from the global `p` within the newly created IPython shell. In addition, you may invoke any of the exported APIs described in the [Python API](#python-api)
|
|
156
|
+
Upon starting Hilda, you are welcomed into an IPython shell.
|
|
157
|
+
You can access following methods via the variable `p`.
|
|
158
|
+
|
|
159
|
+
Basic flow control:
|
|
160
|
+
|
|
161
|
+
- `stop` - Stop process
|
|
162
|
+
- `cont` - Continue process
|
|
163
|
+
- `finish` - Run current function until return
|
|
164
|
+
- `step_into` - Step into current instruction
|
|
165
|
+
- `step_over` - Step over current instruction.
|
|
166
|
+
- `run_for` - Run the process for given interval
|
|
167
|
+
- `force_return` - Prematurely return from a stack frame, short-circuiting exection of inner
|
|
168
|
+
frames and optionally yielding a specified value.
|
|
169
|
+
- `jump` - Jump to given symbol
|
|
170
|
+
- `wait_for_module` - Wait for a module to be loaded (`dlopen`) by checking if given expression is contained within its filename
|
|
171
|
+
- `detach` - Detach from process (useful for exiting gracefully so the
|
|
172
|
+
process doesn't get killed when you exit)
|
|
173
|
+
|
|
174
|
+
Breakpoints:
|
|
175
|
+
- `bp` or `breakpoints.add` - Add a breakpoint
|
|
176
|
+
- `breakpoints.show` - Show existing breakpoints
|
|
177
|
+
- `breakpoints.remove` - Remove a single breakpoint
|
|
178
|
+
- `breakpoints.clear` - Remove all breakpoints
|
|
179
|
+
- `monitor` or `breakpoints.add_monitor` - Creates a breakpoint whose callback implements the requested features (print register vallues, execute commands, mock return value, etc.)
|
|
180
|
+
|
|
181
|
+
Basic read/write:
|
|
182
|
+
|
|
183
|
+
- `get_register` - Get register value
|
|
184
|
+
- `set_register` - Set register value
|
|
185
|
+
- `poke` - Write data at address
|
|
186
|
+
- `peek[_str,_std_str]` - Read buffer/C-string/`std::string` at address
|
|
187
|
+
- `po` - Print object using LLDB's `po` command
|
|
188
|
+
Can also run arbitrary native code:
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
p.po('NSMutableString *s = [NSMutableString string]; [s appendString:@"abc"]; [s description]')
|
|
192
|
+
```
|
|
193
|
+
- `disass` - Print disassembly at address
|
|
194
|
+
- `show_current_source` - Print current source code (if possible)
|
|
195
|
+
- `bt` - Get backtrace
|
|
196
|
+
- `lsof` - Get all open FDs
|
|
197
|
+
- `hd` - Hexdump a buffer
|
|
198
|
+
- `proc_info` - Print information about currently running mapped process
|
|
199
|
+
- `print_proc_entitlements` - Get the plist embedded inside the process' __LINKEDIT section.
|
|
200
|
+
|
|
201
|
+
Execute code:
|
|
202
|
+
|
|
203
|
+
- `call` - Call function at given address with given parameters
|
|
204
|
+
- `objc_call` - Simulate a call to an objc selector
|
|
205
|
+
- `inject` - Inject a single library into currently running process
|
|
206
|
+
- `disable_jetsam_memory_checks` -
|
|
207
|
+
Disable jetsam memory checks (to prevent raising
|
|
208
|
+
`error: Execution was interrupted, reason: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit=15 MB, unused=0x0).`
|
|
209
|
+
when evaluating expressions).
|
|
210
|
+
|
|
211
|
+
Hilda symbols:
|
|
212
|
+
|
|
213
|
+
- `symbol` - Get symbol object for a given address
|
|
214
|
+
- `objc_symbol` - Get objc symbol wrapper for given address
|
|
215
|
+
- `rebind_symbols` - Reparse all loaded images symbols
|
|
216
|
+
- `file_symbol` - Calculate symbol address without ASLR
|
|
217
|
+
- `save` - Save loaded symbols map (for loading later using the load() command)
|
|
218
|
+
- `load` - Load an existing symbols map (previously saved by the save() command)
|
|
219
|
+
- `globalize_symbols` - Make all symbols in python's global scope
|
|
220
|
+
|
|
221
|
+
Advanced:
|
|
222
|
+
|
|
223
|
+
- `lldb_handle_command` - Execute an LLDB command (e.g., `p.lldb_handle_command('register read')`)
|
|
224
|
+
- `evaluate_expression` - Use for quick code snippets (wrapper for LLDB's `EvaluateExpression`)
|
|
225
|
+
|
|
226
|
+
Take advantage of local variables inside the expression using format string, e.g.,
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
currentDevice = p.objc_get_class('UIDevice').currentDevice
|
|
230
|
+
p.evaluate_expression(f'[[{currentDevice} systemName] hasPrefix:@"2"]')
|
|
231
|
+
```
|
|
232
|
+
- `import_module` - Import & reload given python module (intended mainly for external snippets)
|
|
233
|
+
- `unwind` - Unwind the stack (useful when get_evaluation_unwind() == False)
|
|
234
|
+
- `set_selected_thread` - sets the currently selected thread, which is used in other parts of the program, such as displaying disassembly or
|
|
235
|
+
checking registers.
|
|
236
|
+
This ensures the application focuses on the specified thread for these operations.
|
|
237
|
+
|
|
238
|
+
Objective-C related:
|
|
239
|
+
|
|
240
|
+
- `objc_get_class` - Get ObjC class object
|
|
241
|
+
- `CFSTR` - Create CFStringRef object from given string
|
|
242
|
+
- `ns` - Create NSObject from given data
|
|
243
|
+
- `from_ns` - Create python object from NS object.
|
|
314
244
|
|
|
315
245
|
#### Magic functions
|
|
316
246
|
|
|
@@ -672,7 +602,7 @@ commands so you are able to use complicated types when parsing values and passin
|
|
|
672
602
|
import datetime
|
|
673
603
|
|
|
674
604
|
# using the `ns` command we can just pass a python-native dictionary
|
|
675
|
-
function_requiring_a_specfic_dictionary(
|
|
605
|
+
function_requiring_a_specfic_dictionary(p.cf({
|
|
676
606
|
'key1': 'string', # will convert to NSString
|
|
677
607
|
'key2': True, # will convert to NSNumber
|
|
678
608
|
'key3': b'1234', # will convert to NSData
|
|
@@ -94,165 +94,94 @@ You can may start a Hilda interactive shell by invoking any of the subcommand:
|
|
|
94
94
|
|
|
95
95
|
### Inside a Hilda shell
|
|
96
96
|
|
|
97
|
-
Upon starting Hilda
|
|
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
|
-
- `peek`
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
- `
|
|
136
|
-
|
|
137
|
-
- `
|
|
138
|
-
|
|
139
|
-
- `
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
- `
|
|
146
|
-
|
|
147
|
-
- `
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
- `
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
force a return from function with the specified value
|
|
186
|
-
name=some_value
|
|
187
|
-
use `some_name` instead of the symbol name automatically extracted from the calling frame
|
|
188
|
-
override=True
|
|
189
|
-
override previous break point at same location
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
- `show_current_source`
|
|
193
|
-
- print current source code if possible
|
|
194
|
-
- `finish`
|
|
195
|
-
- Run current frame till its end.
|
|
196
|
-
- `step_into`
|
|
197
|
-
- Step into current instruction.
|
|
198
|
-
- `step_over`
|
|
199
|
-
- Step over current instruction.
|
|
200
|
-
- `breakpoints.clear`
|
|
201
|
-
- Remove all breakpoints
|
|
202
|
-
- `breakpoints.remove`
|
|
203
|
-
- Remove a single breakpoint
|
|
204
|
-
- `force_return`
|
|
205
|
-
- Prematurely return from a stack frame, short-circuiting exection of newer frames and optionally
|
|
206
|
-
yielding a specified value.
|
|
207
|
-
- `proc_info`
|
|
208
|
-
- Print information about currently running mapped process.
|
|
209
|
-
- `print_proc_entitlements`
|
|
210
|
-
- Get the plist embedded inside the process' __LINKEDIT section.
|
|
211
|
-
- `bp` or `breakpoints.add`
|
|
212
|
-
- Add a breakpoint
|
|
213
|
-
- `breakpoints.show`
|
|
214
|
-
- Show existing breakpoints
|
|
215
|
-
- `po`
|
|
216
|
-
- Print given object using LLDB's po command
|
|
217
|
-
Can also run big chunks of native code:
|
|
218
|
-
|
|
219
|
-
po('NSMutableString *s = [NSMutableString string]; [s appendString:@"abc"]; [s description]')
|
|
220
|
-
- `globalize_symbols`
|
|
221
|
-
- Make all symbols in python's global scope
|
|
222
|
-
- `jump`
|
|
223
|
-
- jump to given symbol
|
|
224
|
-
- `lldb_handle_command`
|
|
225
|
-
- Execute an LLDB command
|
|
226
|
-
For example:
|
|
227
|
-
lldb_handle_command('register read')
|
|
228
|
-
- `objc_get_class`
|
|
229
|
-
- Get ObjC class object
|
|
230
|
-
- `CFSTR`
|
|
231
|
-
- Create CFStringRef object from given string
|
|
232
|
-
- `ns`
|
|
233
|
-
- Create NSObject from given data
|
|
234
|
-
- `from_ns`
|
|
235
|
-
- Create python object from NS object.
|
|
236
|
-
- `evaluate_expression`
|
|
237
|
-
- Wrapper for LLDB's EvaluateExpression.
|
|
238
|
-
Used for quick code snippets.
|
|
239
|
-
|
|
240
|
-
Feel free to use local variables inside the expression using format string.
|
|
241
|
-
For example:
|
|
242
|
-
currentDevice = objc_get_class('UIDevice').currentDevice
|
|
243
|
-
evaluate_expression(f'[[{currentDevice} systemName] hasPrefix:@"2"]')
|
|
244
|
-
- `import_module`
|
|
245
|
-
- Import & reload given python module (intended mainly for external snippets)
|
|
246
|
-
- `unwind`
|
|
247
|
-
- Unwind the stack (useful when get_evaluation_unwind() == False)
|
|
248
|
-
- `set_selected_thread`
|
|
249
|
-
- sets the currently selected thread, which is used in other parts of the program, such as displaying disassembly or
|
|
250
|
-
checking registers.
|
|
251
|
-
This ensures the application focuses on the specified thread for these operations.
|
|
252
|
-
- `wait_for_module`
|
|
253
|
-
- Wait for a module to be loaded (`dlopen`) by checking if given expression is contained within its filename
|
|
254
|
-
|
|
255
|
-
All these methods are available from the global `p` within the newly created IPython shell. In addition, you may invoke any of the exported APIs described in the [Python API](#python-api)
|
|
97
|
+
Upon starting Hilda, you are welcomed into an IPython shell.
|
|
98
|
+
You can access following methods via the variable `p`.
|
|
99
|
+
|
|
100
|
+
Basic flow control:
|
|
101
|
+
|
|
102
|
+
- `stop` - Stop process
|
|
103
|
+
- `cont` - Continue process
|
|
104
|
+
- `finish` - Run current function until return
|
|
105
|
+
- `step_into` - Step into current instruction
|
|
106
|
+
- `step_over` - Step over current instruction.
|
|
107
|
+
- `run_for` - Run the process for given interval
|
|
108
|
+
- `force_return` - Prematurely return from a stack frame, short-circuiting exection of inner
|
|
109
|
+
frames and optionally yielding a specified value.
|
|
110
|
+
- `jump` - Jump to given symbol
|
|
111
|
+
- `wait_for_module` - Wait for a module to be loaded (`dlopen`) by checking if given expression is contained within its filename
|
|
112
|
+
- `detach` - Detach from process (useful for exiting gracefully so the
|
|
113
|
+
process doesn't get killed when you exit)
|
|
114
|
+
|
|
115
|
+
Breakpoints:
|
|
116
|
+
- `bp` or `breakpoints.add` - Add a breakpoint
|
|
117
|
+
- `breakpoints.show` - Show existing breakpoints
|
|
118
|
+
- `breakpoints.remove` - Remove a single breakpoint
|
|
119
|
+
- `breakpoints.clear` - Remove all breakpoints
|
|
120
|
+
- `monitor` or `breakpoints.add_monitor` - Creates a breakpoint whose callback implements the requested features (print register vallues, execute commands, mock return value, etc.)
|
|
121
|
+
|
|
122
|
+
Basic read/write:
|
|
123
|
+
|
|
124
|
+
- `get_register` - Get register value
|
|
125
|
+
- `set_register` - Set register value
|
|
126
|
+
- `poke` - Write data at address
|
|
127
|
+
- `peek[_str,_std_str]` - Read buffer/C-string/`std::string` at address
|
|
128
|
+
- `po` - Print object using LLDB's `po` command
|
|
129
|
+
Can also run arbitrary native code:
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
p.po('NSMutableString *s = [NSMutableString string]; [s appendString:@"abc"]; [s description]')
|
|
133
|
+
```
|
|
134
|
+
- `disass` - Print disassembly at address
|
|
135
|
+
- `show_current_source` - Print current source code (if possible)
|
|
136
|
+
- `bt` - Get backtrace
|
|
137
|
+
- `lsof` - Get all open FDs
|
|
138
|
+
- `hd` - Hexdump a buffer
|
|
139
|
+
- `proc_info` - Print information about currently running mapped process
|
|
140
|
+
- `print_proc_entitlements` - Get the plist embedded inside the process' __LINKEDIT section.
|
|
141
|
+
|
|
142
|
+
Execute code:
|
|
143
|
+
|
|
144
|
+
- `call` - Call function at given address with given parameters
|
|
145
|
+
- `objc_call` - Simulate a call to an objc selector
|
|
146
|
+
- `inject` - Inject a single library into currently running process
|
|
147
|
+
- `disable_jetsam_memory_checks` -
|
|
148
|
+
Disable jetsam memory checks (to prevent raising
|
|
149
|
+
`error: Execution was interrupted, reason: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit=15 MB, unused=0x0).`
|
|
150
|
+
when evaluating expressions).
|
|
151
|
+
|
|
152
|
+
Hilda symbols:
|
|
153
|
+
|
|
154
|
+
- `symbol` - Get symbol object for a given address
|
|
155
|
+
- `objc_symbol` - Get objc symbol wrapper for given address
|
|
156
|
+
- `rebind_symbols` - Reparse all loaded images symbols
|
|
157
|
+
- `file_symbol` - Calculate symbol address without ASLR
|
|
158
|
+
- `save` - Save loaded symbols map (for loading later using the load() command)
|
|
159
|
+
- `load` - Load an existing symbols map (previously saved by the save() command)
|
|
160
|
+
- `globalize_symbols` - Make all symbols in python's global scope
|
|
161
|
+
|
|
162
|
+
Advanced:
|
|
163
|
+
|
|
164
|
+
- `lldb_handle_command` - Execute an LLDB command (e.g., `p.lldb_handle_command('register read')`)
|
|
165
|
+
- `evaluate_expression` - Use for quick code snippets (wrapper for LLDB's `EvaluateExpression`)
|
|
166
|
+
|
|
167
|
+
Take advantage of local variables inside the expression using format string, e.g.,
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
currentDevice = p.objc_get_class('UIDevice').currentDevice
|
|
171
|
+
p.evaluate_expression(f'[[{currentDevice} systemName] hasPrefix:@"2"]')
|
|
172
|
+
```
|
|
173
|
+
- `import_module` - Import & reload given python module (intended mainly for external snippets)
|
|
174
|
+
- `unwind` - Unwind the stack (useful when get_evaluation_unwind() == False)
|
|
175
|
+
- `set_selected_thread` - sets the currently selected thread, which is used in other parts of the program, such as displaying disassembly or
|
|
176
|
+
checking registers.
|
|
177
|
+
This ensures the application focuses on the specified thread for these operations.
|
|
178
|
+
|
|
179
|
+
Objective-C related:
|
|
180
|
+
|
|
181
|
+
- `objc_get_class` - Get ObjC class object
|
|
182
|
+
- `CFSTR` - Create CFStringRef object from given string
|
|
183
|
+
- `ns` - Create NSObject from given data
|
|
184
|
+
- `from_ns` - Create python object from NS object.
|
|
256
185
|
|
|
257
186
|
#### Magic functions
|
|
258
187
|
|
|
@@ -614,7 +543,7 @@ commands so you are able to use complicated types when parsing values and passin
|
|
|
614
543
|
import datetime
|
|
615
544
|
|
|
616
545
|
# using the `ns` command we can just pass a python-native dictionary
|
|
617
|
-
function_requiring_a_specfic_dictionary(
|
|
546
|
+
function_requiring_a_specfic_dictionary(p.cf({
|
|
618
547
|
'key1': 'string', # will convert to NSString
|
|
619
548
|
'key2': True, # will convert to NSNumber
|
|
620
549
|
'key3': b'1234', # will convert to NSData
|
|
@@ -124,12 +124,30 @@ class HildaBreakpoint:
|
|
|
124
124
|
for name in names_to_add:
|
|
125
125
|
self.lldb_breakpoint.AddName(name)
|
|
126
126
|
|
|
127
|
+
@property
|
|
128
|
+
def enabled(self) -> bool:
|
|
129
|
+
"""
|
|
130
|
+
Configures whether this breakpoint is enabled or not.
|
|
131
|
+
"""
|
|
132
|
+
return self.lldb_breakpoint.IsEnabled()
|
|
133
|
+
|
|
134
|
+
@enabled.setter
|
|
135
|
+
def enabled(self, value: bool) -> None:
|
|
136
|
+
self.lldb_breakpoint.SetEnabled(value)
|
|
137
|
+
|
|
127
138
|
def __repr__(self) -> str:
|
|
128
|
-
|
|
139
|
+
enabled_repr = 'ENABLED' if self.enabled else 'DISABLED'
|
|
140
|
+
guarded_repr = 'GUARDED' if self.guarded else 'NOT-GUARDED'
|
|
141
|
+
return (f'<{self.__class__.__name__} LLDB:{self.lldb_breakpoint} {enabled_repr} {guarded_repr} '
|
|
129
142
|
f'CALLBACK:{self.callback}>')
|
|
130
143
|
|
|
131
144
|
def __str__(self) -> str:
|
|
132
|
-
|
|
145
|
+
emoji = '🚨' if self.enabled else '🔕'
|
|
146
|
+
enabled_str = 'enabled' if self.enabled else 'disabled'
|
|
147
|
+
guarded_str = 'guarded' if self.guarded else 'not-guarded'
|
|
148
|
+
|
|
149
|
+
result = f'{emoji} Breakpoint #{self.id} ({enabled_str}, {guarded_str})\n'
|
|
150
|
+
|
|
133
151
|
if self.description is not None:
|
|
134
152
|
result += f'\tDescription: {self.description}\n'
|
|
135
153
|
|
|
@@ -137,10 +155,13 @@ class HildaBreakpoint:
|
|
|
137
155
|
result += f'\tWhere: {self.where}\n'
|
|
138
156
|
|
|
139
157
|
# A single breakpoint may be related to several locations (addresses)
|
|
158
|
+
locations = self.locations
|
|
159
|
+
if len(locations) == 0:
|
|
160
|
+
result += f'\tNo locations\n'
|
|
140
161
|
for location in self.locations:
|
|
141
162
|
result += f'\tLocation {location}\n'
|
|
142
163
|
|
|
143
|
-
return result
|
|
164
|
+
return result.strip('\n')
|
|
144
165
|
|
|
145
166
|
def remove(self, remove_guarded: bool = False) -> None:
|
|
146
167
|
"""
|
|
@@ -441,8 +462,10 @@ class BreakpointList:
|
|
|
441
462
|
|
|
442
463
|
def show(self) -> None:
|
|
443
464
|
""" Show existing breakpoints. """
|
|
465
|
+
if len(self) == 0:
|
|
466
|
+
self._hilda.log_info('No breakpoints')
|
|
444
467
|
for bp in self:
|
|
445
|
-
|
|
468
|
+
self._hilda.log_info(bp)
|
|
446
469
|
|
|
447
470
|
def items(self):
|
|
448
471
|
"""
|