FileToCode es una pequeña utilidad para crear el código fuente necesario para incluir un archivo binario en nuestra aplicación, que posteriormente se encargará de restituir dicho archivo en disco. Genera un archivo de texto con el código fuente necesario para definir un array inicializado con los bytes del archivo binario que nos interese. En realidad genera dos archivos, uno en C y otro el pascal, así será válido para nuestro lenguaje favorito. Los nombres de los archivos serán los del archivo original más un guión y extensión C o Pas
respectivamente.
Para reconstruir el archivo original una aplicación deberá escribir en disco el array binario y asignar un nombre de archivo.
Para no sobrecargar de código, sólo expongo las funciones que generan el archivo en C y en pascal:
cpp
//--------------------------------------------------------------------------- // Escribe el código fuente en C int bFileToCode_C(char *Fuente, char *Destino) { int n = 0; FILE *FFile = fopen(Fuente, "rb"); if(FFile==0) return n; int Size = FileSize(FFile); FILE *DFile = fopen(Destino, "wt"); BYTE b; char *Name = ExtractFileName(QuitaExt(Destino)); fprintf(DFile, "int %sSize = %d;\n\n", Name, Size); fprintf(DFile, "char %sBytes[%d] = \n{\n ", Name, Size); for(n=1; n<=Size; n++){ b = fgetc(FFile); fprintf(DFile, "0x%02X, ", b); if(n<Size && n%16 == 0) fprintf(DFile, "\n "); } fseek(DFile, -2, SEEK_CUR); fprintf(DFile, "\n};"); fclose(FFile); fclose(DFile); return n; } //--------------------------------------------------------------------------- // Escribe el código fuente en pascal int bFileToCode_Pas(char *Fuente, char *Destino) { int n = 0; FILE *FFile = fopen(Fuente, "rb"); if(FFile==0) return n; int Size = FileSize(FFile); FILE *DFile = fopen(Destino, "wt"); BYTE b; char *Name = ExtractFileName(QuitaExt(Destino)); fprintf(DFile, "unit %s;\n\ninterface\n\nuses Windows;\n\nvar\n", Name); fprintf(DFile, "%sSize: integer = %d;\n", Name, Size); fprintf(DFile, "%sBytes: array [0..%d] of BYTE = \n(\n ", Name, Size-1); for(n=1; n<=Size; n++){ b = fgetc(FFile); fprintf(DFile, "$%02X, ", b); if(n<Size && n%16 == 0) fprintf(DFile, "\n "); } fseek(DFile, -2, SEEK_CUR); fprintf(DFile, "\n);\nimplementation\nend."); fclose(FFile); fclose(DFile); return n; }
Como ejemplo de uso vamos a reconstruir el mismísimo binario ejecutable de FileToCode.exe
En C la reconstrucción sería de la siguiente manera, aunque se pueden buscar otras variantes:
cpp
#include <windows.h> #pragma hdrstop #include "FileToCode_.c" // incluyo el fuente generado del archivo binario // Función extractora void ExtractFile(char* FileName) { HANDLE hFile = CreateFile(PCHAR(FileName), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0); _lwrite((HFILE)hFile, FileToCode_Bytes, FileToCode_Size); CloseHandle(hFile); } #pragma argsused int main(int argc, char* argv[]) { ExtractFile("FileToCode.exe"); return 0; }
Y en Delphi os propongo este ejemplo:
delphi
program PruebaDelphi; {$APPTYPE CONSOLE} uses SysUtils, Windows, FileToCode_ in 'FileToCode_.pas'; // incluyo el fuente generado del archivo binario // Función extractora procedure ExtractFile(FileName: String); var hFile: THANDLE; begin hFile:= CreateFile(PCHAR(FileName), GENERIC_WRITE, 0, nil, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0); _lwrite(hFile, @FileToCode_Bytes[0], FileToCode_Size); CloseHandle(hFile); end; begin ExtractFile('FileToCode.exe'); end.
De esta manera podréis portar con vuestro ejecutable el archivo que deseéis. Subo los binarios, fuentes y ejemplos.
Espero que este truco os sea de utilidad.
Saludos.