hilda 3.1.0__tar.gz → 3.2.1__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 (82) hide show
  1. {hilda-3.1.0 → hilda-3.2.1}/PKG-INFO +19 -25
  2. {hilda-3.1.0 → hilda-3.2.1}/README.md +18 -24
  3. {hilda-3.1.0 → hilda-3.2.1}/hilda/_version.py +16 -3
  4. {hilda-3.1.0 → hilda-3.2.1}/hilda/breakpoints.py +4 -4
  5. {hilda-3.1.0 → hilda-3.2.1}/hilda/decorators.py +1 -0
  6. {hilda-3.1.0 → hilda-3.2.1}/hilda/exceptions.py +1 -6
  7. {hilda-3.1.0 → hilda-3.2.1}/hilda/hilda_client.py +21 -70
  8. {hilda-3.1.0 → hilda-3.2.1}/hilda/ipython_extensions/events.py +14 -18
  9. {hilda-3.1.0 → hilda-3.2.1}/hilda/objective_c_class.py +86 -29
  10. {hilda-3.1.0 → hilda-3.2.1}/hilda/objective_c_symbol.py +5 -16
  11. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/libmalloc.py +9 -9
  12. {hilda-3.1.0 → hilda-3.2.1}/hilda/symbol.py +48 -12
  13. hilda-3.2.1/hilda/symbols.py +595 -0
  14. {hilda-3.1.0 → hilda-3.2.1}/hilda/watchpoints.py +5 -5
  15. {hilda-3.1.0 → hilda-3.2.1}/hilda.egg-info/PKG-INFO +19 -25
  16. {hilda-3.1.0 → hilda-3.2.1}/hilda.egg-info/SOURCES.txt +2 -3
  17. {hilda-3.1.0 → hilda-3.2.1}/tests/test_symbols/test_objective_c_symbol.py +1 -1
  18. hilda-3.2.1/tests/test_symbols/test_symbol_list.py +136 -0
  19. hilda-3.1.0/hilda/symbols_jar.py +0 -208
  20. hilda-3.1.0/tests/test_hilda_client/test_rebind_symbols.py +0 -6
  21. hilda-3.1.0/tests/test_symbols/test_symbols_jar.py +0 -38
  22. {hilda-3.1.0 → hilda-3.2.1}/.github/workflows/python-app.yml +0 -0
  23. {hilda-3.1.0 → hilda-3.2.1}/.github/workflows/python-publish.yml +0 -0
  24. {hilda-3.1.0 → hilda-3.2.1}/.gitignore +0 -0
  25. {hilda-3.1.0 → hilda-3.2.1}/.pre-commit-config.yaml +0 -0
  26. {hilda-3.1.0 → hilda-3.2.1}/LICENSE +0 -0
  27. {hilda-3.1.0 → hilda-3.2.1}/gifs/.gitattributes +0 -0
  28. {hilda-3.1.0 → hilda-3.2.1}/gifs/ui.png +0 -0
  29. {hilda-3.1.0 → hilda-3.2.1}/gifs/xpc_print_message.gif +0 -0
  30. {hilda-3.1.0 → hilda-3.2.1}/hilda/__init__.py +0 -0
  31. {hilda-3.1.0 → hilda-3.2.1}/hilda/__main__.py +0 -0
  32. {hilda-3.1.0 → hilda-3.2.1}/hilda/cli.py +0 -0
  33. {hilda-3.1.0 → hilda-3.2.1}/hilda/common.py +0 -0
  34. {hilda-3.1.0 → hilda-3.2.1}/hilda/ipython_extensions/keybindings.py +0 -0
  35. {hilda-3.1.0 → hilda-3.2.1}/hilda/ipython_extensions/magics.py +0 -0
  36. {hilda-3.1.0 → hilda-3.2.1}/hilda/launch_lldb.py +0 -0
  37. {hilda-3.1.0 → hilda-3.2.1}/hilda/lldb_entrypoint.py +0 -0
  38. {hilda-3.1.0 → hilda-3.2.1}/hilda/lldb_importer.py +0 -0
  39. {hilda-3.1.0 → hilda-3.2.1}/hilda/objective_c/from_ns_to_json.m +0 -0
  40. {hilda-3.1.0 → hilda-3.2.1}/hilda/objective_c/get_objectivec_class_by_module.m +0 -0
  41. {hilda-3.1.0 → hilda-3.2.1}/hilda/objective_c/get_objectivec_class_description.m +0 -0
  42. {hilda-3.1.0 → hilda-3.2.1}/hilda/objective_c/get_objectivec_symbol_data.m +0 -0
  43. {hilda-3.1.0 → hilda-3.2.1}/hilda/objective_c/lsof.m +0 -0
  44. {hilda-3.1.0 → hilda-3.2.1}/hilda/objective_c/to_ns_from_json.m +0 -0
  45. {hilda-3.1.0 → hilda-3.2.1}/hilda/registers.py +0 -0
  46. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/__init__.py +0 -0
  47. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/boringssl.py +0 -0
  48. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/collections.py +0 -0
  49. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/dyld.py +0 -0
  50. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/fs_utils.py +0 -0
  51. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/mach/CFRunLoopServiceMachPort_hooks.py +0 -0
  52. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/mach/__init__.py +0 -0
  53. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/macho/__init__.py +0 -0
  54. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/macho/all_image_infos.py +0 -0
  55. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/macho/apple_version.py +0 -0
  56. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/macho/image_info.py +0 -0
  57. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/macho/macho.py +0 -0
  58. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/macho/macho_load_commands.py +0 -0
  59. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/remotepairingd.py +0 -0
  60. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/syslog.py +0 -0
  61. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/uuid.py +0 -0
  62. {hilda-3.1.0 → hilda-3.2.1}/hilda/snippets/xpc.py +0 -0
  63. {hilda-3.1.0 → hilda-3.2.1}/hilda/ui/colors.json +0 -0
  64. {hilda-3.1.0 → hilda-3.2.1}/hilda/ui/ui_manager.py +0 -0
  65. {hilda-3.1.0 → hilda-3.2.1}/hilda/ui/views.py +0 -0
  66. {hilda-3.1.0 → hilda-3.2.1}/hilda.egg-info/dependency_links.txt +0 -0
  67. {hilda-3.1.0 → hilda-3.2.1}/hilda.egg-info/entry_points.txt +0 -0
  68. {hilda-3.1.0 → hilda-3.2.1}/hilda.egg-info/requires.txt +0 -0
  69. {hilda-3.1.0 → hilda-3.2.1}/hilda.egg-info/top_level.txt +0 -0
  70. {hilda-3.1.0 → hilda-3.2.1}/pyproject.toml +0 -0
  71. {hilda-3.1.0 → hilda-3.2.1}/requirements.txt +0 -0
  72. {hilda-3.1.0 → hilda-3.2.1}/setup.cfg +0 -0
  73. {hilda-3.1.0 → hilda-3.2.1}/tests/__init__.py +0 -0
  74. {hilda-3.1.0 → hilda-3.2.1}/tests/conftest.py +0 -0
  75. {hilda-3.1.0 → hilda-3.2.1}/tests/test_hilda_client/test_from_ns.py +0 -0
  76. {hilda-3.1.0 → hilda-3.2.1}/tests/test_hilda_client/test_hilda_client.py +0 -0
  77. {hilda-3.1.0 → hilda-3.2.1}/tests/test_hilda_client/test_monitor.py +0 -0
  78. {hilda-3.1.0 → hilda-3.2.1}/tests/test_hilda_client/test_ns.py +0 -0
  79. {hilda-3.1.0 → hilda-3.2.1}/tests/test_hilda_client/test_registers.py +0 -0
  80. {hilda-3.1.0 → hilda-3.2.1}/tests/test_snippets/test_xpc.py +0 -0
  81. {hilda-3.1.0 → hilda-3.2.1}/tests/test_symbols/test_objective_c_class.py +0 -0
  82. {hilda-3.1.0 → hilda-3.2.1}/tests/test_symbols/test_symbol.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hilda
