hilda 2.0.0__tar.gz → 2.0.2__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 (78) hide show
  1. {hilda-2.0.0 → hilda-2.0.2}/PKG-INFO +6 -1
  2. {hilda-2.0.0 → hilda-2.0.2}/README.md +4 -0
  3. {hilda-2.0.0 → hilda-2.0.2}/hilda/_version.py +2 -2
  4. {hilda-2.0.0 → hilda-2.0.2}/hilda/cli.py +4 -4
  5. hilda-2.0.2/hilda/common.py +14 -0
  6. {hilda-2.0.0 → hilda-2.0.2}/hilda/exceptions.py +6 -1
  7. {hilda-2.0.0 → hilda-2.0.2}/hilda/hilda_client.py +16 -9
  8. {hilda-2.0.0 → hilda-2.0.2}/hilda/ipython_extensions/keybindings.py +2 -2
  9. {hilda-2.0.0 → hilda-2.0.2}/hilda/launch_lldb.py +15 -2
  10. {hilda-2.0.0 → hilda-2.0.2}/hilda.egg-info/PKG-INFO +6 -1
  11. {hilda-2.0.0 → hilda-2.0.2}/hilda.egg-info/requires.txt +1 -0
  12. {hilda-2.0.0 → hilda-2.0.2}/requirements.txt +2 -1
  13. hilda-2.0.0/hilda/common.py +0 -5
  14. {hilda-2.0.0 → hilda-2.0.2}/.github/workflows/python-app.yml +0 -0
  15. {hilda-2.0.0 → hilda-2.0.2}/.github/workflows/python-publish.yml +0 -0
  16. {hilda-2.0.0 → hilda-2.0.2}/.gitignore +0 -0
  17. {hilda-2.0.0 → hilda-2.0.2}/.pre-commit-config.yaml +0 -0
  18. {hilda-2.0.0 → hilda-2.0.2}/LICENSE +0 -0
  19. {hilda-2.0.0 → hilda-2.0.2}/gifs/.gitattributes +0 -0
  20. {hilda-2.0.0 → hilda-2.0.2}/gifs/ui.png +0 -0
  21. {hilda-2.0.0 → hilda-2.0.2}/gifs/xpc_print_message.gif +0 -0
  22. {hilda-2.0.0 → hilda-2.0.2}/hilda/__init__.py +0 -0
  23. {hilda-2.0.0 → hilda-2.0.2}/hilda/__main__.py +0 -0
  24. {hilda-2.0.0 → hilda-2.0.2}/hilda/hilda_ascii_art.html +0 -0
  25. {hilda-2.0.0 → hilda-2.0.2}/hilda/ipython_extensions/events.py +0 -0
  26. {hilda-2.0.0 → hilda-2.0.2}/hilda/ipython_extensions/magics.py +0 -0
  27. {hilda-2.0.0 → hilda-2.0.2}/hilda/lldb_entrypoint.py +0 -0
  28. {hilda-2.0.0 → hilda-2.0.2}/hilda/lldb_importer.py +0 -0
  29. {hilda-2.0.0 → hilda-2.0.2}/hilda/objective_c/from_ns_to_json.m +0 -0
  30. {hilda-2.0.0 → hilda-2.0.2}/hilda/objective_c/get_objectivec_class_by_module.m +0 -0
  31. {hilda-2.0.0 → hilda-2.0.2}/hilda/objective_c/get_objectivec_class_description.m +0 -0
  32. {hilda-2.0.0 → hilda-2.0.2}/hilda/objective_c/get_objectivec_symbol_data.m +0 -0
  33. {hilda-2.0.0 → hilda-2.0.2}/hilda/objective_c/lsof.m +0 -0
  34. {hilda-2.0.0 → hilda-2.0.2}/hilda/objective_c/to_ns_from_json.m +0 -0
  35. {hilda-2.0.0 → hilda-2.0.2}/hilda/objective_c_class.py +0 -0
  36. {hilda-2.0.0 → hilda-2.0.2}/hilda/objective_c_symbol.py +0 -0
  37. {hilda-2.0.0 → hilda-2.0.2}/hilda/registers.py +0 -0
  38. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/__init__.py +0 -0
  39. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/boringssl.py +0 -0
  40. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/collections.py +0 -0
  41. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/dyld.py +0 -0
  42. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/fs_utils.py +0 -0
  43. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/mach/CFRunLoopServiceMachPort_hooks.py +0 -0
  44. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/mach/__init__.py +0 -0
  45. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/macho/__init__.py +0 -0
  46. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/macho/all_image_infos.py +0 -0
  47. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/macho/apple_version.py +0 -0
  48. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/macho/image_info.py +0 -0
  49. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/macho/macho.py +0 -0
  50. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/macho/macho_load_commands.py +0 -0
  51. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/remotepairingd.py +0 -0
  52. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/syslog.py +0 -0
  53. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/uuid.py +0 -0
  54. {hilda-2.0.0 → hilda-2.0.2}/hilda/snippets/xpc.py +0 -0
  55. {hilda-2.0.0 → hilda-2.0.2}/hilda/symbol.py +0 -0
  56. {hilda-2.0.0 → hilda-2.0.2}/hilda/symbols_jar.py +0 -0
  57. {hilda-2.0.0 → hilda-2.0.2}/hilda/ui/colors.json +0 -0
  58. {hilda-2.0.0 → hilda-2.0.2}/hilda/ui/ui_manager.py +0 -0
  59. {hilda-2.0.0 → hilda-2.0.2}/hilda/ui/views.py +0 -0
  60. {hilda-2.0.0 → hilda-2.0.2}/hilda.egg-info/SOURCES.txt +0 -0
  61. {hilda-2.0.0 → hilda-2.0.2}/hilda.egg-info/dependency_links.txt +0 -0
  62. {hilda-2.0.0 → hilda-2.0.2}/hilda.egg-info/entry_points.txt +0 -0
  63. {hilda-2.0.0 → hilda-2.0.2}/hilda.egg-info/top_level.txt +0 -0
  64. {hilda-2.0.0 → hilda-2.0.2}/pyproject.toml +0 -0
  65. {hilda-2.0.0 → hilda-2.0.2}/setup.cfg +0 -0
  66. {hilda-2.0.0 → hilda-2.0.2}/tests/__init__.py +0 -0
  67. {hilda-2.0.0 → hilda-2.0.2}/tests/conftest.py +0 -0
  68. {hilda-2.0.0 → hilda-2.0.2}/tests/test_hilda_client/test_from_ns.py +0 -0
  69. {hilda-2.0.0 → hilda-2.0.2}/tests/test_hilda_client/test_hilda_client.py +0 -0
  70. {hilda-2.0.0 → hilda-2.0.2}/tests/test_hilda_client/test_monitor.py +0 -0
  71. {hilda-2.0.0 → hilda-2.0.2}/tests/test_hilda_client/test_ns.py +0 -0
  72. {hilda-2.0.0 → hilda-2.0.2}/tests/test_hilda_client/test_rebind_symbols.py +0 -0
  73. {hilda-2.0.0 → hilda-2.0.2}/tests/test_hilda_client/test_registers.py +0 -0
  74. {hilda-2.0.0 → hilda-2.0.2}/tests/test_snippets/test_xpc.py +0 -0
  75. {hilda-2.0.0 → hilda-2.0.2}/tests/test_symbols/test_objective_c_class.py +0 -0
  76. {hilda-2.0.0 → hilda-2.0.2}/tests/test_symbols/test_objective_c_symbol.py +0 -0
  77. {hilda-2.0.0 → hilda-2.0.2}/tests/test_symbols/test_symbol.py +0 -0
  78. {hilda-2.0.0 → hilda-2.0.2}/tests/test_symbols/test_symbols_jar.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hilda
