c - 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;
}
解决方案
最简单的方法是使用资源编译器将原始 .dat 文件转换为资源文件(通常带有 .res 扩展名),链接器可以拾取用户定义的资源并将其包装到最终可执行文件的映像中。
资源脚本(通常带有 .rc 扩展名)可以像这样简单:
1 256 payload.dat
然后,您将使用FindResource
(with MAKEINTRESOURCE(1)
and MAKEINTRESOURCE(256)
arguments), SizeofResource
, LoadResource
,LockResource
来获取资源的指针和长度,您可以从中提取/解密它。
推荐阅读
- postman - 转义或忽略邮递员变量
- ansible - 如何在ansible中使用命令行添加变量?
- php - Xdebug 2 与 Xdebug 3 - 代码覆盖率的差异
- kubernetes - Kubernetes API 容器不断死亡
- c++ - Xcode:致命错误:找不到“iostream”文件
- python - Python 是否对递归循环有内部限制?
- r - 即使不满足条件,是否有 R 函数可以保留所有行?
- thunderbird - Thunderbird:如何向文件夹的所有收件人发送邮件
- javascript - 使用溢出省略号Angular 7创建显示更多效果
- ruby-on-rails - 基于复选框输入的简单表单