3
- Version: 3.1.0
3
+ Version: 3.2.1
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>
@@ -129,7 +129,7 @@ You can may start a Hilda interactive shell by invoking any of the subcommand:
129
129
  - `hilda attach [-p pid] [-n process-name]`
130
130
  - Attach to an already running process on current host (specified by either `pid` or `process-name`)
131
131
  - `hilda remote HOSTNAME PORT`
132
- - Attach to an already running process on a target host (sepcified by `HOSTNAME PORT`)
132
+ - Attach to an already running process on a target host (specified by `HOSTNAME PORT`)
133
133
  - `hilda bare`
134
134
  - Only start an LLDB shell and load Hilda as a plugin.
135
135
  - Please refer to the following help page if you require help on the command available to you within the lldb shell:
@@ -145,8 +145,8 @@ You can may start a Hilda interactive shell by invoking any of the subcommand:
145
145
  ... and attaching to a local process:
146
146
 
147
147
  ```shell
148
- process attach -n proccess_name
149
- process attach -p proccess_pid
148
+ process attach -n process_name
149
+ process attach -p process_pid
150
150
  ```
151
151
 
152
152
  When you are ready, just execute `hilda` to move to Hilda's iPython shell.
@@ -164,7 +164,7 @@ Basic flow control:
164
164
  - `step_into` - Step into current instruction
