000110o5q7ZXuFIk.es.srt
Este video es la parte inicial del análisis estático de las clases del ejercicio 5, donde se identifican y reconstruyen las clases derived_example_1, base, y nest, junto con sus estructuras y vtables.
Generación del valor random:
Se identificó el patrón estándar de srand/rand: se llama a una función que obtiene el tiempo actual (time_64, segundos desde epoch 1970), ese valor se pasa como semilla a srand, y después rand devuelve un valor random que se castea a unsigned short.
Clase derived_example_1 — estructura:
Se identificó la llamada a new(0x20) seguida de __AutoClassInit (zeroea los 0x20 bytes) y el constructor. Al convertir el primer argumento a this (discall), se habilitó Autocreate Class Structure que creó automáticamente la estructura AutoClass, renombrada a derived_1. El layout final fue:
| Offset | Campo | Tipo |
|---|---|---|
| 0x00 | vtable ptr | derived_1_vtable* |
| 0x08 | hello_string | char* |
| 0x10 | word_1 | WORD |
| 0x14 | word_2 | WORD |
| 0x16-0x17 | padding | bytes |
| 0x18 | nest_object | nest_1* |
Clase base — estructura y vtable:
Dentro del constructor de derived_1 se identificó la llamada al constructor de base (siempre ocurre primero cuando hay herencia). Se creó la clase base_1 con Autocreate Class Structure. Su único campo es un puntero a base_vtable (4 punteros void*). La vtable de base se creó como estructura separada y se asignó al puntero en memoria. La vtable de base después queda pisada por la de derived_1 porque ambas comparten offset 0.
Clase nest — estructura y vtable:
Se identificó dentro del constructor de derived_1 una new(0x30) seguida de __AutoClassInit y el constructor de Nest. Se creó la clase nest_1. El layout de nest_1:
| Offset | Tipo | Descripción |
|---|---|---|
| 0x00 | nest_1_vtable* |
vtable (2 funciones) |
| 0x08 | DWORD |
valor 0x1337 |
| 0x10 | char* |
stream_rara (puntero a string) |
| 0x18 | void* |
buffer_20 (primer buffer, copia completa de stream_rara) |
| 0x20+ | void* |
buffer_20_segundo (copia parcial) |
Lógica de copia de stream_rara:
El constructor de Nest tiene un loop que hace dos cosas simultáneamente:
stream_rara al buffer_20 (puntero se incrementa cada iteración).buffer_20_segundo), solo copia caracteres cuando el contador es impar, y además siempre copia el carácter siguiente al que copió el primer puntero en ese mismo ciclo. El resultado es una string con solo ciertos caracteres de la original.La condición de impar se detecta con contador AND 1: si el resultado es 1 (impar), entra al branch de copia. El shift >> 0x1F siempre da 0 para valores dentro del rango de la string, así que la condición efectiva es solo el AND.
Vtables creadas:
base_vtable: 4 punteros void*derived_1_vtable: 5 punteros void*nest_1_vtable: 2 punteros void* (las dos funciones se identificaron después como imprimir_hello e imprimir_only_test)