helpers.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import time
  2. from typing import Optional
  3. import sys
  4. import os
  5. # Agregar el directorio padre al path para importar config
  6. sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  7. from config import HEX_DUMP_CONFIG, BACKUP_CONFIG, UI_MESSAGES
  8. from core.memory_manager import MemoryManager
  9. class HexDumper:
  10. """Utilidad para volcados hexadecimales"""
  11. @staticmethod
  12. def print_hex_dump(data: bytes, base_address: int = 0):
  13. """Imprime un volcado hexadecimal de los datos"""
  14. bytes_per_line = HEX_DUMP_CONFIG['bytes_per_line']
  15. address_width = HEX_DUMP_CONFIG['address_width']
  16. for i in range(0, len(data), bytes_per_line):
  17. line_data = data[i:i+bytes_per_line]
  18. hex_part = ' '.join(f'{b:02X}' for b in line_data)
  19. ascii_part = ''.join(chr(b) if 32 <= b <= 126 else '.' for b in line_data)
  20. print(f" 0x{base_address + i:0{address_width}X}: {hex_part:<48} {ascii_part}")
  21. class BackupManager:
  22. """Gestor de copias de seguridad"""
  23. def __init__(self, memory_manager: MemoryManager):
  24. self.memory_manager = memory_manager
  25. def backup_original_code(self, address: int, size: int) -> Optional[str]:
  26. """Crea una copia de seguridad del código original"""
  27. data = self.memory_manager.read_memory(address, size)
  28. if data and BACKUP_CONFIG['enabled']:
  29. timestamp = int(time.time())
  30. filename = BACKUP_CONFIG['filename_format'].format(address=address, timestamp=timestamp)
  31. try:
  32. with open(filename, 'wb') as f:
  33. f.write(data)
  34. print(UI_MESSAGES['success']['backup_saved'].format(filename=filename))
  35. return filename
  36. except IOError as e:
  37. print(f"❌ Error al guardar backup: {e}")
  38. return None
  39. class UserInterface:
  40. """Utilidades para interacción con el usuario"""
  41. @staticmethod
  42. def confirm_action(message: str) -> bool:
  43. """Solicita confirmación del usuario"""
  44. response = input(f"\n❓ {message} (s/N): ").strip().lower()
  45. return response in ['s', 'si', 'sí', 'y', 'yes']
  46. @staticmethod
  47. def confirm_patch() -> bool:
  48. """Solicita confirmación para aplicar el patch"""
  49. response = input("\n❓ ¿Aplicar el parche? (s/N): ").strip().lower()
  50. return response in ['s', 'si', 'sí', 'y', 'yes']
  51. @staticmethod
  52. def print_banner():
  53. """Imprime el banner de la aplicación"""
  54. banner = UI_MESSAGES['banner']
  55. print(banner['title'])
  56. print(banner['description'])
  57. print(banner['warning'])
  58. print(banner['admin_note'] + "\n")
  59. @staticmethod
  60. def print_found_addresses(found_addresses: list):
  61. """Imprime las direcciones encontradas"""
  62. print(f"\n📍 Se encontraron {len(found_addresses)} coincidencias:")
  63. for i, (pattern_name, address) in enumerate(found_addresses):
  64. print(f" {i + 1}. {pattern_name}: 0x{address:X}")
  65. @staticmethod
  66. def select_target_address(found_addresses: list) -> int:
  67. """Selecciona la dirección objetivo de la lista"""
  68. target_address = next(
  69. (address for pattern_name, address in found_addresses if "pattern_1" in pattern_name),
  70. found_addresses[0][1] # Fallback a la primera coincidencia
  71. )
  72. print(UI_MESSAGES['info']['using_address'].format(address=target_address))
  73. return target_address