hilda 3.1.0__tar.gz → 3.2.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 (82) hide show
  1. {hilda-3.1.0 → hilda-3.2.0}/PKG-INFO +19 -25
  2. {hilda-3.1.0 → hilda-3.2.0}/README.md +18 -24
  3. {hilda-3.1.0 → hilda-3.2.0}/hilda/_version.py +2 -2
  4. {hilda-3.1.0 → hilda-3.2.0}/hilda/breakpoints.py +2 -1
  5. {hilda-3.1.0 → hilda-3.2.0}/hilda/exceptions.py +1 -6
  6. {hilda-3.1.0 → hilda-3.2.0}/hilda/hilda_client.py +17 -65
  7. {hilda-3.1.0 → hilda-3.2.0}/hilda/ipython_extensions/events.py +13 -17
  8. {hilda-3.1.0 → hilda-3.2.0}/hilda/objective_c_class.py +86 -29
  9. {hilda-3.1.0 → hilda-3.2.0}/hilda/objective_c_symbol.py +5 -16
  10. {hilda-3.1.0 → hilda-3.2.0}/hilda/symbol.py +47 -12
  11. hilda-3.2.0/hilda/symbols.py +579 -0
  12. {hilda-3.1.0 → hilda-3.2.0}/hilda/watchpoints.py +5 -5
  13. {hilda-3.1.0 → hilda-3.2.0}/hilda.egg-info/PKG-INFO +19 -25
  14. {hilda-3.1.0 → hilda-3.2.0}/hilda.egg-info/SOURCES.txt +2 -3
  15. {hilda-3.1.0 → hilda-3.2.0}/tests/test_symbols/test_objective_c_symbol.py +1 -1
  16. hilda-3.2.0/tests/test_symbols/test_symbol_list.py +142 -0
  17. hilda-3.1.0/hilda/symbols_jar.py +0 -208
  18. hilda-3.1.0/tests/test_hilda_client/test_rebind_symbols.py +0 -6
  19. hilda-3.1.0/tests/test_symbols/test_symbols_jar.py +0 -38
  20. {hilda-3.1.0 → hilda-3.2.0}/.github/workflows/python-app.yml +0 -0
  21. {hilda-3.1.0 → hilda-3.2.0}/.github/workflows/python-publish.yml +0 -0
  22. {hilda-3.1.0 → hilda-3.2.0}/.gitignore +0 -0
  23. {hilda-3.1.0 → hilda-3.2.0}/.pre-commit-config.yaml +0 -0
  24. {hilda-3.1.0 → hilda-3.2.0}/LICENSE +0 -0
  25. {hilda-3.1.0 → hilda-3.2.0}/gifs/.gitattributes +0 -0
  26. {hilda-3.1.0 → hilda-3.2.0}/gifs/ui.png +0 -0
  27. {hilda-3.1.0 → hilda-3.2.0}/gifs/xpc_print_message.gif +0 -0
  28. {hilda-3.1.0 → hilda-3.2.0}/hilda/__init__.py +0 -0
  29. {hilda-3.1.0 → hilda-3.2.0}/hilda/__main__.py +0 -0
  30. {hilda-3.1.0 → hilda-3.2.0}/hilda/cli.py +0 -0
  31. {hilda-3.1.0 → hilda-3.2.0}/hilda/common.py +0 -0
  32. {hilda-3.1.0 → hilda-3.2.0}/hilda/decorators.py +0 -0
  33. {hilda-3.1.0 → hilda-3.2.0}/hilda/ipython_extensions/keybindings.py +0 -0
  34. {hilda-3.1.0 → hilda-3.2.0}/hilda/ipython_extensions/magics.py +0 -0
  35. {hilda-3.1.0 → hilda-3.2.0}/hilda/launch_lldb.py +0 -0
  36. {hilda-3.1.0 → hilda-3.2.0}/hilda/lldb_entrypoint.py +0 -0
  37. {hilda-3.1.0 → hilda-3.2.0}/hilda/lldb_importer.py +0 -0
  38. {hilda-3.1.0 → hilda-3.2.0}/hilda/objective_c/from_ns_to_json.m +0 -0
  39. {hilda-3.1.0 → hilda-3.2.0}/hilda/objective_c/get_objectivec_class_by_module.m +0 -0
  40. {hilda-3.1.0 → hilda-3.2.0}/hilda/objective_c/get_objectivec_class_description.m +0 -0
  41. {hilda-3.1.0 → hilda-3.2.0}/hilda/objective_c/get_objectivec_symbol_data.m +0 -0
  42. {hilda-3.1.0 → hilda-3.2.0}/hilda/objective_c/lsof.m +0 -0
  43. {hilda-3.1.0 → hilda-3.2.0}/hilda/objective_c/to_ns_from_json.m +0 -0
  44. {hilda-3.1.0 → hilda-3.2.0}/hilda/registers.py +0 -0
  45. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/__init__.py +0 -0
  46. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/boringssl.py +0 -0
  47. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/collections.py +0 -0
  48. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/dyld.py +0 -0
  49. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/fs_utils.py +0 -0
  50. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/libmalloc.py +0 -0
  51. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/mach/CFRunLoopServiceMachPort_hooks.py +0 -0
  52. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/mach/__init__.py +0 -0
  53. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/macho/__init__.py +0 -0
  54. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/macho/all_image_infos.py +0 -0
  55. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/macho/apple_version.py +0 -0
  56. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/macho/image_info.py +0 -0
  57. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/macho/macho.py +0 -0
  58. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/macho/macho_load_commands.py +0 -0
  59. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/remotepairingd.py +0 -0
  60. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/syslog.py +0 -0
  61. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/uuid.py +0 -0
  62. {hilda-3.1.0 → hilda-3.2.0}/hilda/snippets/xpc.py +0 -0
  63. {hilda-3.1.0 → hilda-3.2.0}/hilda/ui/colors.json +0 -0
  64. {hilda-3.1.0 → hilda-3.2.0}/hilda/ui/ui_manager.py +0 -0
  65. {hilda-3.1.0 → hilda-3.2.0}/hilda/ui/views.py +0 -0
  66. {hilda-3.1.0 → hilda-3.2.0}/hilda.egg-info/dependency_links.txt +0 -0
  67. {hilda-3.1.0 → hilda-3.2.0}/hilda.egg-info/entry_points.txt +0 -0
  68. {hilda-3.1.0 → hilda-3.2.0}/hilda.egg-info/requires.txt +0 -0
  69. {hilda-3.1.0 → hilda-3.2.0}/hilda.egg-info/top_level.txt +0 -0
  70. {hilda-3.1.0 → hilda-3.2.0}/pyproject.toml +0 -0
  71. {hilda-3.1.0 → hilda-3.2.0}/requirements.txt +0 -0
  72. {hilda-3.1.0 → hilda-3.2.0}/setup.cfg +0 -0
  73. {hilda-3.1.0 → hilda-3.2.0}/tests/__init__.py +0 -0
  74. {hilda-3.1.0 → hilda-3.2.0}/tests/conftest.py +0 -0
  75. {hilda-3.1.0 → hilda-3.2.0}/tests/test_hilda_client/test_from_ns.py +0 -0
  76. {hilda-3.1.0 → hilda-3.2.0}/tests/test_hilda_client/test_hilda_client.py +0 -0
  77. {hilda-3.1.0 → hilda-3.2.0}/tests/test_hilda_client/test_monitor.py +0 -0
  78. {hilda-3.1.0 → hilda-3.2.0}/tests/test_hilda_client/test_ns.py +0 -0
  79. {hilda-3.1.0 → hilda-3.2.0}/tests/test_hilda_client/test_registers.py +0 -0
  80. {hilda-3.1.0 → hilda-3.2.0}/tests/test_snippets/test_xpc.py +0 -0
  81. {hilda-3.1.0 → hilda-3.2.0}/tests/test_symbols/test_objective_c_class.py +0 -0
  82. {hilda-3.1.0 → hilda-3.2.0}/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.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>