3
- Version: 2.0.0
3
+ Version: 2.0.2
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>
@@ -51,6 +51,7 @@ Requires-Dist: construct
51
51
  Requires-Dist: pymobiledevice3
52
52
  Requires-Dist: keystone-engine
53
53
  Requires-Dist: tabulate
54
+ Requires-Dist: inquirer3
54
55
  Provides-Extra: test
55
56
  Requires-Dist: pytest; extra == "test"
56
57
 
@@ -370,6 +371,10 @@ Here is a gist of methods you can access from `p`:
370
371
  - Import & reload given python module (intended mainly for external snippets)
371
372
  - `unwind`
372
373
  - Unwind the stack (useful when get_evaluation_unwind() == False)
374
+ - `set_selected_thread`
375
+ - sets the currently selected thread, which is used in other parts of the program, such as displaying disassembly or
376
+ checking registers.
377
+ This ensures the application focuses on the specified thread for these operations.
373
378
 
374
379
  ## Magic functions
375
380
 
@@ -314,6 +314,10 @@ Here is a gist of methods you can access from `p`:
314
314
  - Import & reload given python module (intended mainly for external snippets)
315
315
  - `unwind`
316
316
  - Unwind the stack (useful when get_evaluation_unwind() == False)
317
+ - `set_selected_thread`
318
+ - sets the currently selected thread, which is used in other parts of the program, such as displaying disassembly or
319
+ checking registers.
320
+ This ensures the application focuses on the specified thread for these operations.
317
321
 