165
165
  - `step_over` - Step over current instruction.
166
166
  - `run_for` - Run the process for given interval
167
- - `force_return` - Prematurely return from a stack frame, short-circuiting exection of inner
167
+ - `force_return` - Prematurely return from a stack frame, short-circuiting execution of inner
168
168
  frames and optionally yielding a specified value.
169
169
  - `jump` - Jump to given symbol
170
170
  - `wait_for_module` - Wait for a module to be loaded (`dlopen`) by checking if given expression is contained within its filename
@@ -176,7 +176,7 @@ Breakpoints:
176
176
  - `breakpoints.show` - Show existing breakpoints
177
177
  - `breakpoints.remove` - Remove a single breakpoint
178
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.)
179
+ - `monitor` or `breakpoints.add_monitor` - Creates a breakpoint whose callback implements the requested features (print register values, execute commands, mock return value, etc.)
180
180
 
181
181
  Basic read/write:
182
182
 
@@ -212,7 +212,6 @@ Hilda symbols:
212
212
 
213
213
  - `symbol` - Get symbol object for a given address
214
214
  - `objc_symbol` - Get objc symbol wrapper for given address
215
- - `rebind_symbols` - Reparse all loaded images symbols
216
215
  - `file_symbol` - Calculate symbol address without ASLR
217
216
  - `save` - Save loaded symbols map (for loading later using the load() command)
218
217
  - `load` - Load an existing symbols map (previously saved by the save() command)
@@ -293,7 +292,7 @@ ui.show()
293
292
  ```
294
293
 
295
294
  By default `step_into` and `step_over` will show this UI automatically.
296
- You may disable this behaviour by executing:
295
+ You may disable this behavior by executing:
297
296
 
298
297
  ```python
299
298
  ui.active = False
@@ -417,7 +416,7 @@ s[0] = 1
417
416
  s[0] = p.symbol(0x11223344)() # calling symbols also returns symbols
418
417
 
419
418
  # attempt to resolve symbol's name
420
- print(p.symbol(0x11223344).lldb_symbol)
419
+ print(p.symbol(0x11223344).lldb_address)
421
420
 
422
421
  # monitor each time a symbol is called into console and print its backtrace (`bt` option)
423
422
  # this will create a scripted breakpoint which prints your desired data and continue
@@ -467,8 +466,8 @@ p.bp(('symbol_name', 'ModuleName'))
467
466
  #### Globalized symbols
468
467
 
469
468
  Usually you would want/need to use the symbols already mapped into the currently running process. To do so, you can
470
- access them using `symbols.<symbol-name>`. The `symbols` global object is of type `SymbolsJar`, which is a wrapper
471
- to `dict` for accessing all exported symbols. For example, the following will generate a call to the exported
469
+ access them using `symbols.<symbol-name>`. The `symbols` global object is of type `SymbolList`, which acts like
470
+ `dict` for accessing all exported symbols. For example, the following will generate a call to the exported
472
471
  `malloc` function with `20` as its only argument:
473
472
 
474
473
  ```python
@@ -491,22 +490,17 @@ x = malloc(20)
491
490
  Sometimes you don't really know where to start your research. All you have is just theories of how your desired exported
492
491
  symbol should be called (if any).
493
492
 
494
- For that reason alone, we have the `rebind_symbols()`
495
- command - to help you find the symbol you are looking for.
496
-
497
493
  ```python
498
- p.rebind_symbols() # this might take some time
499
-
500
494
  # find all symbols prefixed as `mem*` AND don't have `cpy`
501
495
  # in their name
502
- jar = p.symbols.startswith('mem') - p.symbols.find('cpy')
496
+ l = p.symbols.filter_startswith('mem') - p.symbols.filter_name_contains('cpy')
503
497
 
504
498
  # filter only symbols of type "code" (removing data global for example)
505
- jar = jar.code()
499
+ l = l.filter_code_symbols()
506
500
 
507
501
  # monitor every time each one is called, print its `x0` in HEX
508
502
  # form and show the backtrace
