[Delphi] Creacion de un Server Builder con recursos

Iniciado por BigBear, 9 Marzo 2015, 18:45 PM

0 Miembros y 1 Visitante están viendo este tema.

BigBear

[Titulo] : Creacion de un Server Builder con recursos
[Lenguaje] : Delphi
[Autor] : Doddy Hackman

[Temario]

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

0x01 : Introduccion
0x02 : Creacion del builder
0x03 : Creacion del stub
0x04 : Probando el programa
0x05 : Builder Tools

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

0x01 : Introduccion

En este manual les voy a enseñar como hacer un Server Builder en Delphi usando recursos , en el manual anteior les enseñe como hacerlo mediante EOF , algo que no era muy seguro porque los datos estaban en texto plano y se podian leer facilmente , mediante recursos es diferente y para asegurarlo vamos a usar XOR para eso.

Empecemos ...

0x02 : Creacion del builder

Primero vamos hacer el builder , para eso vamos a "File->New->VCL Forms Application" como lo hice en la imagen :



Ahora creamos dos edit y boton con el texto de "Make Server" como en la siguiente imagen :



Despues deben cambiar el titulo del formulario a "Builder" y cambiarle el nombre por defecto que tienen los edits de la siguiente forma :

Edit1 -> ip
Edit2 -> port

Una vez hecho , hacemos doble click en el boton y agregamos el siguiente codigo :

Código (delphi) [Seleccionar]

procedure TForm1.Button1Click(Sender: TObject);
var
 archivo: string; // Declaramos la variable "archivo" como string
 datos: string; // Declaramos la variable "datos" como string
 clave: integer; // Declaramos la variable "clave" como integer
begin
 archivo := 'stubnow.exe';
 // Establecemos la variable "archivo" como el nombre del ejecutable
 // que vamos abrir
 datos := '[ip]' + ip.Text + '[ip]' + '[port]' + port.Text + '[port]';
 // Establecemos los datos que contiene la IP y el puerto separados por etiquetas
 // y los guardamos en la variable "datos"
 clave := 123; // Establecemos la variable "clave" como "123"
 escribir_recurso(archivo, datos, clave);
 // Escribimos el recurso usando la funcion
 // "escribir_recurso" usando como argumentos las variables que acabamos de establecer
 ShowMessage('Done'); // Mostramos un mensaje en pantalla
end;


Fuera del codigo de la funcion "click" del boton agregamos el codigo de estas dos funciones :

Código (delphi) [Seleccionar]

function xor_now(texto: string; clave: integer): string;
// Funcion xor_now con el argumento
// del texto a crifrar y la clave a usar

var
 numero: integer; // Declaramos la variable "numero" como entero
 contenido: string; // Declaramos la variable "contenido" como string
begin
 contenido := ''; // Vaciamos la variable contenido
 for numero := 1 to Length(texto) do // Realizamos un for del "1"
 // a la longitud de la variable texto
 begin
   contenido := contenido + Char(integer(texto[numero]) xor clave);
   // Realizamos el cifrado xor
 end;
 Result := contenido; // Devolvemos como resultado la variable "contenido"
end;

function escribir_recurso(ruta: string; datos: string; clave: integer): bool;
var
 escribiendo: THandle; // Declaramos la variable "escribiendo" como THandle
begin
 datos := xor_now('-0x646F646479206861636B6D616E-' + datos +
   '-0x646F646479206861636B6D616E-', clave);
 // Ciframos los datos usando la funcion xor_now
 // Los parametros que usamos en la funcion xor_now son la variable "datos" como el texto
 // a cifrar , los "datos" estan entre dos delimitadores para facilitar su busqueda y
 // tambien usamos la variable "clave" como key en el cifrado xor
 escribiendo := BeginUpdateResource(pchar(ruta), False);
 // Empezamos el inicio de de la creacion
 // del recurso usando la variable "ruta"
 UpdateResource(escribiendo, MakeIntResource(10), 'CONFIGURATION', 0,
   pchar(datos), (Length(datos) + 1) * SizeOf(datos[1]));
 // Escribimos el recurso usando
 // la variable "datos" como el contenido del recurso y como nombre del recurso usamos
 // "CONFIGURATION"
 EndUpdateResource(escribiendo, False); // Terminamos de crear el recurso
 Result := True; // Devolvemos True como resultado de la funcion
end;


Les deberia quedar algo asi :



Con eso ya estaria el builder entonces guardamos el proyecto como "builder_now" o como quieran para terminar el builder.

0x03 : Creacion del stub

Ahora vamos a codear el Stub para eso vamos a "File->New->VCL Forms Application" como lo hice en la imagen :



La idea es buscar el recurso en el ejecutable mismo , entonces para eso vamos a crear dos edits y un boton con el texto de "Get Values".

Despues deben poner como titulo del formulario "Stub" y cambiar los names de los edits de la siguiente forma :

Edit1 -> ip
Edit2 -> port

El formulario les deberia quedar algo asi :



