0

I have two .c files, one that generates an encrypted version of an input executable and another that accesses this data, decrypts it, and then runs it. My issue is I want the encrypted data to be hardcoded into the second file so that it can be run as a single executable itself. Currently, my encryption program writes the binary data to a .dat format file, however, I want this to be directly included in the second file as a resource. How can I accomplish this with Windows PE format resources? Both files are currently just .c files. Here is my code for reference:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/aes.h>

void handleErrors(void){
  ERR_print_errors_fp(stderr);
  abort();
}

int main(){
  //read in the exe file and convert its bytes to a string
  FILE *inFile;
  inFile = fopen("Quasar.exe","rb");
  if (inFile == NULL){
    perror("Failed to read in file\n");
  }

  printf("File read in complete!\n");

  if(fseek(inFile , 0 , SEEK_END) == -1){
    perror("Offset error\n");
  };
    unsigned long lSize = ftell(inFile);
  if (lSize == -1){
    perror("Size error\n");
  }
    rewind(inFile);

  unsigned char *unencryptedText = (unsigned char*) malloc (sizeof(unsigned char)*lSize);
    fread(unencryptedText,1,lSize,inFile);
    fclose(inFile);

  unsigned char *encryptedText = (unsigned char*) malloc (3 *(sizeof(unsigned char)*lSize));

  //encrypt these bytes with open ssl
  printf("Encrypting...\n");
  int outlen, tmplen;
  unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
  unsigned char iv[] = {1,2,3,4,5,6,7,8};
  EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();

  EVP_CIPHER_CTX_init(ctx);
  EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);

  if(EVP_EncryptUpdate(ctx, encryptedText, &outlen, unencryptedText, lSize *sizeof(char)) == 0){
    ERR_print_errors_fp(stderr);
    return 0;
  }
      
  if(EVP_EncryptFinal_ex(ctx, encryptedText + outlen, &tmplen) == 0){
    ERR_print_errors_fp (stderr);
    return 0;
  }
  outlen += tmplen;
  EVP_CIPHER_CTX_cleanup(ctx);
  printf("Encrypt Success!\n");

  char absPath[500];
    strcpy (absPath, "encrypted.dat");
    FILE *outFile = fopen(absPath, "wb");
    fwrite(encryptedText, lSize, 1, outFile);
    fclose (outFile);


//decrypt
unsigned char *decryptedText = (unsigned char*) malloc (sizeof(unsigned char)*lSize);
EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);

if(EVP_DecryptUpdate(ctx, decryptedText, &outlen, encryptedText, lSize) == 0){
  ERR_print_errors_fp (stderr);
  return 0;
}

EVP_CIPHER_CTX_cleanup(ctx);
printf("Decrypt Success!\n");


 //write
char absPath2[500];
strcpy (absPath2, "decrypted.exe");
FILE *outFile2 = fopen(absPath2, "wb");
fwrite(decryptedText, lSize, 1, outFile);
fclose (outFile2);
return 0;
}
James
  • 127
  • 11
  • One traditional way is to use the data to generate C code with a variable initialization. Include/compile it into the second binary and you have the data in a variable without having to do anything extra: https://stackoverflow.com/questions/62731498/c-generate-a-header-file-via-a-binary-file –  May 18 '21 at 17:56
  • It sounds like you are re-inventing the self-extracting archive. Why not pick an existing self-extracting archive tool that supports encryption? – Ben Voigt May 18 '21 at 22:09
  • Related: https://security.stackexchange.com/q/36711/3034 – Ben Voigt May 18 '21 at 22:10

1 Answers1

0

The easiest way would be to use the resource compiler to translate the raw .dat file into a resource file (commonly with a .res extension) the linker can pick up and wrap the user-defined resource into the final executable's image.

A resource script (commonly with an .rc extension) can be as simple as this:

1 256 payload.dat

You would then use FindResource (with MAKEINTRESOURCE(1) and MAKEINTRESOURCE(256) arguments), SizeofResource, LoadResource, LockResource to get a pointer and length of the resource, from where you can extract/decrypt it.

IInspectable
  • 46,945
  • 8
  • 85
  • 181
  • Thanks this helps a lot! Do I need to install the resource compiler? I'm working on a mac and when I try to run RC myscript.rc I get that the command is not recognized? – James May 18 '21 at 18:58
  • RC.exe is a tool that ships with Visual Studio for PC and the Windows SDK. I'm not aware of a version that would run on macOS. The comparison for [Visual Studio for PC and Mac](https://visualstudio.microsoft.com/vs/mac/#vs_mac_table) doesn't list the ability to develop C++ applications. I'm not familiar with tooling support for macOS that would allow you to compile a PE image to run on Windows. – IInspectable May 18 '21 at 20:22
  • Can i generate the RC object on another computer then link it on my mac? – James May 18 '21 at 21:50
  • That's probably possible, but you'll still need Microsoft's linker that understands the resource file format, and creates a resource object from it. – IInspectable May 18 '21 at 21:53
  • Hey, I followed your advice and was able to create and compile the resource file. I'm using MSVC how can I link this file while compiling? – James May 21 '21 at 14:38
  • Just pass the compiled .res file to the linker the same way you pass .obj files to it. – IInspectable May 21 '21 at 15:46
  • Thanks so much for the help and sorry I’m such a noob here ;). The command line option for linker is /link then the library right? I’m using MSVC as my compiler and I want to link a library stored at say C:/OpenSSL and the include files are at C:/OpenSSL/include. Would I do /link then these directories? – James May 21 '21 at 16:01
  • You can use *cl.exe* as a compiler and linker. You'd use the [/link](https://learn.microsoft.com/en-us/cpp/build/reference/link-pass-options-to-linker) command line option in this case. The linker is *link.exe* which you can invoke directly. The [reference](https://learn.microsoft.com/en-us/cpp/build/reference/linking) explains how to use it. I'm not familiar with OpenSSL's directory layout, though *include* is commonly used with header files (which you cannot pass to a linker). Likewise, I don't know where the import libraries are deployed. – IInspectable May 22 '21 at 15:56