509
- jar.monitor(regs={'x0': 'x'}, bt=True)
503
+ l.monitor(regs={'x0': 'x'}, bt=True)
510
504
  ```
511
505
 
512
506
  #### Objective-C Classes
@@ -538,21 +532,21 @@ print(NSDictionary.ivars)
538
532
  # show the class' methods
539
533
  print(NSDictionary.methods)
540
534
 
541
- # show the class' proprties
535
+ # show the class' properties
542
536
  print(NSDictionary.properties)
543
537
 
544
538
  # view class' selectors which are prefixed with 'init'
545
- print(NSDictionary.symbols_jar.startswith('-[NSDictionary init'))
539
+ print(NSDictionary.methods.filter_startswith('init'))
546
540
 
547
- # you can of course use any of `SymbolsJar` over them, for example:
541
+ # you can of course use any of `SymbolList` over them, for example:
548
542
  # this will `po` (print object) all those selectors returned value
549
- NSDictionary.symbols_jar.startswith('-[NSDictionary init').monitior(retval='po')
543
+ NSDictionary.methods.filter_startswith('init').monitor(retval='po')
550
544
 
551
545
  # monitor each time any selector in NSDictionary is called
552
546
  NSDictionary.monitor()
553
547
 
554
548
  # `force_return` for some specific selector with a hard-coded value (4)
555
- NSDictionary.get_method('valueForKey:').address.monitor(force_return=4)
549
+ NSDictionary.methods.get('valueForKey:').address.monitor(force_return=4)
556
550
 
557
551
  # capture the `self` object at the first hit of any selector
558
552
  # `True` for busy-wait for object to be captured
@@ -637,7 +631,7 @@ They all use the following concept to use:
637
631
  ```python
638
632
  from hilda.snippets import snippet_name
639
633
 
640
- snippet_name.do_domething()
634
+ snippet_name.do_something()
641
635
  ```
642
636
 
643
637
  For example, XPC sniffing can be done using:
@@ -70,7 +70,7 @@ You can may start a Hilda interactive shell by invoking any of the subcommand:
70
70
  - `hilda attach [-p pid] [-n process-name]`
71
71
  - Attach to an already running process on current host (specified by either `pid` or `process-name`)
72
72
  - `hilda remote HOSTNAME PORT`
73
- - Attach to an already running process on a target host (sepcified by `HOSTNAME PORT`)
73
+ - Attach to an already running process on a target host (specified by `HOSTNAME PORT`)
74
74
  - `hilda bare`
75
75
  - Only start an LLDB shell and load Hilda as a plugin.
76
76
  - Please refer to the following help page if you require help on the command available to you within the lldb shell:
@@ -86,8 +86,8 @@ You can may start a Hilda interactive shell by invoking any of the subcommand:
86
86
  ... and attaching to a local process:
87
87
 
88
88
  ```shell
89
- process attach -n proccess_name
90
- process attach -p proccess_pid
89
+ process attach -n process_name
90
+ process attach -p process_pid
91
91
  ```
92
92
 
93
93
  When you are ready, just execute `hilda` to move to Hilda's iPython shell.
@@ -105,7 +105,7 @@ Basic flow control:
105
105
  - `step_into` - Step into current instruction
106
106
  - `step_over` - Step over current instruction.
107
107
  - `run_for` - Run the process for given interval
108
- - `force_return` - Prematurely return from a stack frame, short-circuiting exection of inner
108
+ - `force_return` - Prematurely return from a stack frame, short-circuiting execution of inner
109
109
  frames and optionally yielding a specified value.
110
110
  - `jump` - Jump to given symbol
111
111
  - `wait_for_module` - Wait for a module to be loaded (`dlopen`) by checking if given expression is contained within its filename
@@ -117,7 +117,7 @@ Breakpoints:
117
117
  - `breakpoints.show` - Show existing breakpoints
118
118
  - `breakpoints.remove` - Remove a single breakpoint
119
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.)
120
+ - `monitor` or `breakpoints.add_monitor` - Creates a breakpoint whose callback implements the requested features (print register values, execute commands, mock return value, etc.)
121
121
 
122
122
  Basic read/write:
123
123
 
@@ -153,7 +153,6 @@ Hilda symbols:
153
153
 
154
154
  - `symbol` - Get symbol object for a given address
155
155
  - `objc_symbol` - Get objc symbol wrapper for given address
156
- - `rebind_symbols` - Reparse all loaded images symbols
157
156
  - `file_symbol` - Calculate symbol address without ASLR
158
157
  - `save` - Save loaded symbols map (for loading later using the load() command)
159
158
  - `load` - Load an existing symbols map (previously saved by the save() command)
@@ -234,7 +233,7 @@ ui.show()
234
233
  ```
235
234
 
236
235
  By default `step_into` and `step_over` will show this UI automatically.
237
- You may disable this behaviour by executing:
236
+ You may disable this behavior by executing:
238
237
 
