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.
Files changed (81) hide show
  1. {hilda-3.0.0 → hilda-3.1.0}/.github/workflows/python-app.yml +1 -1
  2. {hilda-3.0.0 → hilda-3.1.0}/PKG-INFO +92 -162
  3. {hilda-3.0.0 → hilda-3.1.0}/README.md +89 -160
  4. {hilda-3.0.0 → hilda-3.1.0}/hilda/_version.py +2 -2
  5. {hilda-3.0.0 → hilda-3.1.0}/hilda/breakpoints.py +27 -4
  6. hilda-3.1.0/hilda/decorators.py +45 -0
  7. {hilda-3.0.0 → hilda-3.1.0}/hilda/hilda_client.py +2 -0
  8. {hilda-3.0.0 → hilda-3.1.0}/hilda/launch_lldb.py +29 -12
  9. {hilda-3.0.0 → hilda-3.1.0}/hilda/symbol.py +3 -0
  10. hilda-3.1.0/hilda/watchpoints.py +269 -0
  11. {hilda-3.0.0 → hilda-3.1.0}/hilda.egg-info/PKG-INFO +92 -162
  12. {hilda-3.0.0 → hilda-3.1.0}/hilda.egg-info/SOURCES.txt +2 -1
  13. {hilda-3.0.0 → hilda-3.1.0}/tests/conftest.py +1 -1
  14. hilda-3.0.0/hilda/hilda_ascii_art.html +0 -40
  15. {hilda-3.0.0 → hilda-3.1.0}/.github/workflows/python-publish.yml +0 -0
  16. {hilda-3.0.0 → hilda-3.1.0}/.gitignore +0 -0
  17. {hilda-3.0.0 → hilda-3.1.0}/.pre-commit-config.yaml +0 -0
  18. {hilda-3.0.0 → hilda-3.1.0}/LICENSE +0 -0
  19. {hilda-3.0.0 → hilda-3.1.0}/gifs/.gitattributes +0 -0
  20. {hilda-3.0.0 → hilda-3.1.0}/gifs/ui.png +0 -0
  21. {hilda-3.0.0 → hilda-3.1.0}/gifs/xpc_print_message.gif +0 -0
  22. {hilda-3.0.0 → hilda-3.1.0}/hilda/__init__.py +0 -0
  23. {hilda-3.0.0 → hilda-3.1.0}/hilda/__main__.py +0 -0
  24. {hilda-3.0.0 → hilda-3.1.0}/hilda/cli.py +0 -0
  25. {hilda-3.0.0 → hilda-3.1.0}/hilda/common.py +0 -0
  26. {hilda-3.0.0 → hilda-3.1.0}/hilda/exceptions.py +0 -0
  27. {hilda-3.0.0 → hilda-3.1.0}/hilda/ipython_extensions/events.py +0 -0
  28. {hilda-3.0.0 → hilda-3.1.0}/hilda/ipython_extensions/keybindings.py +0 -0
  29. {hilda-3.0.0 → hilda-3.1.0}/hilda/ipython_extensions/magics.py +0 -0
  30. {hilda-3.0.0 → hilda-3.1.0}/hilda/lldb_entrypoint.py +0 -0
  31. {hilda-3.0.0 → hilda-3.1.0}/hilda/lldb_importer.py +0 -0
  32. {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c/from_ns_to_json.m +0 -0
  33. {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c/get_objectivec_class_by_module.m +0 -0
  34. {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c/get_objectivec_class_description.m +0 -0
  35. {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c/get_objectivec_symbol_data.m +0 -0
  36. {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c/lsof.m +0 -0
  37. {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c/to_ns_from_json.m +0 -0
  38. {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c_class.py +0 -0
  39. {hilda-3.0.0 → hilda-3.1.0}/hilda/objective_c_symbol.py +0 -0
  40. {hilda-3.0.0 → hilda-3.1.0}/hilda/registers.py +0 -0
  41. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/__init__.py +0 -0
  42. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/boringssl.py +0 -0
  43. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/collections.py +0 -0
  44. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/dyld.py +0 -0
  45. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/fs_utils.py +0 -0
  46. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/libmalloc.py +0 -0
  47. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/mach/CFRunLoopServiceMachPort_hooks.py +0 -0
  48. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/mach/__init__.py +0 -0
  49. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/macho/__init__.py +0 -0
  50. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/macho/all_image_infos.py +0 -0
  51. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/macho/apple_version.py +0 -0
  52. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/macho/image_info.py +0 -0
  53. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/macho/macho.py +0 -0
  54. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/macho/macho_load_commands.py +0 -0
  55. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/remotepairingd.py +0 -0
  56. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/syslog.py +0 -0
  57. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/uuid.py +0 -0
  58. {hilda-3.0.0 → hilda-3.1.0}/hilda/snippets/xpc.py +0 -0
  59. {hilda-3.0.0 → hilda-3.1.0}/hilda/symbols_jar.py +0 -0
  60. {hilda-3.0.0 → hilda-3.1.0}/hilda/ui/colors.json +0 -0
  61. {hilda-3.0.0 → hilda-3.1.0}/hilda/ui/ui_manager.py +0 -0
  62. {hilda-3.0.0 → hilda-3.1.0}/hilda/ui/views.py +0 -0
  63. {hilda-3.0.0 → hilda-3.1.0}/hilda.egg-info/dependency_links.txt +0 -0
  64. {hilda-3.0.0 → hilda-3.1.0}/hilda.egg-info/entry_points.txt +0 -0
  65. {hilda-3.0.0 → hilda-3.1.0}/hilda.egg-info/requires.txt +0 -0
  66. {hilda-3.0.0 → hilda-3.1.0}/hilda.egg-info/top_level.txt +0 -0
  67. {hilda-3.0.0 → hilda-3.1.0}/pyproject.toml +0 -0
  68. {hilda-3.0.0 → hilda-3.1.0}/requirements.txt +0 -0
  69. {hilda-3.0.0 → hilda-3.1.0}/setup.cfg +0 -0
  70. {hilda-3.0.0 → hilda-3.1.0}/tests/__init__.py +0 -0
  71. {hilda-3.0.0 → hilda-3.1.0}/tests/test_hilda_client/test_from_ns.py +0 -0
  72. {hilda-3.0.0 → hilda-3.1.0}/tests/test_hilda_client/test_hilda_client.py +0 -0
  73. {hilda-3.0.0 → hilda-3.1.0}/tests/test_hilda_client/test_monitor.py +0 -0
  74. {hilda-3.0.0 → hilda-3.1.0}/tests/test_hilda_client/test_ns.py +0 -0
  75. {hilda-3.0.0 → hilda-3.1.0}/tests/test_hilda_client/test_rebind_symbols.py +0 -0
  76. {hilda-3.0.0 → hilda-3.1.0}/tests/test_hilda_client/test_registers.py +0 -0
  77. {hilda-3.0.0 → hilda-3.1.0}/tests/test_snippets/test_xpc.py +0 -0
  78. {hilda-3.0.0 → hilda-3.1.0}/tests/test_symbols/test_objective_c_class.py +0 -0
  79. {hilda-3.0.0 → hilda-3.1.0}/tests/test_symbols/test_objective_c_symbol.py +0 -0
  80. {hilda-3.0.0 → hilda-3.1.0}/tests/test_symbols/test_symbol.py +0 -0
  81. {hilda-3.0.0 → hilda-3.1.0}/tests/test_symbols/test_symbols_jar.py +0 -0
@@ -39,4 +39,4 @@ jobs:
39
39
  xcrun python3 -m pip install -e ".[test]"
40
40
  - name: Run pytest
41
41
  run: |
42
- sudo xcrun python3 -m pytest -k "not set_implementation"
42
+ sudo xcrun python3 -m pytest -k "not set_implementation" -vvv
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: hilda
3
- Version: 3.0.0
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 shell, you are greeted with:
156
-
157
- ```
158
- Hilda has been successfully loaded! 😎
159
- Use the p global to access all features.
160
- Have a nice flight ✈️! Starting an IPython shell...
161
- ```
162
-
163
- Here is a gist of methods you can access from `p`:
164
-
165
- - `hd`
166
- - Print a hexdump of given buffer
167
- - `lsof`
168
- - Get dictionary of all open FDs
169
- - `bt`
170
- - Print an improved backtrace.
171
- - `disable_jetsam_memory_checks`
172
- - Disable jetsam memory checks, prevent raising:
173
- `error: Execution was interrupted, reason: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit=15 MB, unused=0x0).`
174
- when evaluating expression.
175
- - `symbol`
176
- - Get symbol object for a given address
177
- - `objc_symbol`
178
- - Get objc symbol wrapper for given address
179
- - `inject`
180
- - Inject a single library into currently running process
181
- - `rebind_symbols`
182
- - Reparse all loaded images symbols
183
- - `poke`
184
- - Write data at given address
185
- - `peek`
186
- - Read data at given address
187
- - `peek_str`
188
- - Peek a buffer till null termination
189
- - `peek_std_str`
190
- - Peek a `std::string`
191
- - `stop`
192
- - Stop process.
193
- - `cont`
194
- - Continue process.
195
- - `run_for`
196
- - Run the process for given interval.
197
- - `detach`
198
- - Detach from process.
199
- Useful in order to exit gracefully so process doesn't get killed
200
- while you exit
201
- - `disass`
202
- - Print disassembly from a given address
203
- - `file_symbol`
204
- - Calculate symbol address without ASLR
205
- - `get_register`
206
- - Get value for register by its name
207
- - `set_register`
208
- - Set value for register by its name
209
- - `objc_call`
210
- - Simulate a call to an objc selector
211
- - `call`
212
- - Call function at given address with given parameters
213
- - `monitor` or `breakpoints.add_monitor`
214
- - Monitor every time a given address is called
215
-
216
- The following options are available:
217
-
218
- ```
219
- regs={reg1: format}
220
- will print register values
221
-
222
- Available formats:
223
- x: hex
224
- s: string
225
- cf: use CFCopyDescription() to get more informative description of the object
226
- po: use LLDB po command
227
- User defined function, will be called like `format_function(hilda_client, value)`.
228
-
229
- For example:
230
- regs={'x0': 'x'} -> x0 will be printed in HEX format
231
- expr={lldb_expression: format}
232
- lldb_expression can be for example '$x0' or '$arg1'
233
- format behaves just like 'regs' option
234
- retval=format
235
- Print function's return value. The format is the same as regs format.
236
- stop=True
237
- force a stop at every hit
238
- bt=True
239
- print backtrace
240
- cmd=[cmd1, cmd2]
241
- run several LLDB commands, one by another
242
- force_return=value
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(ns({
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 shell, you are greeted with:
98
-
99
- ```
100
- Hilda has been successfully loaded! 😎
101
- Use the p global to access all features.
102
- Have a nice flight ✈️! Starting an IPython shell...
103
- ```
104
-
105
- Here is a gist of methods you can access from `p`:
106
-
107
- - `hd`
108
- - Print a hexdump of given buffer
109
- - `lsof`
110
- - Get dictionary of all open FDs
111
- - `bt`
112
- - Print an improved backtrace.
113
- - `disable_jetsam_memory_checks`
114
- - Disable jetsam memory checks, prevent raising:
115
- `error: Execution was interrupted, reason: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit=15 MB, unused=0x0).`
116
- when evaluating expression.
117
- - `symbol`
118
- - Get symbol object for a given address
119
- - `objc_symbol`
120
- - Get objc symbol wrapper for given address
121
- - `inject`
122
- - Inject a single library into currently running process
123
- - `rebind_symbols`
124
- - Reparse all loaded images symbols
125
- - `poke`
126
- - Write data at given address
127
- - `peek`
128
- - Read data at given address
129
- - `peek_str`
130
- - Peek a buffer till null termination
131
- - `peek_std_str`
132
- - Peek a `std::string`
133
- - `stop`
134
- - Stop process.
135
- - `cont`
136
- - Continue process.
137
- - `run_for`
138
- - Run the process for given interval.
139
- - `detach`
140
- - Detach from process.
141
- Useful in order to exit gracefully so process doesn't get killed
142
- while you exit
143
- - `disass`
144
- - Print disassembly from a given address
145
- - `file_symbol`
146
- - Calculate symbol address without ASLR
147
- - `get_register`
148
- - Get value for register by its name
149
- - `set_register`
150
- - Set value for register by its name
151
- - `objc_call`
152
- - Simulate a call to an objc selector
153
- - `call`
154
- - Call function at given address with given parameters
155
- - `monitor` or `breakpoints.add_monitor`
156
- - Monitor every time a given address is called
157
-
158
- The following options are available:
159
-
160
- ```
161
- regs={reg1: format}
162
- will print register values
163
-
164
- Available formats:
165
- x: hex
166
- s: string
167
- cf: use CFCopyDescription() to get more informative description of the object
168
- po: use LLDB po command
169
- User defined function, will be called like `format_function(hilda_client, value)`.
170
-
171
- For example:
172
- regs={'x0': 'x'} -> x0 will be printed in HEX format
173
- expr={lldb_expression: format}
174
- lldb_expression can be for example '$x0' or '$arg1'
175
- format behaves just like 'regs' option
176
- retval=format
177
- Print function's return value. The format is the same as regs format.
178
- stop=True
179
- force a stop at every hit
180
- bt=True
181
- print backtrace
182
- cmd=[cmd1, cmd2]
183
- run several LLDB commands, one by another
184
- force_return=value
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(ns({
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
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '3.0.0'
21
- __version_tuple__ = version_tuple = (3, 0, 0)
20
+ __version__ = version = '3.1.0'
21
+ __version_tuple__ = version_tuple = (3, 1, 0)
@@ -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
- return (f'<{self.__class__.__name__} LLDB:{self.lldb_breakpoint} GUARDED:{self.guarded} '
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
- result = f'🚨 Breakpoint #{self.id} (guarded: {self.guarded}):\n'
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
- print(bp)
468
+ self._hilda.log_info(bp)
446
469
 
447
470
  def items(self):
448
471
  """