¿Proteger el ejecutable de la ingeniería inversa?

He estado contemplando cómo proteger mi código C / C ++ del desensamblaje y la ingeniería inversa. Normalmente nunca toleraría este comportamiento en mi código; sin embargo, el protocolo actual en el que he estado trabajando no debe ser inspeccionado ni comprensible por la seguridad de varias personas.

Ahora este es un tema nuevo para mí, y el internet no es realmente ingenioso para la prevención contra la ingeniería inversa, sino que representa toneladas de información sobre cómo realizar ingeniería inversa.

Algunas de las cosas que he pensado hasta ahora son:

  • Inyección de código (llamando a funciones ficticias antes y después de llamadas a funciones reales)
  • Obscurecimiento de código (destruye el desensamblaje del binario)
  • Escribir mis propias rutinas de inicio (más difícil para los depuradores vincular)

    void startup(); int _start() { startup( ); exit (0) } void startup() { /* code here */ } 
  • Verificación en tiempo de ejecución para los depuradores (y forzar la salida si se detecta)

  • Trampolines de función

      void trampoline(void (*fnptr)(), bool ping = false) { if(ping) fnptr(); else trampoline(fnptr, true); } 
  • Asignaciones y desasignaciones sin sentido (la stack cambia mucho)

  • Llamadas simuladas y trampolines sin sentido (toneladas de saltos en la salida de desassembly)
  • Toneladas de fundición (para el desarmado ofuscado)

Quiero decir que estas son algunas de las cosas en las que he pensado, pero los analistas de códigos pueden resolverlas o descifrarlas teniendo en cuenta el marco de tiempo adecuado. ¿Hay alguna otra alternativa que tenga?

Lo que Amber dijo es exactamente correcto. Puedes hacer que la ingeniería inversa sea más difícil, pero nunca puedes prevenirla. Nunca debe confiar en la “seguridad” que se basa en la prevención de la ingeniería inversa .

Dicho esto, las mejores técnicas de ingeniería anti-reversa que he visto se centraron no en ofuscar el código, sino en romper las herramientas que la gente usualmente usa para entender cómo funciona el código. Encontrar formas creativas para romper desensambladores, depuradores, etc. es probable que sean más efectivos y también más satisfactorios desde el punto de vista intelectual que simplemente generar montones de horribles códigos de espagueti. Esto no hace nada para bloquear a un atacante determinado, pero sí aumenta la probabilidad de que J Random Cracker se desvíe y trabaje en algo más fácil.

pero todos pueden ser analizados por analistas de códigos con el tiempo correcto.

Si le ofrece a las personas un progtwig que pueden ejecutar, entonces también podrán realizar una ingeniería inversa con suficiente tiempo. Esa es la naturaleza de los progtwigs. Tan pronto como el binario esté disponible para alguien que quiera descifrarlo, no podrá evitar la ingeniería inversa eventual. Después de todo, la computadora tiene que poder descifrarlo para poder ejecutarlo, y un humano es simplemente una computadora más lenta.

Safe Net Sentinel (anteriormente Aladdin). Sin embargo, las advertencias: su API es una mierda, la documentación apesta, y ambas son excelentes en comparación con sus herramientas de SDK.

He usado su método de protección de hardware ( Sentinel HASP HL ) durante muchos años. Requiere un llavero USB patentado que actúa como la ‘licencia’ del software. Su SDK encripta y ofusca el ejecutable y las bibliotecas, y le permite vincular diferentes características en su aplicación con las características grabadas en la clave. Sin una llave USB proporcionada y activada por el licenciante, el software no puede descifrar y, por lo tanto, no se ejecutará. Key incluso usa un protocolo de comunicación USB personalizado (fuera de mi ámbito de conocimiento, no soy un controlador de dispositivo) para dificultar la creación de una clave virtual o alterar la comunicación entre el contenedor de tiempo de ejecución y la clave. Su SDK no es muy amigable para el desarrollador, y es bastante doloroso integrar la protección añadida con un proceso de comstackción automatizado (pero posible).

