| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- import time
- from typing import Optional
- import sys
- import os
- # Agregar el directorio padre al path para importar config
- sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
- from config import HEX_DUMP_CONFIG, BACKUP_CONFIG, UI_MESSAGES
- from core.memory_manager import MemoryManager
- class HexDumper:
- """Utilidad para volcados hexadecimales"""
-
- @staticmethod
- def print_hex_dump(data: bytes, base_address: int = 0):
- """Imprime un volcado hexadecimal de los datos"""
- bytes_per_line = HEX_DUMP_CONFIG['bytes_per_line']
- address_width = HEX_DUMP_CONFIG['address_width']
-
- for i in range(0, len(data), bytes_per_line):
- line_data = data[i:i+bytes_per_line]
- hex_part = ' '.join(f'{b:02X}' for b in line_data)
- ascii_part = ''.join(chr(b) if 32 <= b <= 126 else '.' for b in line_data)
- print(f" 0x{base_address + i:0{address_width}X}: {hex_part:<48} {ascii_part}")
- class BackupManager:
- """Gestor de copias de seguridad"""
-
- def __init__(self, memory_manager: MemoryManager):
- self.memory_manager = memory_manager
-
- def backup_original_code(self, address: int, size: int) -> Optional[str]:
- """Crea una copia de seguridad del código original"""
- data = self.memory_manager.read_memory(address, size)
- if data and BACKUP_CONFIG['enabled']:
- timestamp = int(time.time())
- filename = BACKUP_CONFIG['filename_format'].format(address=address, timestamp=timestamp)
- try:
- with open(filename, 'wb') as f:
- f.write(data)
- print(UI_MESSAGES['success']['backup_saved'].format(filename=filename))
- return filename
- except IOError as e:
- print(f"❌ Error al guardar backup: {e}")
- return None
- class UserInterface:
- """Utilidades para interacción con el usuario"""
-
- @staticmethod
- def confirm_action(message: str) -> bool:
- """Solicita confirmación del usuario"""
- response = input(f"\n❓ {message} (s/N): ").strip().lower()
- return response in ['s', 'si', 'sí', 'y', 'yes']
-
- @staticmethod
- def confirm_patch() -> bool:
- """Solicita confirmación para aplicar el patch"""
- response = input("\n❓ ¿Aplicar el parche? (s/N): ").strip().lower()
- return response in ['s', 'si', 'sí', 'y', 'yes']
-
- @staticmethod
- def print_banner():
- """Imprime el banner de la aplicación"""
- banner = UI_MESSAGES['banner']
- print(banner['title'])
- print(banner['description'])
- print(banner['warning'])
- print(banner['admin_note'] + "\n")
-
- @staticmethod
- def print_found_addresses(found_addresses: list):
- """Imprime las direcciones encontradas"""
- print(f"\n📍 Se encontraron {len(found_addresses)} coincidencias:")
- for i, (pattern_name, address) in enumerate(found_addresses):
- print(f" {i + 1}. {pattern_name}: 0x{address:X}")
-
- @staticmethod
- def select_target_address(found_addresses: list) -> int:
- """Selecciona la dirección objetivo de la lista"""
- target_address = next(
- (address for pattern_name, address in found_addresses if "pattern_1" in pattern_name),
- found_addresses[0][1] # Fallback a la primera coincidencia
- )
- print(UI_MESSAGES['info']['using_address'].format(address=target_address))
- return target_address
|