首页 > 解决方案 > Windows PE 格式资源传输问题

问题描述

我有两个 .c 文件,一个生成输入可执行文件的加密版本,另一个访问此数据,对其进行解密,然后运行它。我的问题是我希望将加密数据硬编码到第二个文件中,以便它可以作为单个可执行文件本身运行。目前,我的加密程序将二进制数据写入 .dat 格式文件,但是,我希望将其作为资源直接包含在第二个文件中。如何使用 Windows PE 格式资源完成此操作?这两个文件目前都只是 .c 文件。这是我的参考代码:

#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;
}

标签: cwindowswinapi

解决方案


最简单的方法是使用资源编译器将原始 .dat 文件转换为资源文件(通常带有 .res 扩展名),链接器可以拾取用户定义的资源并将其包装到最终可执行文件的映像中。

资源脚本(通常带有 .rc 扩展名)可以像这样简单:

1 256 payload.dat

然后,您将使用FindResource(with MAKEINTRESOURCE(1)and MAKEINTRESOURCE(256)arguments), SizeofResource, LoadResource,LockResource来获取资源的指针和长度,您可以从中提取/解密它。


推荐阅读