Antes de implementar la protección HASP HL, había 7 piratas conocidos que habían quitado las ‘protecciones’ de dotfuscator del producto. Añadimos la protección HASP al mismo tiempo que una actualización importante del software, que realiza algunos cálculos pesados ​​en video en tiempo real. Lo mejor que puedo decir de la creación de perfiles y la evaluación comparativa, la protección HASP HL ​​solo redujo la velocidad de los cálculos intensivos en aproximadamente un 3%. Desde que se lanzó el software hace unos 5 años, no se ha encontrado un nuevo pirata del producto. El software que protege tiene una gran demanda en su segmento de mercado, y el cliente conoce que varios competidores están intentando activamente realizar ingeniería inversa (sin éxito hasta el momento). Sabemos que han tratado de solicitar la ayuda de algunos grupos en Rusia que anuncian un servicio para romper la protección del software, ya que numerosas publicaciones en varios grupos de noticias y foros han incluido las versiones más recientes del producto protegido.

Recientemente probamos su solución de licencia de software (HASP SL) en un proyecto más pequeño, lo cual fue lo suficientemente sencillo como para funcionar si ya está familiarizado con el producto HL. Parece que funciona; no se han reportado incidentes de piratería, pero este producto tiene mucha menos demanda.

Por supuesto, ninguna protección puede ser perfecta. Si alguien está lo suficientemente motivado y tiene dinero en efectivo para gastar, estoy seguro de que se pueden eludir las protecciones otorgadas por HASP.

Tomemos, por ejemplo, el algoritmo AES . Es un algoritmo muy, muy público, y es MUY seguro. ¿Por qué? Dos razones: ha sido revisado por muchas personas inteligentes, y la parte “secreta” no es el algoritmo en sí; la parte secreta es la clave que es una de las entradas al algoritmo. Es un enfoque mucho mejor diseñar su protocolo con un “secreto” generado que está fuera de su código, en lugar de hacer que el código sea secreto. El código siempre se puede interpretar sin importar lo que se haga, y (idealmente) el secreto generado solo puede verse comprometido por un enfoque de fuerza bruta masivo o por robo.

Creo que una pregunta interesante es ” ¿Por qué quieres ofuscar tu código?” ¿Quieres que sea difícil para los atacantes descifrar tus algoritmos? ¿Para que les resulte más difícil encontrar errores explotables en su código? No necesitarías ofuscar el código si el código no fuera descifrable en primer lugar. La raíz del problema es software crackable. Arregle la raíz de su problema, no lo ofusque.

Además, cuanto más confuso sea el código, más difícil será para USTED encontrar errores de seguridad. Sí, será difícil para los piratas informáticos, pero también debes encontrar errores. El código debería ser fácil de mantener en años, e incluso un código claro bien escrito puede ser difícil de mantener. No lo empeores.

Los mejores trucos contra el desensamblador, en particular en los conjuntos de instrucciones de longitud de palabra variable, son en ensamblador / código de máquina, no C. Por ejemplo

 CLC BCC over .byte 0x09 over: 

El desensamblador tiene que resolver el problema de que un destino de sucursal es el segundo byte en una instrucción de varios bytes. Sin embargo, un simulador de conjunto de instrucciones no tendrá ningún problema. La ramificación a direcciones calculadas, que puede causar desde C, también hace que el desensamblaje sea difícil o imposible. El simulador de conjunto de instrucciones no tendrá ningún problema. Usar un simulador para ordenar los destinos de las sucursales puede ayudar en el proceso de desensamblaje. El código comstackdo es relativamente limpio y fácil para un desensamblador. Así que creo que se requiere algún ensamblaje.

