binary - Cómo REALMENTE desnudar un binario en MacOs
executable strip (4)
Dado el código de ejemplo que ha publicado, al agregar el indicador de optimización ''-O'', esos símbolos no se muestran por nm
después de la compilación.
MacOs 10.6, si tengo un archivo "no deseado.c" que contiene:
class secret_thing {
public:
secret_thing() {}
void revealing_method_name() {}
};
main()
{
secret_thing obj;
obj.revealing_method_name();
}
Ahora lo hago:
$ g++ unwanted.c -o unwanted
$ strip unwanted
$ nm unwanted | grep secret
0000000100000eb8 T __ZN12secret_thing21revealing_method_nameEv
0000000100000eae T __ZN12secret_thingC1Ev
Si dividí la interfaz y la implementación de la clase secreta, como la mayoría de las personas lo hacen cuando escriben código C ++, entonces no hay símbolos no deseados en el ejecutable eliminado. Lamentablemente, me entregó una base de código existente de muchos miles de líneas de código y esta no es una de mis opciones.
He intentado -fno-rtti, como una suposición salvaje, y eso no solucionó nada. He rezado a los dioses de Google y he encontrado muchas referencias a clubes de striptease, pero no enlaces útiles. He robado las páginas man para strip, g ++ y ld en el mac, y no había cosas obvias para probar, aunque la frase "private externs" era intrigante, no pude entender qué hacer al respecto.
[actualización] Lamentablemente, resulta un problema con mi intento de hacer un pequeño ejemplo. Aquí hay un ejemplo más complicado, que está más cerca de lo que es el problema real, que todavía tiene símbolos no deseados si está optimizado.
Me disculpo por los malos ejemplos. Resulta difícil encontrar el problema real más pequeño. Muchas gracias por las respuestas, sin embargo, cada respuesta me acerca a una solución.
class base {
public:
virtual int revealing_method_name() = 0;
virtual ~base() {};
};
class secret_thing : public base {
public:
int revealing_method_name() { return 0; };
};
class other_thing : public base {
public:
int revealing_method_name() { return 1; };
};
int main(int argc, char**)
{
base *object = 0;
if( argc > 1 ) object = new secret_thing;
else object = new other_thing;
return object->revealing_method_name();
}
Esto parece funcionar como se desea ...
$ strip unwanted
$ nm unwanted | grep secret | cut -f 3 -d '' '' > /tmp/remove
$ strip -R /tmp/remove unwanted
Parece que lo que realmente quieres es no quitar el ejecutable, sino ofuscar su tabla de símbolos. No estoy seguro, pero quizás algo así podría ser útil. Al menos, "obfuscator de tabla de símbolos de C ++" es probablemente una mejor cadena de búsqueda de Google.
Utilizando la siguiente línea de compilación, elimino con éxito los símbolos del ejecutable:
$ g++ -Xlinker -unexported_symbol -Xlinker "*" -o executable file.cpp
$ strip executable
Dado el último archivo de muestra, esto da como resultado:
$ nm executable
U __ZTVN10__cxxabiv117__class_type_infoE
U __ZTVN10__cxxabiv120__si_class_type_infoE
U __ZdlPv
U __Znwm
U ___cxa_pure_virtual
U ___gxx_personality_v0
0000000100000000 A __mh_execute_header
U _exit
U dyld_stub_binder