Tablas de estado del sistema (II): módulos
Al igual que existen tablas para el estado de los importes, el HBL también cuenta con estructuras de datos para los módulos (así es como denomina Sony a los ejecutables y librerías, los ELFs y PRXs). Estas tablas le sirven al HBL para saber qué modulos están cargados, dónde, por qué, cómo y esas cosas que nunca se cumplen en el periodismo (pero vemos que en el software sí que se cumplen).
La implementación de estas tablas se encuentra en modmgr.h. Vamos a echarles un vistazo:
Código: Seleccionar todo
typedef struct
{
SceUID id; // Module ID given by HBL
HBLModState state; // Current module state
unsigned int type; // Static or reloc
unsigned long size; // Allocated size
void* text_addr; // Text address (useful?)
void* text_entry; // Entry point
void* libstub_addr; // .lib.stub section address
void* gp; // Global pointer
char path[256]; // Path (do we need this?)
} HBLModInfo;
Esta estructura describe un módulo (un ejecutable o una librería).
- id contiene un ID dado por HBL, que es un número no negativo, y que empieza en MOD_ID_START y va aumentando en 1 para cada nuevo módulo. Esto es una simulación del SceUID que el firmware de la PSP asigna a cada módulo.
- state describe el estado del módulo, que como podemos ver en la estructura HBLModState, puede ser LOADED, RUNNING o STOPPED. Esto indica si el módulo está cargado, corriendo o parado respectivamente.
- type indica si el módulo es estático o relocalizable (entraremos en el detalle de esto más tarde).
- size indica el tamaño en memoria que se le ha asignado al módulo.
- text_addr es la dirección en la que está cargado el módulo.
- text_entry es la dirección donde se encuentra la entrada (el main, para que nos entendamos) al módulo.
- libstub_addr es la dirección donde se encuentra la sección .lib.stub del módulo (más detalles sobre esto adelante).
- gp es el GP (Global Pointer) del módulo. No nos interesa entrar en estos detalles por ahora.
- path es la ruta de donde se cargó el módulo. Sólo se usa para depuración.
Luego tenemos, al igual que con los syscalls, arrays de esta estructura:
Código: Seleccionar todo
typedef struct
{
unsigned int num_loaded_mod; // Loaded modules
HBLModInfo table[MAX_MODULES]; // List of loaded modules info struct
unsigned int num_utility; // Loaded utility modules
unsigned int utility[MAX_MODULES]; // List of ID for utility modules loaded
} HBLModTable;
table son los módulos cargados por HBL, mientras que utility son las IDs de los módulos utility (resumiendo: un tipo de módulos que se pueden cargar desde f0 aún en modo usuario) que han sido cargados por petición del homebrew. Cada tabla lleva asociado un num_ que indica cuántos elementos con información hay en el array.
Cómo se extrae un ELF de un EBOOT
Esto, que a mucha gente le puede parecer algo extraordinariamente complicado, es una de las cosas más sencillas y simples del HBL. Lo hace la función elf_extract_eboot_open.
Código: Seleccionar todo
eboot = sceIoOpen(eboot_path, PSP_O_RDONLY, 777);
Abrimos el EBOOT.PBP que se haya elegido.
Código: Seleccionar todo
sceIoLseek(eboot, 0x20, PSP_SEEK_SET);
Nos colocamos en el offset 0x20 (32) del EBOOT, que es donde se indica en qué offset se encuentra el ELF.
Código: Seleccionar todo
sceIoRead(eboot, offset, sizeof(u32));
Leemos el offset.
Código: Seleccionar todo
sceIoLseek(eboot, *offset, PSP_SEEK_SET);
Movemos el puntero del fichero a donde nos indica el EBOOT que está el ELF (en *offset).
Y esto es todo. ¿Complicadísimo, verdad? Gracias a n00b81 por esta función
<< Anterior