Creo que fue casi el comienzo del Zen of Assembly Language de Michael Abrash, donde mostró un simple truco anti desensamblador y anti depurador. El 8088/6 tenía una cola de búsqueda previa lo que hiciste fue tener una instrucción que modificó la siguiente instrucción o una pareja por delante. Si realizaba un solo paso y luego ejecutaba la instrucción modificada, si su simulador de conjunto de instrucciones no simulaba completamente el hardware, ejecutaba las instrucciones modificadas. En el hardware real que se ejecuta normalmente, la instrucción real ya estaría en la cola y la ubicación de la memoria modificada no causaría ningún daño siempre que no haya ejecutado esa cadena de instrucciones nuevamente. Probablemente aún puedas usar un truco como este hoy en día, ya que los procesadores en línea buscan las siguientes instrucciones. O si sabe que el hardware tiene una instrucción separada y caché de datos, puede modificar un número de bytes por delante si alinea este código en la línea de caché correctamente, el byte modificado no se escribirá a través del caché de instrucciones sino el caché de datos, y un simulador de conjunto de instrucciones que no tenía simuladores de caché adecuados no se ejecutaría correctamente. Creo que las soluciones de solo software no te llevarán muy lejos.

Los anteriores son viejos y conocidos, no sé lo suficiente sobre las herramientas actuales para saber si ya funcionan. El código de auto modificación puede / hará tropezar el depurador, pero el humano puede / se limitará al problema y luego verá el código de auto modificación y trabajará alrededor de él.

Solía ​​ser que los piratas tardarían unos 18 meses en resolver algo, dvds, por ejemplo. Ahora promedian alrededor de 2 días a 2 semanas (si está motivado) (blue ray, iphones, etc.). Eso significa para mí si gasto más de unos días en seguridad, probablemente estoy perdiendo el tiempo. La única seguridad real que obtendrá es a través del hardware (por ejemplo, sus instrucciones están encriptadas y solo el núcleo del procesador dentro del chip se descifra justo antes de la ejecución, de una manera que no puede exponer las instrucciones descifradas). Eso podría comprarle meses en lugar de días.

Además, lea el libro de Kevin Mitnick The Art of Deception. Una persona como esa podría levantar un teléfono y hacer que usted o un compañero de trabajo entreguen los secretos al sistema pensando que es un gerente u otro compañero de trabajo o ingeniero de hardware en otra parte de la empresa. Y tu seguridad ha explotado. La seguridad no se trata solo de administrar la tecnología, sino también de gestionar a los humanos.

Hacer código difícil de aplicar ingeniería inversa se denomina ofuscación de código.

La mayoría de las técnicas que mencionas son bastante fáciles de solucionar. Se centran en agregar algún código inútil. Pero el código inútil es fácil de detectar y eliminar, dejándolo con un progtwig limpio.

Para una ofuscación efectiva, necesita hacer que el comportamiento de su progtwig dependa de los bits inútiles que se están ejecutando. Por ejemplo, en lugar de hacer esto:

 a = useless_computation(); a = 42; 

hacer esto:

 a = complicated_computation_that_uses_many_inputs_but_always_returns_42(); 

O en lugar de hacer esto:

 if (running_under_a_debugger()) abort(); a = 42; 

Haga esto (donde running_under_a_debugger no debe ser fácilmente identificable como una función que prueba si el código se está ejecutando bajo un depurador; debe mezclar cálculos útiles con la detección del depurador):

 a = 42 - running_under_a_debugger(); 

La ofuscación efectiva no es algo que puedas hacer puramente en la etapa de comstackción. Cualquier cosa que el comstackdor pueda hacer, un descomstackdor puede hacerlo. Claro, puede boost la carga de los descomstackdores, pero no va a ir muy lejos. Las técnicas efectivas de ofuscación, en la medida en que existen, implican escribir una fuente ofuscada desde el día 1. Haga que su código se auto-modifique. Descargue su código con saltos calculados, derivados de una gran cantidad de entradas. Por ejemplo, en lugar de una simple llamada

 some_function(); 

haz esto, donde conoces el diseño exacto esperado de los bits en some_data_structure :

 goto (md5sum(&some_data_structure, 42) & 0xffffffff) + MAGIC_CONSTANT; 