318
322
  ## Magic functions
319
323
 
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '2.0.0'
16
- __version_tuple__ = version_tuple = (2, 0, 0)
15
+ __version__ = version = '2.0.2'
16
+ __version_tuple__ = version_tuple = (2, 0, 2)
@@ -54,10 +54,10 @@ def attach(name: str, pid: int, startup_files: Optional[List[str]] = None) -> No
54
54
  @click.argument('exec_path')
55
55
  @click.option('--argv', multiple=True, help='Command line arguments to pass to the process')
56
56
  @click.option('--envp', multiple=True, callback=parse_envp, help='Environment variables in the form KEY=VALUE')
57
- @click.option('--stdin', type=Path, help='Redirect stdin from this file path')
58
- @click.option('--stdout', type=Path, help='Redirect stdout to this file path')
59
- @click.option('--stderr', type=Path, help='Redirect stderr to this file path')
60
- @click.option('--cwd', type=Path, help='Set the working directory for the process')
57
+ @click.option('--stdin', type=str, help='Redirect stdin from this file path')
58
+ @click.option('--stdout', type=str, help='Redirect stdout to this file path')
59
+ @click.option('--stderr', type=str, help='Redirect stderr to this file path')
60
+ @click.option('--cwd', type=str, help='Set the working directory for the process')
61
61
  @click.option('--flags', type=click.INT, default=0, help='Launch flags (bitmask)')
62
62
  @click.option('--stop-at-entry', is_flag=True, help='Stop the process at the entry point')
63
63
  @startup_files_option
@@ -0,0 +1,14 @@
1
+ from datetime import datetime
2
+ from typing import Any, List, Mapping, Tuple, Union
3
+
4
+ import inquirer3
5
+ from inquirer3.themes import GreenPassion
6
+
7
+ CfSerializable = Union[
8
+ Mapping[str, Any], List, Tuple[Any, ...], str, bool, float, bytes, datetime, None]
9
+
10
+
11
+ def selection_prompt(options_list: List):
12
+ question = [inquirer3.List('choice', message='choose device', choices=options_list, carousel=True)]
13
+ result = inquirer3.prompt(question, theme=GreenPassion(), raise_keyboard_interrupt=True)
14
+ return result['choice']
@@ -1,7 +1,7 @@
1
1
  __all__ = ['HildaException', 'SymbolAbsentError', 'EvaluatingExpressionError', 'CreatingObjectiveCSymbolError',
2
2
  'ConvertingToNsObjectError', 'ConvertingFromNSObjectError', 'DisableJetsamMemoryChecksError',
3
3
  'GettingObjectiveCClassError', 'AccessingRegisterError', 'AccessingMemoryError',
4
- 'BrokenLocalSymbolsJarError', 'AddingLldbSymbolError', 'LLDBException']
4
+ 'BrokenLocalSymbolsJarError', 'AddingLldbSymbolError', 'LLDBException', 'InvalidThreadIndexError']
5
5
 
6
6
 
7
7
  class HildaException(Exception):
@@ -70,3 +70,8 @@ class BrokenLocalSymbolsJarError(HildaException):
70
70
  class AddingLldbSymbolError(HildaException):