239
238
  ```python
240
239
  ui.active = False
@@ -358,7 +357,7 @@ s[0] = 1
358
357
  s[0] = p.symbol(0x11223344)() # calling symbols also returns symbols
359
358
 
360
359
  # attempt to resolve symbol's name
361
- print(p.symbol(0x11223344).lldb_symbol)
360
+ print(p.symbol(0x11223344).lldb_address)
362
361
 
363
362
  # monitor each time a symbol is called into console and print its backtrace (`bt` option)
364
363
  # this will create a scripted breakpoint which prints your desired data and continue
@@ -408,8 +407,8 @@ p.bp(('symbol_name', 'ModuleName'))
408
407
  #### Globalized symbols
409
408
 
410
409
  Usually you would want/need to use the symbols already mapped into the currently running process. To do so, you can
411
- access them using `symbols.<symbol-name>`. The `symbols` global object is of type `SymbolsJar`, which is a wrapper
412
- to `dict` for accessing all exported symbols. For example, the following will generate a call to the exported
410
+ access them using `symbols.<symbol-name>`. The `symbols` global object is of type `SymbolList`, which acts like
411
+ `dict` for accessing all exported symbols. For example, the following will generate a call to the exported
413
412
  `malloc` function with `20` as its only argument:
414
413
 
415
414
  ```python
@@ -432,22 +431,17 @@ x = malloc(20)
432
431
  Sometimes you don't really know where to start your research. All you have is just theories of how your desired exported
433
432
  symbol should be called (if any).
434
433
 
435
- For that reason alone, we have the `rebind_symbols()`
436
- command - to help you find the symbol you are looking for.
437
-
438
434
  ```python
439
- p.rebind_symbols() # this might take some time
440
-
441
435
  # find all symbols prefixed as `mem*` AND don't have `cpy`
442
436
  # in their name
443
- jar = p.symbols.startswith('mem') - p.symbols.find('cpy')
437
+ l = p.symbols.filter_startswith('mem') - p.symbols.filter_name_contains('cpy')
444
438
 
445
439
  # filter only symbols of type "code" (removing data global for example)
446
- jar = jar.code()
440
+ l = l.filter_code_symbols()
447
441
 
448
442
  # monitor every time each one is called, print its `x0` in HEX
449
443
  # form and show the backtrace
450
- jar.monitor(regs={'x0': 'x'}, bt=True)
444
+ l.monitor(regs={'x0': 'x'}, bt=True)
451
445
  ```
452
446
 
453
447
  #### Objective-C Classes
@@ -479,21 +473,21 @@ print(NSDictionary.ivars)
479
473
  # show the class' methods
480
474
  print(NSDictionary.methods)
481
475
 
482
- # show the class' proprties
476
+ # show the class' properties
483
477
  print(NSDictionary.properties)
484
478
 
485
479
  # view class' selectors which are prefixed with 'init'
486
- print(NSDictionary.symbols_jar.startswith('-[NSDictionary init'))
480
+ print(NSDictionary.methods.filter_startswith('init'))
487
481
 
488
- # you can of course use any of `SymbolsJar` over them, for example:
482
+ # you can of course use any of `SymbolList` over them, for example:
489
483
  # this will `po` (print object) all those selectors returned value
490
- NSDictionary.symbols_jar.startswith('-[NSDictionary init').monitior(retval='po')
484
+ NSDictionary.methods.filter_startswith('init').monitor(retval='po')
491
485
 
492
486
  # monitor each time any selector in NSDictionary is called
493
487
  NSDictionary.monitor()
494
488
 
495
489
  # `force_return` for some specific selector with a hard-coded value (4)
496
- NSDictionary.get_method('valueForKey:').address.monitor(force_return=4)
490
+ NSDictionary.methods.get('valueForKey:').address.monitor(force_return=4)
497
491
 
498
492
  # capture the `self` object at the first hit of any selector
499
493
  # `True` for busy-wait for object to be captured
@@ -578,7 +572,7 @@ They all use the following concept to use:
578
572
  ```python
579
573
  from hilda.snippets import snippet_name
580
574
 
581
- snippet_name.do_domething()
575
+ snippet_name.do_something()
582
576
  ```
583
577
 
584
578
  For example, XPC sniffing can be done using:
@@ -1,7 +1,14 @@
1
1
  # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
3
 
4
- __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
5
12
 
6
13
  TYPE_CHECKING = False
7
14
  if TYPE_CHECKING:
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
9
16
  from typing import Union
10
17
 
11
18
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
12
20
  else:
13
21
  VERSION_TUPLE = object
22
+ COMMIT_ID = object
14
23
 
15
24
  version: str
16
25
  __version__: str
17
26
  __version_tuple__: VERSION_TUPLE
18
27
  version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
19
30
 