Si es serio acerca de la ofuscación, agregue varios meses a su planificación; la ofuscación no es barata. Y considere que, con mucho, la mejor manera de evitar que las personas apliquen ingeniería inversa a su código es hacerlo inútil para que no se molesten. Es una simple consideración económica: realizarán ingeniería inversa si el valor para ellos es mayor que el costo; pero boost su costo también aumenta mucho su costo, así que trate de disminuir el valor para ellos.

Ahora que ya te dije que la ofuscación es dura y costosa, te voy a decir que no es para ti de todos modos . Usted escribe

El protocolo actual en el que he estado trabajando no debe ser inspeccionado ni comprensible, por la seguridad de varias personas

Eso levanta una bandera roja. Es la seguridad por oscuridad , que tiene un registro muy pobre. Si la seguridad del protocolo depende de personas que no conocen el protocolo, ya has perdido .

Lectura recomendada:

  • La biblia de seguridad: Ingeniería de seguridad por Ross Anderson
  • La biblia de ofuscación: software subrepticio de Christian Collberg y Jasvir Nagra

Muchas veces, el miedo a que su producto sea sometido a ingeniería inversa está fuera de lugar. Sí, puede obtener ingeniería inversa; pero se volverá tan famoso en un corto período de tiempo, que los hackers encontrarán que vale la pena invertir engg. eso ? (este trabajo no es una actividad pequeña, para líneas de código sustanciales).

Si realmente se convierte en una fuente de ingresos monetarios, entonces debería haber reunido suficiente dinero para protegerlo usando las formas legales como patentes y / o derechos de autor .

En mi humilde opinión, tome las precauciones básicas que va a tomar y libérela. Si se convierte en un punto de ingeniería inversa lo que significa que ha realizado un trabajo realmente bueno, usted mismo encontrará mejores formas de superarlo. Buena suerte.

Lea la página http://en.wikipedia.org/wiki/Security_by_obscurity#Arguments_against . Estoy seguro de que otros probablemente también podrían dar una mejor fuente de por qué la seguridad por oscuridad es algo malo.

Debería ser completamente posible, usando técnicas criptográficas modernas, tener su sistema abierto (no digo que debería estar abierto, solo que podría serlo), y aún así tener total seguridad, siempre que el algoritmo criptográfico no lo haga tiene un agujero (no es probable si elige uno bueno), sus claves privadas / contraseñas permanecen privadas, y no tiene agujeros de seguridad en su código ( esto es por lo que debería preocuparse).

Desde julio de 2013, existe un interés renovado en la ofuscación criptográficamente robusta (en forma de ofuscación de indistinguibilidad ) que parece haber sido un estímulo de la investigación original de Amit Sahai .

  • Sahai, Garg, Gentry, Halevi, Raykova, Waters, Candidate indistinguishability Ofuscación y cifrado funcional para todos los circuitos (21 de julio de 2013).
  • Sahai, Waters, Cómo usar la ofuscación de indistinguibilidad: cifrado denegable y más .
  • Sahai, Barak, Garg, Kalai, Paneth, protección contra la ofuscación de ataques algebraicos (4 de febrero de 2014).

Puede encontrar información destilada en este artículo de Quanta Magazine y en ese artículo de IEEE Spectrum .

Actualmente, la cantidad de recursos necesarios para hacer uso de esta técnica lo hace poco práctico, pero AFAICT el consenso es bastante optimista sobre el futuro.

Digo esto de manera muy informal, pero para todos los que solían descartar instintivamente la tecnología de ofuscación, esto es diferente. Si se demuestra que realmente funciona y se hace práctico, esto es realmente importante, y no solo para la ofuscación.

Si alguien quiere pasar el tiempo para invertir tu binario, entonces no hay absolutamente nada que puedas hacer para detenerlos. Puedes hacerlo moderadamente más difícil, pero eso es todo. Si realmente quieres aprender sobre esto, obtén una copia de http://www.hex-rays.com/idapro/ y desensambla algunos binarios.

El hecho de que la CPU necesita ejecutar el código es su perdición. La CPU solo ejecuta código de máquina … y los progtwigdores pueden leer códigos de máquina.