71
71
  """ Raise when failing to convert a LLDB symbol to Hilda's symbol. """
72
72
  pass
73
+
74
+
75
+ class InvalidThreadIndexError(HildaException):
76
+ """ Raise when thread idx invalid """
77
+ pass
@@ -30,10 +30,11 @@ from tqdm import tqdm
30
30
  from traitlets.config import Config
31
31
 
32
32
  from hilda import objective_c_class
33
- from hilda.common import CfSerializable
33
+ from hilda.common import CfSerializable, selection_prompt
34
34
  from hilda.exceptions import AccessingMemoryError, AccessingRegisterError, AddingLldbSymbolError, \
35
35
  BrokenLocalSymbolsJarError, ConvertingFromNSObjectError, ConvertingToNsObjectError, CreatingObjectiveCSymbolError, \
36
- DisableJetsamMemoryChecksError, EvaluatingExpressionError, HildaException, SymbolAbsentError
36
+ DisableJetsamMemoryChecksError, EvaluatingExpressionError, HildaException, InvalidThreadIndexError, \
37
+ SymbolAbsentError
37
38
  from hilda.lldb_importer import lldb
38
39
  from hilda.objective_c_symbol import ObjectiveCSymbol
39
40
  from hilda.registers import Registers
@@ -340,8 +341,6 @@ class HildaClient:
340
341
 
341
342
  if not self.process.Stop().Success():
342
343
  self.log_critical('failed to stop process')
343
- else:
344
- self.log_info('Process Stopped')
345
344
 
346
345
  def cont(self, *args) -> None:
347
346
  """ Continue process. """
@@ -357,8 +356,6 @@ class HildaClient:
357
356
 
358
357
  if not self.process.Continue().Success():
359
358
  self.log_critical('failed to continue process')
360
- else:
361
- self.log_info('Process Continued')
362
359
 
363
360
  def detach(self):