@@ -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:
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '3.1.0'
21
- __version_tuple__ = version_tuple = (3, 1, 0)
20
+ __version__ = version = '3.2.0'
21
+ __version_tuple__ = version_tuple = (3, 2, 0)
@@ -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):
@@ -366,7 +367,7 @@ class BreakpointList:
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
373
  nonlocal hilda
@@ -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
@@ -40,7 +40,7 @@ from hilda.objective_c_symbol import ObjectiveCSymbol
40
40
  from hilda.registers import Registers
41
41
  from hilda.snippets.mach import CFRunLoopServiceMachPort_hooks
42
42
  from hilda.symbol import Symbol
43
- from hilda.symbols_jar import SymbolsJar
43
+ from hilda.symbols import SymbolList
44
44
  from hilda.ui.ui_manager import UiManager
45
45
  from hilda.watchpoints import WatchpointList
46
46
 
@@ -127,7 +127,7 @@ class HildaClient:
127
127
  self.debugger = debugger
128
128
  self.target = debugger.GetSelectedTarget()
129
129
  self.process = self.target.GetProcess()
130
- self.symbols = SymbolsJar.create(self)
130
+ self.symbols = SymbolList(self)
131
131
  self.breakpoints = BreakpointList(self)
132
132
  self.watchpoints = WatchpointList(self)