Dicho eso … es probable que tenga un problema diferente que se puede resolver de otra manera. ¿Qué estás tratando de proteger? Dependiendo de su problema, es probable que pueda usar el cifrado para proteger su producto.

Para informarse, lea la literatura académica sobre ofuscación de códigos . Christian Collberg de la Universidad de Arizona es un erudito acreditado en este campo; Salil Vadhan de la Universidad de Harvard también ha hecho un buen trabajo.

Estoy atrasado en esta literatura, pero la idea esencial de la que soy consciente es que no puedes evitar que un atacante vea el código que ejecutarás, pero puedes rodearlo con código que no se ejecuta, y cuesta un tiempo exponencial de atacante (usando las técnicas más conocidas) para descubrir qué fragmentos de su código se ejecutan y cuáles no.

Hay un documento reciente llamado ” Ofuscación de progtwigs y progtwigs de una sola vez “. Si realmente quieres proteger tu aplicación. El documento en general da la vuelta a los resultados teóricos de imposibilidad mediante el uso de hardware simple y universal.

Si no puede permitirse requerir hardware adicional, también hay otro documento que ofrece la mejor ofuscación teórica posible ” En la mejor ofuscación posible “, entre todos los progtwigs con la misma funcionalidad y el mismo tamaño. Sin embargo, el documento muestra que la teoría de la información es lo mejor posible implica un colapso de la jerarquía polinómica.

Esos documentos, por lo menos, le brindarán suficientes pistas bibliográficas para ir a la literatura relacionada si estos resultados no funcionan para sus necesidades.

Actualización: una nueva noción de ofuscación, llamada ofuscación indistinguible, puede mitigar el resultado de imposibilidad (papel)

Sin dados, no puedes proteger tu código para que no se desarme. Lo que puede hacer es configurar el servidor para la lógica comercial y usar el servicio web para proporcionarlo para su aplicación. Por supuesto, este escenario no siempre es posible.

Para poder seleccionar la opción correcta, debe pensar en los siguientes aspectos:

  1. ¿Es probable que los “nuevos usuarios” no quieran pagar, pero usen su software?
  2. ¿Es probable que los clientes existentes necesiten más licencias de las que tienen?
  3. ¿Cuánto están dispuestos a pagar los usuarios potenciales?
  4. ¿Desea otorgar licencias por usuario / usuarios concurrentes / estación de trabajo / compañía?
  5. ¿Su software necesita capacitación / personalización para ser útil?

Si la respuesta a la pregunta 5 es “sí”, entonces no se preocupe por las copias ilegales. No serían útiles de todos modos.

Si la respuesta a la pregunta 1 es “sí”, primero piense en los precios (vea la pregunta 3).

Si responde a la pregunta 2 “sí”, un modelo de “pago por uso” podría ser apropiado para usted.

Según mi experiencia, pagar por uso + personalización y capacitación es la mejor protección para su software, porque:

  • Los nuevos usuarios se sienten atraídos por el modelo de precios (poco uso -> poco salario)
  • Casi no hay “usuarios anónimos”, ya que necesitan capacitación y personalización.
  • Ninguna restricción de software asusta a los clientes potenciales.
  • Hay un flujo continuo de dinero de clientes existentes.
  • Obtiene comentarios valiosos para el desarrollo de Sus clientes, debido a una relación comercial a largo plazo.

Antes de pensar en introducir DRM u ofuscación, puede pensar en estos puntos y si son aplicables a su software.

El código protegido en una máquina virtual parecía imposible de aplicar ingeniería inversa al principio. Themida Packer

Pero ya no es tan seguro … Y no importa cómo empaque su código, siempre puede hacer un volcado de memoria de cualquier ejecutable cargado y desensamblarlo con cualquier desensamblador como IDA Pro.

IDA Pro también viene con un código de ensamblaje ingenioso para el transformador de código fuente C, aunque el código generado se parecerá más a un desorden matemático de puntero / dirección … si lo comparas con el original, puedes corregir todos los errores y arrancar cualquier cosa.

Posiblemente su mejor alternativa sigue siendo la virtualización, que introduce otro nivel de indirección / ofuscación necesario para el bypass, pero como dijo SSpoke en su respuesta , esta técnica tampoco es 100% segura.


El punto es que no obtendrás la máxima protección, porque no existe tal cosa, y si alguna vez lo será, no durará mucho, lo que significa que no fue la máxima protección en primer lugar.

Cualquier hombre que ensamble, puede ser desarmado.

Por lo general, es cierto que el desassembly (correcto) es a menudo (un poco o más) tarea más difícil, por lo que su oponente debe ser más hábil , pero puede suponer que siempre hay alguien de esa calidad, y es una apuesta segura.

Si desea proteger algo contra RE, debe conocer al menos las técnicas comunes utilizadas por RE.

Así palabras

Internet no es realmente ingenioso para la prevención contra la ingeniería inversa, sino que representa toneladas de información sobre cómo realizar ingeniería inversa.

muestra mala actitud tuya. No estoy diciendo que para usar o incrustar protección debe saber cómo romperla, pero para usarla sabiamente debe conocer sus debilidades y dificultades. Deberías entenderlo .

(Hay ejemplos de software que usa protección de manera incorrecta, haciendo que dicha protección sea prácticamente inexistente. Para evitar hablar vagamente, le daré un ejemplo brevemente descrito en Internet: Oxford English Dictionary Second Edition en CD-ROM v4. Puede leer sobre su uso fallido de SecuROM en la página siguiente: Oxford English Dictionary (OED) en CD-ROM en un entorno de Windows de 16, 32 o 64 bits: instalación de disco duro, errores, macros de procesamiento de textos, redes, fonts y etc. )

Todo lleva tiempo.

Si eres nuevo en el tema y no tienes meses o más bien años para conectarte adecuadamente con el tema de RE, entonces ve con soluciones disponibles hechas por otros. El problema aquí es obvio, ya están allí, por lo que ya sabe que no son 100% seguros, pero crear su propia protección le daría una falsa sensación de protección, a menos que sepa muy bien el estado del arte en ingeniería inversa y protección (pero no lo hace, al menos en este momento).

El objective de la protección del software es asustar a los novatos, detener REs comunes y poner una sonrisa en la cara de RE experimentada después de su viaje (afortunadamente interesante) hacia el centro de su aplicación.

En las conversaciones comerciales, puede decir que todo se trata de retrasar la competencia, tanto como sea posible.

(Eche un vistazo a la presentación agradable Silver Needle en Skype, de Philippe Biondi y Fabrice Desclaux, que se muestra en Black Hat 2006).


Sabes que hay muchas cosas sobre RE por ahí, así que comienza a leerlo. 🙂

Dije acerca de la virtualización, así que le daré un enlace a un hilo ejemplar de EXETOOLS FORUM : Mejor protector de software: ¿Themida o Enigma Protector? . Puede ayudarlo un poco en futuras búsquedas.

I do not think that any code is unhackable but the rewards need to be great for someone to want to attempt it.

Having said that there are things you should do such as:

  • Use the highest optimization level possible (reverse engineering is not only about getting the assembly sequence, it is also about understanding the code and porting it into a higher-level language such as C). Highly optimized code can be a b—h to follow.
  • Make structures dense by not having larger data types than necessary. Rearrange structure members between official code releases. Rearranged bit fields in structures are also something you can use.
  • You can check for the presence of certain values which shouldn’t be changed (a copyright message is an example). If a byte vector contains “vwxyz” you can have another byte vector containing “abcde” and compare the differences. The function doing it should not be passed pointers to the vectors but use external pointers defined in other modules as (pseudo-C code) “char *p1=&string1[539];” and “char p2=&string2[-11731];”. That way there won’t be any pointers pointing exactly at the two strings. In the comparison code you then compare for “ (p1-539+i)-*(p2+11731+i)==some value”. The cracker will think it is safe to change string1 because no one appears to reference it. Bury the test in some unexpected place.

Try to hack the assembly code yourself to see what is easy and what is difficult to do. Ideas should pop up that you can experiment with to make the code more difficult to reverse engineer and to make debugging it more difficult.

As many already said: On a regular CPU you cant stop them from doing, you can just delay them. As my old crypto teacher told me: You dont need perfect encryption, breaking the code must be just more expensive than the gain. Same holds for your obfuscation.

But 3 additional notes:

  1. It is possible to make reverse engineering impossible, BUT (and this is a very very big but), you cant do it on a conventional cpu. I did also much hardware development, and often FPGA are used. Eg the Virtex 5 FX have a PowerPC CPU on them, and you can use the APU to implement own CPU opcodes in your hardware. You could use this facility to really decrypt incstuctions for the PowerPC, that is not accessible by the outside or other software, or even execute the command in the hardware. As the FPGA has builtin AES encryption for its configuration bitstream, you could not reverse engineer it (except someone manages to break AES, but then I guess we have other problems…). This ways vendors of hardware IP also protect their work.

  2. You speak from protocol. You dont say what kind of protocol it is, but when it is a network protocol you should at least protect it against network sniffing. This can you indeed do by encryption. But if you want to protect the en/decryption from an owner of the software, you are back to the obfuscation.

  3. Do make your programm undebuggable/unrunnable. Try to use some kind of detection of debugging and apply it eg in some formula oder adding a debug register content to a magic constant. It is much harder if your program looks in debug mode is if it where running normal, but makes a complete wrong computation, operation, or some other. Eg I know some eco games, that had a really nasty copy-protection (I know you dont want copyprotection, but it is similar): The stolen version altered the mined resources after 30 mins of game play, and suddenly you got just a single resource. The pirate just cracked it (ie reverse engineered it) – checked if it run, and volia released it. Such slight behaviour changings are very hard to detect, esp. if they do not appear instantly to detection, but only delayed.

So finally I would suggest: Estimate what is the gain of the people reverse engineering your software, translate this into some time (eg by using the cheapest indian salary) and make the reverse engineering so time costing that it is bigger.

To avoid reverse engineering, you must not give the code to users. That said, I recommend using an online application…however (since you gave no context) that could be pointless on yours.

Contrary to what most people say, based on their intuition and personal experience, I don’t think cryptographically-safe program obfuscation is proven to be impossible in general.

This is one example of a perfectly obfuscated program statement to demonstrate my point:

 printf("1677741794\n"); 

One can never guess that what it really does is

 printf("%d\n", 0xBAADF00D ^ 0xDEADBEEF); 

There is an interesting paper on this subject, which proves some impossibility results. It is called “On the (Im)possibility of Obfuscating Programs” .

Although the paper does prove that the obfuscation making the program non-distinguishable from the function it implements is impossible, obfuscation defined in some weaker way may still be possible!

Security through obscurity doesn’t work as has been demonstrated by people much cleverer than the both of us. If you must protect the communication protocol of your customers then you are morally obliged to use the best code that is in the open and fully scrutinized by experts.

This is for the situation where people can inspect the code. If your application is to run on an embedded microprocessor, you can choose one that has a sealing facility, which makes it impossible to inspect the code or observe more than trivial parameters like current usage while it runs. (It is, except by hardware invading techniques, where you carefully dismantle the chip and use advanced equipment to inspect currents on individual transistors.)

I’m the author of a reverse engineering assembler for the x86. If you’re ready for a cold surprise, send me the result of your best efforts. (Contact me through my websites.) Few I have seen in the answers would present a substantial hurdle to me. If you want to see how sophisticated reverse engineering code works, you should really study websites with reverse engineering challenges.

Your question could use some clarification. How do you expect to keep a protocol secret if the computer code is amenable to reverse engineering? If my protocol would be to send an RSA encrypted message (even public key) what do you gain by keeping the protocol secret? For all practical purposes an inspector would be confronted with a sequence of random bits.

Groetjes Albert

Traditional reverse engineering techniques depend on the ability of a smart agent using a disassembler to answer questions about the code. If you want strong safety, you have do to things that provably prevent the agent from getting such answers.

You can do that by relying on the Halting Program (“does program X halt?”) which in general cannot be solved. Adding programs that are difficult to reason about to your program, makes your program difficult to reason about. It is easier to construct such programs than to tear them apart. You can also add code to program that has varying degrees of difficulty for reasoning; a great candidate is the program of reasoning about aliases (“pointers”).

Collberg et al have a paper (“Manufacturing Cheap, Resilient and Stealthy Opaque Constructs”) that discusses these topics and defines a variety of “opaque” predicates that can make it very difficult to reason about code:

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.39.1946&rep=rep1&type=pdf

I have not seen Collberg’s specific methods applied to production code, especially not C or C++ source code.

The DashO Java obfuscator seems to use similar ideas. http://www.cs.arizona.edu/~collberg/Teaching/620/2008/Assignments/tools/DashO/

FIRST THING TO REMEMBER ABOUT HIDING YOUR CODE : Not all of your code needs to be hidden.

THE END GOAL : My end goal for most software programs is the ability to sell different licenses that will turn on and off specific features within my programs.

BEST TECHNIQUE : I find that building in a system of hooks and filters like WordPress offers, is the absolute best method when trying to confuse your opponents. This allows you to encrypt certain trigger associations without actually encrypting the code.

The reason that you do this, is because you’ll want to encrypt the least amount of code possible.

KNOW YOUR CRACKERS : Know this: The main reason for cracking code is not because of malicious distribution of licensing, it’s actually because NEED to change your code and they don’t really NEED to distribute free copies.

GETTING STARTED : Set aside the small amount of code that you’re going to encrypt, the rest of the code should try and be crammed into ONE file to increase complexity and understanding.

PREPARING TO ENCRYPT : You’re going to be encrypting in layers with my system, it’s also going to be a very complex procedure so build another program that will be responsible for the encryption process.

STEP ONE : Obfuscate using base64 names for everything. Once done, base64 the obfuscated code and save it into a temporary file that will later be used to decrypt and run this code. ¿Tener sentido?

I’ll repeat since you’ll be doing this again and again. You’re going to create a base64 string and save it into another file as a variable that will be decrypted and rendered.

STEP TWO : You’re going to read in this temporary file as a string and obfuscate it, then base64 it and save it into a second temp file that will be used to decrypt and render it for the end user.

STEP THREE : Repeat step two as many times as you would like. Once you have this working properly without decrypt errors, then you’re going to want to start building in land mines for your opponents.

LAND MINE ONE : You’re going to want to keep the fact that you’re being notified an absolute secret. So build in a cracker attempt security warning mail system for layer 2. This will be fired letting you know the specifics about your opponent if anything is to go wrong.

LAND MINE TWO : Dependencies. You don’t want your opponent to be able to run layer one, without layer 3 or 4 or 5, or even the actual program it was designed for. So make sure that within layer one you include some sort of kill script that will activate if the program isn’t present, or the other layers.

I’m sure you can come up with you’re own landmines, have fun with it.

THING TO REMEMBER : You can actually encrypt your code instead of base64’ing it. That way a simple base64 willnt decrypt the program.

REWARD : Keep in mind that this can actually be a symbiotic relationship between you and you’r opponent. I always place a comment inside of layer one, the comment congratulates the cracker and gives them a promo code to use in order to receive a cash reward from you.

Make the cash reward significant with no prejudice involved. I normally say something like $500. If your guy is the first to crack the code, then pay him his money and become his friend. If he’s a friend of yours he’s not going to distribute your software. Ask him how he did it and how you can improve!

¡BUENA SUERTE!

Have anyone tried CodeMorth: http://www.sourceformat.com/code-obfuscator.htm ? Or Themida: http://www.oreans.com/themida_features.php ?

Later one looks more promissing.