Ahora hacemos doble click en el boton y ponemos el siguiente codigo :

Código (delphi) [Seleccionar]

procedure TForm1.Button1Click(Sender: TObject);
var
 clave: integer; // Declaramos la variable "clave" como integer
 datos: string; // Declaramos la variable "datos" como string
 ip_found: string; // Declaramos la variable "ip_found" como string
 port_found: string; // Declaramos la variable "port_found" como string
begin
 clave := 123; // Establecemos la variable "clave" como 123
 datos := leer_recurso(clave); // Leemos el recurso usando el key que esta
 // en la variable clave y guardamos los datos en la variable "datos"
 ip_found := regex(datos, '[ip]', '[ip]');
 // Usamos la funcion regex() para buscar
 // la ip y la guardamos en la variable "ip_found"
 port_found := regex(datos, '[port]', '[port]');
 // Usamos la funcion regex() para
 // buscar el puerto y lo guardamos en la variable "port_found"
 ip.text := ip_found; // Mostramos en el edit "ip" la IP
 port.text := port_found; // Mostramos en el edit "port" el puerto
 ShowMessage('Loaded'); // Mostramos en pantalla un mensaje
end;


Despues ponemos las siguientes funciones fuera del codigo del boton :

Código (delphi) [Seleccionar]

function regex(text: string; deaca: string; hastaaca: string): string;
begin
 Delete(text, 1, AnsiPos(deaca, text) + Length(deaca) - 1);
 SetLength(text, AnsiPos(hastaaca, text) - 1);
 Result := text;
end;

function xor_now(texto: string; clave: integer): string;
// Funcion xor_now con el argumento
// del texto a crifrar y la clave a usar

var
 numero: integer; // Declaramos la variable "numero" como entero
 contenido: string; // Declaramos la variable "contenido" como string
begin
 contenido := ''; // Vaciamos la variable contenido
 for numero := 1 to Length(texto) do // Realizamos un for del "1"
 // a la longitud de la variable texto
 begin
   contenido := contenido + Char(integer(texto[numero]) xor clave);
   // Realizamos el cifrado xor
 end;
 Result := contenido; // Devolvemos como resultado la variable contenido
end;

function leyendo_recurso: string;
var
 leyendo1: HRSRC; // Establecemos la variable "leyendo1" como HRSRC
 leyendo2: DWORD; // Establecemos la variable "leyendo2" como DWORD
 leyendo3: THandle; // Establecemos la variable "leyendo3" como THandle
 leyendo4: pointer; // Establecemos la variable "leyendo4" como Pointer
begin
 leyendo1 := FindResource(hInstance, 'CONFIGURATION', RT_RCDATA);
 // Buscamos el recurso
 // "CONFIGURATION"
 leyendo2 := SizeofResource(hInstance, leyendo1);
 // Calculamos la tamaño del recurso
 leyendo3 := LoadResource(hInstance, leyendo1); // Cargamos el recurso
 leyendo4 := LockResource(leyendo3);
 // Bloqueamos el recurso para poder leerlo despues
 if leyendo4 <> nil then // Si "leyendo4" no esta null ...
 begin
   SetLength(Result, leyendo2 - 1); // Cambiamos la longitud de Result
   CopyMemory(@Result[1], leyendo4, leyendo2);
   // Copiamos los datos al resultado de la funcion
   FreeResource(leyendo3); // Liberamos el recurso
 end;
end;

function leer_recurso(clave: integer): string;
var
 datos: string; // Declaramos la variable "datos" como string
begin
 datos := xor_now(leyendo_recurso, clave);
 // Realizamos el cifrado xor con los datos que usamos
 // como argumentos de la funcion leer_recurso()
 datos := regex(datos, '-0x646F646479206861636B6D616E-',
   '-0x646F646479206861636B6D616E-');
 // Usamos la funcion regex() para cortar los delimitadores
 // y encontrar asi los datos del recurso para despues guardar el
 // resultado en la variable "datos"
 Result := datos;
 // Devolvemos como resultado lo que contiene la variable "datos"
end;


El codigo les deberia quedar asi :



Guardan el proyecto con el nombre que quieran y con eso ya estaria listo el stub.

0x04 : Probando el programa

Para probarlo cargamos el builder y llenamos los campos de IP y Puerto como quieran , un ejemplo de como los complete yo seria  :



Despues presionan el boton "Make Server" y listo.

Ahora cargamos el stub y le damos al boton "Get Values" , deberian ver como resultado algo como esto :



Si no ven algo como en la imagen es porque hicieron algo mal en el codigo.

0x05 : Builder Tools

Como regalo les dejo esta Unit que hice en Delphi sobre como hacer un Builder , contiene funciones para EOF y Recursos , en los dos casos uso XOR para cifrar los datos , tambien viene con ejemplos de uso.

Solo deben agregar "builder_tools" en el parte de "uses" del codigo y listo , podran usar las funciones.

El codigo :

Código (delphi) [Seleccionar]