133
133
  self.captured_objects = {}
@@ -201,7 +201,7 @@ class HildaClient:
201
201
  :param address:
202
202
  :return: Hilda's symbol object
203
203
  """
204
- return Symbol.create(address, self)
204
+ return self.symbols.add(address)
205
205
 
206
206
  def objc_symbol(self, address: int) -> ObjectiveCSymbol:
207
207
  """
@@ -214,18 +214,18 @@ class HildaClient:
214
214
  except HildaException as e:
215
215
  raise CreatingObjectiveCSymbolError from e
216
216
 
217
- def inject(self, filename: str) -> SymbolsJar:
217
+ def inject(self, filename: str) -> SymbolList:
218
218
  """
219
219
  Inject a single library into currently running process.
220
220
 
221
221
  :param filename: library to inject (dylib)
222
- :return: SymbolsJar
222
+ :return: SymbolList
223
223
  """
224
224
  module = self.target.FindModule(lldb.SBFileSpec(os.path.basename(filename), False))
225
225
  if module.file.basename is not None:
226
226
  self.log_warning(f'file {filename} has already been loaded')
227
227
 
228
- injected = SymbolsJar.create(self)
228
+ injected = SymbolList(self)
229
229
  handle = self.symbols.dlopen(filename, 10) # RTLD_GLOBAL|RTLD_NOW
230
230
 
231
231
  if handle == 0:
@@ -247,34 +247,9 @@ class HildaClient:
247
247
  # ignore unnamed symbols and those which are not: data, code or objc classes
248
248
  continue
249
249
 
250
- injected[name] = self.symbol(load_addr)
250
+ injected.add(self.symbol(load_addr), name)
251
251
  return injected
252
252
 
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
253
  @stop_is_needed
279
254
  def poke(self, address, buf: bytes):
280
255
  """
@@ -594,7 +569,7 @@ class HildaClient:
594
569
  """ jump to given symbol """
595
570
  self.lldb_handle_command(f'j *{symbol}')
596
571
 
597
- def lldb_handle_command(self, cmd: str) -> None:
572
+ def lldb_handle_command(self, cmd: str, capture_output: bool = False) -> Optional[str]:
598
573
  """
599
574
  Execute an LLDB command
600
575
 
@@ -602,8 +577,15 @@ class HildaClient:
602
577
  lldb_handle_command('register read')
603
578
 
604
579
  :param cmd: LLDB command
580
+ :param capture_output: True if capturing the command output
581
+ :return: The output if capture was requested, None if not or the command failed
605
582
  """
606
- self.debugger.HandleCommand(cmd)
583
+ if capture_output:
584
+ result = lldb.SBCommandReturnObject()
585
+ self.debugger.GetCommandInterpreter().HandleCommand(cmd, result)
586
+ return result.GetOutput() if result.Succeeded() else None
587
+ else:
588
+ self.debugger.HandleCommand(cmd)
607
589
 
608
590
  def objc_get_class(self, name: str, module_name: Optional[str] = None) -> objective_c_class.Class:
609
591
  """
@@ -828,36 +810,6 @@ class HildaClient:
828
810
  """ Log at info level """
829
811
  self.logger.info(message)
830
812
 
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
813
  def wait_for_module(self, expression: str) -> None:
862
814
  """ Wait for a module to be loaded using `dlopen` by matching given expression """
863
815
  self.log_info(f'Waiting for module name containing "{expression}" to be loaded')
@@ -901,7 +853,7 @@ class HildaClient:
901
853
 
902
854
  # Configure and start IPython shell
903
855
  ipython_config = Config()
904
- ipython_config.IPCompleter.use_jedi = True
856
+ ipython_config.IPCompleter.use_jedi = False
905
857
  ipython_config.BaseIPythonApplication.profile = 'hilda'
906
858
  ipython_config.InteractiveShellApp.extensions = ['hilda.ipython_extensions.magics',
907
859
  'hilda.ipython_extensions.events',
@@ -6,7 +6,6 @@ from IPython.terminal.interactiveshell import TerminalInteractiveShell
6
6
  from hilda.exceptions import EvaluatingExpressionError, SymbolAbsentError
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):