Modificadores para miembros de clase (C++ Reversing)¶
Objetivo¶
Entender tres modificadores que aparecen mucho en C++ y que afectan lo que vas a ver en reversing:
inlineconst(en metodos y retornos)static(miembros de clase)
1) inline en metodos de clase¶
Idea¶
inline sugiere al compilador reemplazar una llamada por el cuerpo de la funcion.
Regla importante¶
En compiladores modernos, inline es una sugerencia, no una orden.
- Con optimizaciones desactivadas, suele quedar
call. - Con optimizaciones agresivas, el compilador puede inlinear aunque no pongas
inline. - Con optimizaciones agresivas, incluso puede eliminar clases/metodos y dejar solo constantes si el resultado final es equivalente.
Lectura de reversing¶
- No uses la presencia/ausencia de
callcomo prueba de que habiainlineen fuente. - Primero identifica build flags (
/Od,/O2, LTO, etc.).
2) Metodos const¶
Idea¶
Un metodo marcado como const promete no modificar el estado observable del objeto.
Si intentas modificar un miembro dentro de Lee() const, falla compilacion:
Tambien restringe llamadas¶
Desde un metodo const no puedes llamar metodos no-const del mismo objeto (salvo casts explicitos).
Lectura de reversing¶
const de metodo no deja una "instruccion especial" en ASM.
Es una restriccion de tipo en compilacion.
3) const en el valor de retorno¶
Caso tipico con punteros¶
Si devuelves un puntero a memoria interna privada, puedes romper encapsulamiento si no cuidas el tipo.
Caso riesgoso:
Desde fuera:
Caso mas seguro:
Desde fuera, compila lectura pero no escritura:
Nota¶
const char* protege contra escritura accidental por esa ruta.
No reemplaza una politica completa de ownership/copias.
4) Miembros static de clase¶
Idea¶
Un miembro static pertenece a la clase, no a cada objeto.
Hay una sola copia compartida por todas las instancias.
class Numero {
public:
Numero(int v) : valor(v) { ++cuenta; suma += v; calcularMedia(); }
~Numero() { --cuenta; suma -= valor; calcularMedia(); }
static int LeerCuenta() { return cuenta; }
static int LeerMedia() { return media; }
private:
int valor;
static int cuenta;
static int suma;
static int media;
static void calcularMedia() {
media = (cuenta > 0) ? (suma / cuenta) : 0;
}
};
Propiedades clave¶
- Se definen/almacenan fuera del objeto (seccion global, tipicamente
.data/.bss). - Son compartidas entre todos los objetos.
- Si son
private, no puedes leerlas directo desdemain; necesitas metodos de acceso.
Lectura de reversing¶
Patrones comunes:
- Constructor: incrementa contador global de clase y actualiza acumuladores.
- Destructor: decrementa contador y ajusta acumuladores.
- Los objetos siguen teniendo sus campos no static dentro del
this. - Los
staticaparecen como simbolos globales referenciados por varias funciones.
5) Lo que cambia en ASM y lo que no¶
inline: puede cambiar mucho la forma (con o sincall), segun optimizacion.const(metodo/retorno): casi siempre no cambia instrucciones, cambia reglas de compilacion.static: si cambia layout y accesos, porque deja de vivir dentro del objeto y pasa a almacenamiento de clase/global.
6) Checklist para reversing rapido¶
- Verifica modo de compilacion antes de inferir semantica (
/Odvs optimizado). - Si un campo parece "global compartido", evalua si era
staticde clase. - Si una API devuelve puntero a buffer interno, evalua riesgo de romper encapsulamiento.
- Distingue restricciones de compilacion (
const) de efectos reales en runtime.
7) Errores comunes¶
- Suponer que
inlinesiempre elimina llamadas. - Pensar que
const"protege memoria" en runtime por si solo. - Tratar miembros
staticcomo si fuesen campos por-instancia. - Exponer punteros mutables a estado privado.