20
- __version__ = version = '3.1.0'
21
- __version_tuple__ = version_tuple = (3, 1, 0)
31
+ __version__ = version = '3.2.1'
32
+ __version_tuple__ = version_tuple = (3, 2, 1)
33
+
34
+ __commit_id__ = commit_id = 'g44204a25f'
@@ -157,7 +157,7 @@ class HildaBreakpoint:
157
157
  # A single breakpoint may be related to several locations (addresses)
158
158
  locations = self.locations
159
159
  if len(locations) == 0:
160
- result += f'\tNo locations\n'
160
+ result += '\tNo locations\n'
161
161
  for location in self.locations:
162
162
  result += f'\tLocation {location}\n'
163
163
 
@@ -227,6 +227,7 @@ class BreakpointList:
227
227
  if it does not exist.
228
228
 
229
229
  :param id_or_name_or_bp: Breakpoint's ID or name (or the breakpoint itself)
230
+ :return: `HildaBreakpoint` if one exists, or `None` otherwise
230
231
  """
231
232
 
232
233
  if isinstance(id_or_name_or_bp, int):
@@ -362,14 +363,13 @@ class BreakpointList:
362
363
  :param frame: LLDB frame
363
364
  :param bp_loc: LLDB breakpoint location
364
365
  """
365
- nonlocal regs, expr, retval, stop, bt, cmd, force_return, name
366
+ nonlocal name
366
367
  bp = bp_loc.GetBreakpoint()
367
368
  symbol = hilda.symbol(hilda.frame.addr.GetLoadAddress(hilda.target))
368
369
  thread = hilda.thread
369
- printed_name = name if name is not None else str(symbol.lldb_symbol)
370
+ printed_name = name if name is not None else str(symbol.lldb_address)
370
371
 
371
372
  def format_value(fmt: Union[str, Callable], value: Symbol) -> str:
372
- nonlocal hilda
373
373
  if callable(fmt):
374
374
  return fmt(hilda, value)
375
375
  formatters = {
@@ -1,5 +1,6 @@
1
1
  from hilda.breakpoints import WhereType
2
2
  from hilda.lldb_importer import lldb
3
+
3
4
  p = lldb.hilda_client
4
5
 
5
6
 
@@ -1,7 +1,7 @@
1
1
  __all__ = ['HildaException', 'SymbolAbsentError', 'EvaluatingExpressionError', 'CreatingObjectiveCSymbolError',
2
2
  'ConvertingToNsObjectError', 'ConvertingFromNSObjectError', 'DisableJetsamMemoryChecksError',
3
3
  'GettingObjectiveCClassError', 'AccessingRegisterError', 'AccessingMemoryError',
4
- 'BrokenLocalSymbolsJarError', 'AddingLldbSymbolError', 'LLDBError', 'InvalidThreadIndexError']
4
+ 'AddingLldbSymbolError', 'LLDBError', 'InvalidThreadIndexError']
5
5
 
6
6
 
7
7
  class HildaException(Exception):
@@ -59,11 +59,6 @@ class AccessingMemoryError(HildaException):
59
59
  pass
60
60
 
61
61
 
62
- class BrokenLocalSymbolsJarError(HildaException):
63
- """ Raise when attempt to load an invalid symbols jar pickle """
64
- pass
65
-
66
-
67
62
  class AddingLldbSymbolError(HildaException):
68
63
  """ Raise when failing to convert a LLDB symbol to Hilda's symbol. """
69
64
  pass
@@ -10,7 +10,7 @@ import sys
10
10
  import time
11
11
  import typing
12
12
  from collections import namedtuple
13
- from contextlib import contextmanager, suppress
13
+ from contextlib import contextmanager
14
14
  from dataclasses import dataclass, field
15
15
  from datetime import datetime, timezone
16
16
  from functools import cached_property, wraps
@@ -30,17 +30,16 @@ from traitlets.config import Config
30
30
  from hilda import objective_c_class
31
31
  from hilda.breakpoints import BreakpointList, HildaBreakpoint, WhereType
32
32
  from hilda.common import CfSerializable, selection_prompt
33
- from hilda.exceptions import AccessingMemoryError, AccessingRegisterError, AddingLldbSymbolError, \
34
- ConvertingFromNSObjectError, ConvertingToNsObjectError, CreatingObjectiveCSymbolError, \
35
- DisableJetsamMemoryChecksError, EvaluatingExpressionError, HildaException, InvalidThreadIndexError, \
36
- SymbolAbsentError
33
+ from hilda.exceptions import AccessingMemoryError, AccessingRegisterError, ConvertingFromNSObjectError, \
34
+ ConvertingToNsObjectError, CreatingObjectiveCSymbolError, DisableJetsamMemoryChecksError, \
35
+ EvaluatingExpressionError, HildaException, InvalidThreadIndexError, SymbolAbsentError
37
36
  from hilda.ipython_extensions.keybindings import get_keybindings
38
37
  from hilda.lldb_importer import lldb
39
38
  from hilda.objective_c_symbol import ObjectiveCSymbol
40
39
  from hilda.registers import Registers
41
40
  from hilda.snippets.mach import CFRunLoopServiceMachPort_hooks
42
41
  from hilda.symbol import Symbol
43
- from hilda.symbols_jar import SymbolsJar
42
+ from hilda.symbols import SymbolList
44
43
  from hilda.ui.ui_manager import UiManager
45
44
  from hilda.watchpoints import WatchpointList
46
45
 
@@ -127,7 +126,7 @@ class HildaClient:
127
126
  self.debugger = debugger
128
127
  self.target = debugger.GetSelectedTarget()
129
128
  self.process = self.target.GetProcess()
130
- self.symbols = SymbolsJar.create(self)
129
+ self.symbols = SymbolList(self)
131
130
  self.breakpoints = BreakpointList(self)
132
131
  self.watchpoints = WatchpointList(self)
133
132
  self.captured_objects = {}
@@ -201,7 +200,7 @@ class HildaClient:
201
200
  :param address:
202
201
  :return: Hilda's symbol object
203
202
  """
204
- return Symbol.create(address, self)
203
+ return self.symbols.add(address)
205
204
 
206
205
  def objc_symbol(self, address: int) -> ObjectiveCSymbol:
207
206
  """
@@ -214,18 +213,18 @@ class HildaClient:
214
213
  except HildaException as e:
215
214
  raise CreatingObjectiveCSymbolError from e
216
215
 
217
- def inject(self, filename: str) -> SymbolsJar:
216
+ def inject(self, filename: str) -> SymbolList:
218
217
  """
219
218
  Inject a single library into currently running process.
220
219
 
221
220
  :param filename: library to inject (dylib)
222
- :return: SymbolsJar
221
+ :return: SymbolList
223
222
  """
224
223
  module = self.target.FindModule(lldb.SBFileSpec(os.path.basename(filename), False))
225
224
  if module.file.basename is not None:
226
225
  self.log_warning(f'file {filename} has already been loaded')
227
226
 
228
- injected = SymbolsJar.create(self)
227
+ injected = SymbolList(self)
229
228
  handle = self.symbols.dlopen(filename, 10) # RTLD_GLOBAL|RTLD_NOW
230
229
 
231
230
  if handle == 0:
@@ -247,34 +246,9 @@ class HildaClient:
247
246
  # ignore unnamed symbols and those which are not: data, code or objc classes
248
247
  continue
249
248
 
250
- injected[name] = self.symbol(load_addr)
249
+ injected.add(self.symbol(load_addr), name)
251
250
  return injected
252
251
 
253
- def rebind_symbols(self, image_range=None, filename_expr=''):
254
- """
255
- Reparse all loaded images symbols
256
- :param image_range: index range for images to load in the form of [start, end]
257
- :param filename_expr: filter only images containing given expression
258
- """
259
- self.log_debug('mapping symbols')
260
- self._symbols_loaded = False
261
-
262
- for i, module in enumerate(tqdm(self.target.modules)):
263
- filename = module.file.basename
264
-
265
- if filename_expr not in filename:
266
- continue
267
-
268
- if image_range is not None and (i < image_range[0] or i > image_range[1]):
269
- continue
270
-
271
- for symbol in module:
272
- with suppress(AddingLldbSymbolError):
273
- self.add_lldb_symbol(symbol)
274
-
275
- globals()['symbols'] = self.symbols
276
- self._symbols_loaded = True
277
-
278
252
  @stop_is_needed
279
253
  def poke(self, address, buf: bytes):
280
254
  """
@@ -594,7 +568,7 @@ class HildaClient:
594
568
  """ jump to given symbol """
595
569
  self.lldb_handle_command(f'j *{symbol}')
596
570
 
597
- def lldb_handle_command(self, cmd: str) -> None:
571
+ def lldb_handle_command(self, cmd: str, capture_output: bool = False) -> Optional[str]:
598
572
  """
599
573
  Execute an LLDB command
600
574
 
@@ -602,8 +576,15 @@ class HildaClient:
602
576
  lldb_handle_command('register read')
603
577
 
604
578
  :param cmd: LLDB command
579
+ :param capture_output: True if capturing the command output
580
+ :return: The output if capture was requested, None if not or the command failed
605
581
  """
606
- self.debugger.HandleCommand(cmd)
582
+ if capture_output:
583
+ result = lldb.SBCommandReturnObject()
584
+ self.debugger.GetCommandInterpreter().HandleCommand(cmd, result)
585
+ return result.GetOutput() if result.Succeeded() else None
586
+ else:
587
+ self.debugger.HandleCommand(cmd)
607
588
 
608
589
  def objc_get_class(self, name: str, module_name: Optional[str] = None) -> objective_c_class.Class:
609
590
  """
@@ -828,36 +809,6 @@ class HildaClient:
828
809
  """ Log at info level """
829
810
  self.logger.info(message)
830
811
 
831
- def add_lldb_symbol(self, symbol: lldb.SBSymbol) -> Symbol:
832
- """
833
- Convert an LLDB symbol into Hilda's symbol object and insert into `symbols` global
834
- :param symbol: LLDB symbol
835
- :return: converted symbol
836
- :raise AddingLldbSymbolError: Hilda failed to convert the LLDB symbol.
837
- """
838
- load_addr = symbol.addr.GetLoadAddress(self.target)
839
- if load_addr == 0xffffffffffffffff:
840
- # skip those not having a real address
841
- raise AddingLldbSymbolError()
842
-
843
- name = symbol.name
844
- type_ = symbol.GetType()
845
-
846
- if name in ('<redacted>',) or (type_ not in (lldb.eSymbolTypeCode,
847
- lldb.eSymbolTypeRuntime,
848
- lldb.eSymbolTypeData,
849
- lldb.eSymbolTypeObjCMetaClass)):
850
- # ignore unnamed symbols and those which are not in a really used type
851
- raise AddingLldbSymbolError()
852
-
853
- value = self.symbol(load_addr)
854
-
855
- # add it into symbols global
856
- self.symbols[name] = value
857
- self.symbols[f'{name}{{{value.filename}}}'] = value
858
-
859
- return value
860
-
861
812
  def wait_for_module(self, expression: str) -> None:
862
813
  """ Wait for a module to be loaded using `dlopen` by matching given expression """
863
814
  self.log_info(f'Waiting for module name containing "{expression}" to be loaded')
@@ -901,7 +852,7 @@ class HildaClient:
901
852
 
902
853
  # Configure and start IPython shell
903
854
  ipython_config = Config()
904
- ipython_config.IPCompleter.use_jedi = True
855
+ ipython_config.IPCompleter.use_jedi = False
905
856
  ipython_config.BaseIPythonApplication.profile = 'hilda'
906
857
  ipython_config.InteractiveShellApp.extensions = ['hilda.ipython_extensions.magics',
907
858
  'hilda.ipython_extensions.events',
@@ -3,10 +3,9 @@ import builtins
3
3
 
4
4
  from IPython.terminal.interactiveshell import TerminalInteractiveShell
5
5
 
6
- from hilda.exceptions import EvaluatingExpressionError, SymbolAbsentError
6
+ from hilda.exceptions import EvaluatingExpressionError
7
7
  from hilda.hilda_client import HildaClient
8
8
  from hilda.lldb_importer import lldb
9
- from hilda.symbols_jar import SymbolsJar
10
9
 
11
10
 
12
11
  class HIEvents:
@@ -30,22 +29,19 @@ class HIEvents:
30
29
  # That are undefined
31
30
  continue
32
31
 
33
- if not hasattr(SymbolsJar, node.id):
34
- # ignore SymbolsJar properties
35
- try:
36
- symbol = getattr(self.hilda_client.symbols, node.id)
37
- except SymbolAbsentError:
38
- pass
39
- else:
40
- try:
41
- self.hilda_client._add_global(
42
- node.id,
43
- symbol if symbol.type_ != lldb.eSymbolTypeObjCMetaClass else self.hilda_client.objc_get_class(
44
- node.id)
45
- )
46
- except EvaluatingExpressionError:
47
- self.hilda_client.log_warning(
48
- f'Process is running. Pause execution in order to resolve "{node.id}"')
32
+ symbol = self.hilda_client.symbols.get(node.id)
33
+ if symbol is None:
34
+ continue
35
+
36
+ try:
37
+ self.hilda_client._add_global(
38
+ node.id,
39
+ symbol if symbol.type_ != lldb.eSymbolTypeObjCMetaClass else self.hilda_client.objc_get_class(
40
+ node.id)
41
+ )
42
+ except EvaluatingExpressionError:
43
+ self.hilda_client.log_warning(
44
+ f'Process is running. Pause execution in order to resolve "{node.id}"')
49
45
 
50
46
 
51
47
  def load_ipython_extension(ip: TerminalInteractiveShell):