// Unit : Builder Tools
// Version : 0.2
// (C) Doddy Hackman 2015
// Credits : Resources based in http://www.hackforums.net/showthread.php?tid=1422700
// Examples :
// escribir_eof('stub.exe','-delimitador-','-delimitador-','test',123);
// leer_eof('stub.exe','-delimitador-','-delimitador-',123);
// escribir_recurso('stub.exe','test',123);
// leer_recurso(123);

unit builder_tools;

interface

uses SysUtils, Windows;

function leer_eof(ruta, delimitador1, delimitador2: string;
 clave: integer): string;
function escribir_eof(ruta, delimitador1, delimitador2, texto: string;
 clave: integer): bool;
function escribir_recurso(ruta: string; datos: string; clave: integer): bool;
function leyendo_recurso: string;
function leer_recurso(clave: integer): string;
function xor_now(texto: string; clave: integer): string;
function regex(text: string; deaca: string; hastaaca: string): string;

implementation

function xor_now(texto: string; clave: integer): string;
var
 numero: integer;
 contenido: string;
begin
 contenido := '';
 for numero := 1 to Length(texto) do
 begin
   contenido := contenido + Char(integer(texto[numero]) xor clave);
 end;
 Result := contenido;
end;

function regex(text: string; deaca: string; hastaaca: string): string;
begin
 Delete(text, 1, AnsiPos(deaca, text) + Length(deaca) - 1);
 SetLength(text, AnsiPos(hastaaca, text) - 1);
 Result := text;
end;

function leer_eof(ruta, delimitador1, delimitador2: string;
 clave: integer): string;
var
 ob: THandle;
 code: Array [0 .. 9999 + 1] of Char;
 nose: DWORD;
 resultado: string;

begin

 ob := INVALID_HANDLE_VALUE;
 code := '';

 ob := CreateFile(pchar(ruta), GENERIC_READ, FILE_SHARE_READ, nil,
   OPEN_EXISTING, 0, 0);
 if (ob <> INVALID_HANDLE_VALUE) then
 begin
   SetFilePointer(ob, -9999, nil, FILE_END);
   ReadFile(ob, code, 9999, nose, nil);
   CloseHandle(ob);
 end;

 resultado := regex(code, delimitador1, delimitador2);
 resultado := xor_now(resultado, clave);
 Result := resultado;

end;

function escribir_eof(ruta, delimitador1, delimitador2, texto: string;
 clave: integer): bool;
var
 linea: string;
 aca: THandle;
 code: Array [0 .. 9999 + 1] of Char;
 nose: DWORD;
 marca_uno: string;
 marca_dos: string;

begin

 aca := INVALID_HANDLE_VALUE;
 nose := 0;

 begin
   linea := delimitador1 + xor_now(texto, clave) + delimitador2;
   StrCopy(code, pchar(linea));
   aca := CreateFile(pchar(ruta), GENERIC_WRITE, FILE_SHARE_READ, nil,
     OPEN_EXISTING, 0, 0);
   if (aca <> INVALID_HANDLE_VALUE) then
   begin
     SetFilePointer(aca, 0, nil, FILE_END);
     WriteFile(aca, code, 9999, nose, nil);
     CloseHandle(aca);
     Result := True;
   end
   else
   begin
     Result := False;
   end;
 end;
end;

function escribir_recurso(ruta: string; datos: string; clave: integer): bool;
var
 escribiendo: THandle;
begin
 datos := xor_now('-0x646F646479206861636B6D616E-' + datos +
   '-0x646F646479206861636B6D616E-', clave);
 escribiendo := BeginUpdateResource(pchar(ruta), False);
 UpdateResource(escribiendo, MakeIntResource(10), 'CONFIGURATION', 0,
   pchar(datos), (Length(datos) + 1) * SizeOf(datos[1]));
 EndUpdateResource(escribiendo, False);
 Result := True;
end;

function leyendo_recurso: string;
var
 leyendo1: HRSRC;
 leyendo2: DWORD;
 leyendo3: THandle;
 leyendo4: pointer;
begin
 leyendo1 := FindResource(hInstance, 'CONFIGURATION', RT_RCDATA);
 leyendo2 := SizeofResource(hInstance, leyendo1);
 leyendo3 := LoadResource(hInstance, leyendo1);
 leyendo4 := LockResource(leyendo3);
 if leyendo4 <> nil then
 begin
   SetLength(Result, leyendo2 - 1);
   CopyMemory(@Result[1], leyendo4, leyendo2);
   FreeResource(leyendo3);
 end;
end;

function leer_recurso(clave: integer): string;
var
 datos: string;
begin
 datos := xor_now(leyendo_recurso, clave);
 datos := regex(datos, '-0x646F646479206861636B6D616E-',
   '-0x646F646479206861636B6D616E-');
 Result := datos;
end;

end.

// The End ?


Eso seria todo.

--========--
 The End ?
--========--

Version PDF.

Version en VideoTutorial :

[youtube=640,360]https://www.youtube.com/watch?v=RQw7NEG94go[/youtube]