364
361
  """
@@ -514,7 +511,7 @@ class HildaClient:
514
511
  if options.get('name', False):
515
512
  name = options['name']
516
513
 
517
- log_message = f'🚨 #{bp.id} 0x{symbol:x} {name}'
514
+ log_message = f'🚨 #{bp.id} 0x{symbol:x} {name} - Thread #{self.thread.idx}:{hex(self.thread.id)}'
518
515
 
519
516
  if 'regs' in options:
520
517
  log_message += '\nregs:'
@@ -528,7 +525,7 @@ class HildaClient:
528
525
  value = hilda.symbol(hilda.evaluate_expression(name))
529
526
  log_message += f'\n\t{name} = {hilda._monitor_format_value(fmt, value)}'
530
527
 
531
- if options.get('force_return', False):
528
+ if options.get('force_return', None) is not None:
532
529
  hilda.force_return(options['force_return'])
533
530
  log_message += f'\nforced return: {options["force_return"]}'
534
531
 
@@ -537,7 +534,7 @@ class HildaClient:
537
534
  hilda.finish()
538
535
  hilda.bt()
539
536
 
540
- if options.get('retval', False):
537
+ if options.get('retval', None) is not None:
541
538
  # return from function
542
539
  hilda.finish()
543
540
  value = hilda.evaluate_expression('$arg1')
@@ -884,6 +881,16 @@ class HildaClient:
884
881
  spec.loader.exec_module(m)
885
882
  return m
886
883
 
884
+ def set_selected_thread(self, idx: Optional[int] = None) -> None:
885
+ if idx is None:
886
+ thread = selection_prompt(self.process.threads)
887
+ else:
888
+ try:
889
+ thread = [t for t in self.process.threads if t.idx == idx][0]
890
+ except IndexError:
891
+ raise InvalidThreadIndexError()
892
+ self.process.SetSelectedThread(thread)
893
+
887
894
  def unwind(self) -> bool:
888
895
  """ Unwind the stack (useful when get_evaluation_unwind() == False) """
889
896
  return self.thread.UnwindInnermostExpression().Success()
@@ -8,8 +8,8 @@ def load_ipython_extension(ipython):
8
8
  hilda = ipython.user_ns['p']
9
9
  keys_mapping = {Keys.F7: hilda.step_into,
10
10
  Keys.F8: hilda.step_over,
11
- Keys.F9: hilda.cont,
12
- Keys.F10: hilda.stop}
11
+ Keys.F9: lambda _: (hilda.log_info('Sending continue'), hilda.cont()),
12
+ Keys.F10: lambda _: (hilda.log_info('Sending stop'), hilda.stop())}
13
13
 
14
14
  insert_mode = ViInsertMode() | EmacsInsertMode()
15
15
  registry = ipython.pt_app.key_bindings
@@ -70,9 +70,22 @@ class LLDBListenerThread(Thread, ABC):
70
70
  logger.debug(f'Process Exited with status {self.process.GetExitStatus()}')
71
71
  self.should_quit = True
72
72
  elif state == lldb.eStateRunning and last_state == lldb.eStateStopped:
73
- logger.debug("Process Continued")
73
+ logger.debug('Process Continued')
74
74
  elif state == lldb.eStateStopped and last_state == lldb.eStateRunning:
75
75
  logger.debug('Process Stopped')
76
+ for thread in self.process:
77
+ frame = thread.GetFrameAtIndex(0)
78
+ stop_reason = thread.GetStopReason()
79
+ logger.debug(f'tid = {hex(thread.GetThreadID())} pc = {frame.GetPC()}')
80
+ if stop_reason not in [lldb.eStopReasonSignal, lldb.eStopReasonException,
81
+ lldb.eStopReasonBreakpoint,
82
+ lldb.eStopReasonWatchpoint, lldb.eStopReasonPlanComplete,
83
+ lldb.eStopReasonTrace,
84
+ lldb.eStopReasonSignal]:
85
+ continue
86
+ self.process.SetSelectedThread(thread)
87
+ break
88
+
76
89
  last_state = state
77
90
 
78
91
 
@@ -114,7 +127,7 @@ class LLDBAttachName(LLDBListenerThread):
114
127
  return self.debugger.CreateTargetWithFileAndArch(None, None)
115
128
 
116
129
  def _create_process(self) -> lldb.SBProcess:
117
- logger.debug(f'Attaching to {self.name}')
130
+ logger.debug(f'Attaching to {self.proc_name}')
118
131
  return self.target.AttachToProcessWithName(self.listener, self.proc_name, self.wait_for, self.error)
119
132
 
120
133
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hilda
3
- Version: 2.0.0
3
+ Version: 2.0.2
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>
@@ -51,6 +51,7 @@ Requires-Dist: construct
51
51
  Requires-Dist: pymobiledevice3
52
52
  Requires-Dist: keystone-engine
53
53
  Requires-Dist: tabulate
54
+ Requires-Dist: inquirer3
54
55
  Provides-Extra: test
55
56
  Requires-Dist: pytest; extra == "test"
56
57
 
@@ -370,6 +371,10 @@ Here is a gist of methods you can access from `p`:
370
371
  - Import & reload given python module (intended mainly for external snippets)
371
372
  - `unwind`
372
373
  - Unwind the stack (useful when get_evaluation_unwind() == False)
374
+ - `set_selected_thread`
375
+ - sets the currently selected thread, which is used in other parts of the program, such as displaying disassembly or
376
+ checking registers.
377
+ This ensures the application focuses on the specified thread for these operations.
373
378
 
374
379
  ## Magic functions
375
380
 
@@ -9,6 +9,7 @@ construct
9
9
  pymobiledevice3
10
10
  keystone-engine
11
11
  tabulate
12
+ inquirer3
12
13
 
13
14
  [test]
14
15
  pytest
@@ -8,4 +8,5 @@ objc_types_decoder
8
8
  construct
9
9
  pymobiledevice3
10
10
  keystone-engine
11
- tabulate
11
+ tabulate
12
+ inquirer3
@@ -1,5 +0,0 @@
1
- from datetime import datetime
2
- from typing import Any, List, Mapping, Tuple, Union
3
-
4
- CfSerializable = Union[
5
- Mapping[str, Any], List, Tuple[Any, ...], str, bool, float, bytes, datetime, None]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes