Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: BloodSharp en 15 Mayo 2022, 17:26 pm



Título: [C++/ASM] Ejemplo de cifrador de funciones y eliminador de códigos
Publicado por: BloodSharp en 15 Mayo 2022, 17:26 pm
Buenas gente del foro, este código lo había hecho hace unos cuantos años por el 2014 (https://foro.elhacker.net/programacion_cc/dudacomo_resuelve_el_pe_loader_direcciones_de_memoria_en_secciones_ejecutables-t421844.0.html), pensando que lo había perdido hasta que lo encontré hace un par de días, finalmente he decidido liberarlo como FOSS para quien quiera probarlo.

La idea es cifrar y/o destruir parte del contenido de las funciones para evitar el análisis estático de los binarios, esto lo tome como idea hace años del antiguo sistema de protección de Themida/WinLicense de Oreans:

Código
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include "codeencryption.h"
  4.  
  5. #pragma optimize("",off)
  6. _declspec(noinline)int addOperation(int a, int b)
  7. {
  8. int iRetval;
  9. CodeEncryption cdProtection;
  10. cdProtection.dwPassWord = 0xDEADBAFF;
  11. cdProtection.biOptions = ENCRYPTION_PAGE_PROTECTIONS | ENCRYPTION_CLEAR_CODE;
  12. iRetval = a;
  13. BeginEncryption(&cdProtection);
  14. iRetval += b;
  15. EndEncryption(&cdProtection);
  16. return iRetval;
  17. }
  18.  
  19. _declspec(noinline)int addAndSquareRoot(int a, int b)
  20. {
  21. int iRetval;
  22. CodeEncryption cdProtection;
  23. cdProtection.dwPassWord = 0xDEADBAFF;
  24. cdProtection.biOptions = ENCRYPTION_PAGE_PROTECTIONS | ENCRYPTION_CLEAR_CODE;
  25. iRetval = a;
  26. BeginEncryption(&cdProtection);
  27. iRetval += b;
  28. iRetval = (int)sqrt(iRetval);
  29. EndEncryption(&cdProtection);
  30. return iRetval;
  31. }
  32. #pragma optimize("",on)
  33.  
  34. int main()
  35. {
  36. int a = 4, b = 21;
  37. printf("%i+%i=%i\n", a, b, addOperation(a, b));
  38. printf("%i+%i=%i\n", a, b, addOperation(a, b));
  39. getchar();
  40. printf("sqrt(%i+%i)=%i\n", a, b, addAndSquareRoot(a, b));
  41. printf("sqrt(%i+%i)=%i\n", a, b, addAndSquareRoot(a, b));
  42. getchar();
  43. return 0;
  44. }

Donde se puede ver el código original compilado se vé de la siguiente forma:
(https://raw.githubusercontent.com/BloodSharp/CodeObfuscation/master/Images/OriginalOutput.png)
(https://raw.githubusercontent.com/BloodSharp/CodeObfuscation/master/Images/Original.png)

Sin embargo si se le pasa el mini sistema de protección que cifra y elimina las rutinas:
(https://raw.githubusercontent.com/BloodSharp/CodeObfuscation/master/Images/EncryptedOutput.png)
(https://raw.githubusercontent.com/BloodSharp/CodeObfuscation/master/Images/Encrypted.png)

Como se pudo observar parte de la función que elegí queda cifrada y en ejecución si se ejecuta más de una vez esta se elimina del código asignando opcodes de NOP.

Desventaja:
Requiere deshabilitar el ASLR (https://es.wikipedia.org/wiki/Aleatoriedad_en_la_disposición_del_espacio_de_direcciones) lo cuál no es lo usual hacerlo dado a que esto está habilitado por defecto para evitar exploits.

Cosas para terminar:
Mejorar la detección de las funciones que marcan el que código cifrar y/o eliminar.

Enlace al repositorio:
https://github.com/BloodSharp/CodeObfuscation


B#