hey,
I have a program that uses a certain algorithm to decrypt dll files from the game, half-life. but once i have decrypted them, the game crashed whenever i try to start it with the un-encrypted files. How would I reverse the algorithm, making the program encrypt them instead of decrypting them. I have the code and it is posted below:
hldlldec.c:
/*
Copyright 2007 Luigi Auriemma
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
http://www.gnu.org/licenses/gpl.txt
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>
#include <ctype.h>
#include "pe.h"
#define VER "0.1"
#define round(n) (((n + (PE_align - 1)) / PE_align) * PE_align)
void halflife_dll_decrypt(uint8_t *data, uint32_t datasz);
void find_impexp_tables(uint8_t *base, uint32_t baseoff, uint32_t *impoff, uint32_t *impsz, uint32_t *expoff, uint32_t *expsz);
void dump_section(FILE *fd, uint32_t num, uint8_t *data, uint32_t datasz);
uint8_t *fd_read(uint8_t *name, int *fdlen);
void fd_write(uint8_t *name, uint8_t *data, int datasz);
void std_err(void);
int dump = 0;
uint8_t *in_file,
*out_file;
int main(int argc, char *argv[]) {
uint32_t filelen;
int i;
uint8_t *filebuff;
fputs("\n"
"Half-life DLL decrypter and rebuilder "VER"\n"
"by Luigi Auriemma\n"
"e-mail: aluigi@autistici.org\n"
"web: aluigi.org\n"
"\n", stdout);
if(argc < 3) {
printf("\n"
"Usage: %s [options] <input.DLL> <output.DLL>\n"
"\n"
"Options:\n"
"-d dump all the sections of the DLL instead of building the PE file,\n"
" use <output.DLL> as base for the sequential output filename\n"
"\n", argv[0]);
exit(1);
}
argc -= 2;
for(i = 1; i < argc; i++) {
if(((argv[i][0] != '-') && (argv[i][0] != '/')) || (strlen(argv[i]) != 2)) {
printf("\nError: recheck your options (%s is not valid)\n", argv[i]);
exit(1);
}
switch(argv[i][1]) {
case 'd': dump = 1; break;
default: {
printf("\nError: wrong command-line argument (%s)\n\n", argv[i]);
exit(1);
} break;
}
}
in_file = argv[argc];
out_file = argv[argc + 1];
filebuff = fd_read(in_file, &filelen);
halflife_dll_decrypt(filebuff, filelen);
printf("\n- the DLL has been decrypted and %s\n", dump
? "dumped in the various section files"
: "rebuilt");
free(filebuff);
return(0);
}
void halflife_dll_decrypt(uint8_t *data, uint32_t datasz) {
typedef struct {
uint32_t Characteristics;
uint32_t Sections;
uint32_t copywhat;
uint32_t ImageBase;
uint32_t EntryPoint;
uint32_t ImportTable;
} hlhdr_t;
typedef struct {
uint32_t rva;
uint32_t raw_size;
uint32_t virtual_size;
uint32_t file_offset;
uint32_t zero;
} hlsec_t;
const static char *sec_names[4] = { ".text", ".rdata", ".data", ".rsrc" };
hlhdr_t *hlhdr;
hlsec_t *hlsec;
FILE *fd;
uint32_t i,
fdoff,
peoff;
uint8_t chr,
*base;
if(*(uint32_t *)(data + 64) != 0x12345678) {
printf("\nAlert: this DLL doesn't seem encrypted with the Valve algorithm\n");
}
base = data;
data += 68;
datasz -= 68;
chr = 'W';
for(i = 0; i < datasz; i++) {
data[i] ^= chr;
chr += data[i] + 'W';
}
hlhdr = (void *)data;
hlsec = (void *)(data + sizeof(hlhdr_t));
hlhdr->copywhat ^= 0x7a32bc85;
hlhdr->ImageBase ^= 0x49c042d1;
hlhdr->ImportTable ^= 0x872c3d47;
hlhdr->EntryPoint -= 12;
printf("\n"
" Characteristics %08x\n"
" Sections %08x\n"
" copywhat %08x\n"
" ImageBase %08x\n"
" EntryPoint %08x\n"
" ImportTable %08x\n",
hlhdr->Characteristics,
hlhdr->Sections,
hlhdr->copywhat,
hlhdr->ImageBase,
hlhdr->EntryPoint,
hlhdr->ImportTable);
for(i = 0; i <= hlhdr->Sections; i++) {
printf("\n"
"- section %u\n"
" raw_size %08x\n"
" virtual_size %08x\n"
" file_offset %08x\n"
" rva %08x\n"
" zero %08x\n",
i,
hlsec[i].raw_size,
hlsec[i].virtual_size,
hlsec[i].file_offset,
hlsec[i].rva,
hlsec[i].zero);
if(dump) {
dump_section(NULL, i, base + hlsec[i].file_offset, hlsec[i].virtual_size);
}
}
if(dump) return;
printf("\n");
/* when all the section have been placed in memory */
/* HL.EXE calls hlhdr->EntryPoint and then hlhdr->copywhat */
/* copying a zone of the DLL in the HL.EXE process */
/* IMPORTANT NOTE */
/* all the PE stuff here and in pe.h seems to work fine */
/* but for the moment I consider it only a work-around */
/* so don't take it too seriously */
for(i = 0; i <= hlhdr->Sections; i++) {
PE_size_image += round(hlsec[i].raw_size);
}
PE_sections = hlhdr->Sections + 1;
PE_size_code = hlsec[0].raw_size;
PE_entry_point = hlhdr->EntryPoint - hlhdr->ImageBase;
PE_base_code = hlsec[0].rva - hlhdr->ImageBase;
PE_image_base = hlhdr->ImageBase;
PE_Characteristics = hlhdr->Characteristics;
printf("- search offsets and sizes of the import and export tables\n");
PE_import_rva = hlhdr->ImportTable;
find_impexp_tables(
base + hlsec[1].file_offset,
hlsec[1].rva,
&PE_import_rva, &PE_import_size,
&PE_export_rva, &PE_export_size);
PE_import_rva -= PE_image_base;
PE_export_rva -= PE_image_base;
if(hlhdr->Sections >= 3) {
PE_resource_rva = hlsec[3].rva - PE_image_base;
PE_resource_size = hlsec[3].virtual_size;
}
printf("- now I try to build the PE DLL (experimental)\n\n");
fd = fopen(out_file, "wb");
if(!fd) std_err();
PE_dos_fwrite(fd);
PE_sign_fwrite(fd);
PE_file_fwrite(fd);
PE_optional_fwrite(fd);
peoff = ftell(fd);
fseek(fd, PE_base_code, SEEK_SET);
for(i = 0; i <= hlhdr->Sections; i++) {
fdoff = ftell(fd);
printf(" section %u -> %08x -> %08x\n",
i,
(uint32_t)ftell(fd),
hlsec[i].rva);
dump_section(fd, i, base + hlsec[i].file_offset, hlsec[i].virtual_size);
hlsec[i].file_offset = fdoff; // here file_offset becomes our new offset
}
fseek(fd, peoff, SEEK_SET);
for(i = 0; i <= hlhdr->Sections; i++) {
PE_Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE |
IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA |
IMAGE_SCN_MEM_WRITE;
PE_virtual_size = hlsec[i].virtual_size;
PE_rva = hlsec[i].rva;
PE_raw_size = hlsec[i].raw_size;
PE_file_offset = hlsec[i].file_offset;
if(i < 4) {
strcpy(PE_section_name, sec_names[i]);
} else {
sprintf(PE_section_name, "sec%u", i);
}
PE_section_fwrite(fd);
}
fclose(fd);
}
/* the following stupid function takes the data where starts the import table */
/* and finds its size and the offset and size of the export table too */
void find_impexp_tables(uint8_t *base, uint32_t baseoff, uint32_t *impoff, uint32_t *impsz, uint32_t *expoff, uint32_t *expsz) {
uint32_t off,
maxoff;
uint16_t hint;
uint8_t *data,
*p;
data = base + (*impoff - baseoff);
p = data;
maxoff = 0;
while((off = *(uint32_t *)(p + 12))) {
if(off > maxoff) maxoff = off;
p += 20;
}
maxoff -= (baseoff - PE_image_base);
p = base + maxoff;
while(*p++);
if((p - base) & 1) p++;
while((hint = *(uint16_t *)p)) {
p += 2;
while(*p++);
if((p - base) & 1) p++;
}
while(!*p) p++; // blah I think it's lame
p -= ((p - base) & 3);
p -= 4;
*impsz = p - data;
*expoff = (p - base) + baseoff;
data = p;
off = *(uint32_t *)(p + 12);
off -= (baseoff - PE_image_base);
p = base + off;
while(*p) {
while(*p++);
}
if((p - base) & 1) p++;
*expsz = p - data;
printf("- import table found: %08x -> %u\n", *impoff - baseoff, *impsz);
printf("- export table found: %08x -> %u\n", *expoff - baseoff, *expsz);
}
void dump_section(FILE *fd, uint32_t num, uint8_t *data, uint32_t datasz) {
uint32_t i,
zero;
uint8_t *fname = NULL,
*p;
if(dump) {
fname = malloc(strlen(out_file) + 12);
p = strrchr(out_file, '.');
if(p) {
sprintf(fname, "%.*s_%u.%s", p - out_file, out_file, num, p + 1);
} else {
sprintf(fname, "%s_%u.dll", out_file, num);
}
printf("- write %s\n", fname);
fd = fopen(fname, "wb");
if(!fd) std_err();
}
fwrite(data, datasz, 1, fd);
if(dump) {
fclose(fd);
free(fname);
} else {
zero = round(datasz);
for(i = datasz; i < zero; i++) {
fputc(0, fd);
}
}
}
uint8_t *fd_read(uint8_t *name, int *fdlen) {
struct stat xstat;
FILE *fd;
uint8_t *buff;
printf("- open file %s\n", name);
fd = fopen(name, "rb");
if(!fd) std_err();
fstat(fileno(fd), &xstat);
buff = malloc(xstat.st_size);
fread(buff, xstat.st_size, 1, fd);
fclose(fd);
*fdlen = xstat.st_size;
return(buff);
}
void fd_write(uint8_t *name, uint8_t *data, int datasz) {
FILE *fd;
printf("- create file %s\n", name);
fd = fopen(name, "rb");
if(fd) {
fclose(fd);
printf("- file already exists, do you want to overwrite it (y/N)?\n ");
fflush(stdin);
if(tolower(fgetc(stdin)) != 'y') exit(1);
}
fd = fopen(name, "wb");
if(!fd) std_err();
fwrite(data, datasz, 1, fd);
fclose(fd);
}
void std_err(void) {
perror("\nError");
exit(1);
}
pe.h:
/*
Copyright 2007 Luigi Auriemma
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
http://www.gnu.org/licenses/gpl.txt
*/
#include <stdio.h>
#include <stdlib.h>
#include <cstdint.h>
#include <string.h>
/* DEFINES */
#define IMAGE_DOS_SIGNATURE 0x5A4D
#define IMAGE_OS2_SIGNATURE 0x454E
#define IMAGE_OS2_SIGNATURE_LE 0x454C
#define IMAGE_VXD_SIGNATURE 0x454C
#define IMAGE_NT_SIGNATURE 0x00004550
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC
#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56
#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224
#define IMAGE_SIZEOF_SHORT_NAME 8
#define IMAGE_SIZEOF_SECTION_HEADER 40
#define IMAGE_SIZEOF_SYMBOL 18
#define IMAGE_SIZEOF_AUX_SYMBOL 18
#define IMAGE_SIZEOF_RELOCATION 10
#define IMAGE_SIZEOF_BASE_RELOCATION 8
#define IMAGE_SIZEOF_LINENUMBER 6
#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_RELOCS_STRIPPED 1
#define IMAGE_FILE_EXECUTABLE_IMAGE 2
#define IMAGE_FILE_LINE_NUMS_STRIPPED 4
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 8
#define IMAGE_FILE_AGGRESIVE_WS_TRIM 16
#define IMAGE_FILE_LARGE_ADDRESS_AWARE 32
#define IMAGE_FILE_BYTES_REVERSED_LO 128
#define IMAGE_FILE_32BIT_MACHINE 256
#define IMAGE_FILE_DEBUG_STRIPPED 512
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 1024
#define IMAGE_FILE_NET_RUN_FROM_SWAP 2048
#define IMAGE_FILE_SYSTEM 4096
#define IMAGE_FILE_DLL 8192
#define IMAGE_FILE_UP_SYSTEM_ONLY 16384
#define IMAGE_FILE_BYTES_REVERSED_HI 32768
#define IMAGE_SUBSYSTEM_UNKNOWN 0
#define IMAGE_SUBSYSTEM_NATIVE 1
#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2
#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3
#define IMAGE_SUBSYSTEM_OS2_CUI 5
#define IMAGE_SUBSYSTEM_POSIX_CUI 7
#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8
#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9
#define IMAGE_SUBSYSTEM_XBOX 14
#define IMAGE_SCN_CNT_CODE 32
#define IMAGE_SCN_CNT_INITIALIZED_DATA 64
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 128
#define IMAGE_SCN_LNK_OTHER 256
#define IMAGE_SCN_LNK_INFO 512
#define IMAGE_SCN_TYPE_OVER 1024
#define IMAGE_SCN_LNK_REMOVE 2048
#define IMAGE_SCN_LNK_COMDAT 4096
#define IMAGE_SCN_MEM_DISCARDABLE 0x2000000
#define IMAGE_SCN_MEM_NOT_CACHED 0x4000000
#define IMAGE_SCN_MEM_NOT_PAGED 0x8000000
#define IMAGE_SCN_MEM_SHARED 0x10000000
#define IMAGE_SCN_MEM_EXECUTE 0x20000000
#define IMAGE_SCN_MEM_READ 0x40000000
#define IMAGE_SCN_MEM_WRITE 0x80000000
/* STRUCTURES */
typedef struct {
uint16_t e_magic;
uint16_t e_cblp;
uint16_t e_cp;
uint16_t e_crlc;
uint16_t e_cparhdr;
uint16_t e_minalloc;
uint16_t e_maxalloc;
uint16_t e_ss;
uint16_t e_sp;
uint16_t e_csum;
uint16_t e_ip;
uint16_t e_cs;
uint16_t e_lfarlc;
uint16_t e_ovno;
uint16_t e_res[4];
uint16_t e_oemid;
uint16_t e_oeminfo;
uint16_t e_res2[10];
int32_t e_lfanew;
} IMAGE_DOS;
typedef struct {
uint16_t Machine;
uint16_t NumberOfSections;
uint32_t TimeDateStamp;
uint32_t PointerToSymbolTable;
uint32_t NumberOfSymbols;
uint16_t SizeOfOptionalHeader;
uint16_t Characteristics;
} IMAGE_FILE;
typedef struct {
uint32_t VirtualAddress;
uint32_t Size;
} IMAGE_DATA_DIRECTORY;
typedef struct {
uint16_t Magic;
uint8_t MajorLinkerVersion;
uint8_t MinorLinkerVersion;
uint32_t SizeOfCode;
uint32_t SizeOfInitializedData;
uint32_t SizeOfUninitializedData;
uint32_t AddressOfEntryPoint;
uint32_t BaseOfCode;
uint32_t BaseOfData;
uint32_t ImageBase;
uint32_t SectionAlignment;
uint32_t FileAlignment;
uint16_t MajorOperatingSystemVersion;
uint16_t MinorOperatingSystemVersion;
uint16_t MajorImageVersion;
uint16_t MinorImageVersion;
uint16_t MajorSubsystemVersion;
uint16_t MinorSubsystemVersion;
uint32_t Win32VersionValue;
uint32_t SizeOfImage;
uint32_t SizeOfHeaders;
uint32_t CheckSum;
uint16_t Subsystem;
uint16_t DllCharacteristics;
uint32_t SizeOfStackReserve;
uint32_t SizeOfStackCommit;
uint32_t SizeOfHeapReserve;
uint32_t SizeOfHeapCommit;
uint32_t LoaderFlags;
uint32_t NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL32;
#define PE_DIR_ExportTable DataDirectory[0]
#define PE_DIR_ImportTable DataDirectory[1]
#define PE_DIR_Resource DataDirectory[2]
#define PE_DIR_Exception DataDirectory[3]
#define PE_DIR_Security DataDirectory[4]
#define PE_DIR_Relocation DataDirectory[5]
#define PE_DIR_Debug DataDirectory[6]
#define PE_DIR_Copyright DataDirectory[7]
#define PE_DIR_GlobalPtr DataDirectory[8]
#define PE_DIR_TLSTable DataDirectory[9]
#define PE_DIR_LoadConfig DataDirectory[10]
#define PE_DIR_BoundImport DataDirectory[11]
#define PE_DIR_IAT DataDirectory[12]
#define PE_DIR_DelayImport DataDirectory[13]
#define PE_DIR_COM DataDirectory[14]
#define PE_DIR_Reserved DataDirectory[15]
typedef struct {
uint8_t Name[IMAGE_SIZEOF_SHORT_NAME];
union {
uint32_t PhysicalAddress;
uint32_t VirtualSize;
} Misc;
uint32_t VirtualAddress;
uint32_t SizeOfRawData;
uint32_t PointerToRawData;
uint32_t PointerToRelocations;
uint32_t PointerToLinenumbers;
uint16_t NumberOfRelocations;
uint16_t NumberOfLinenumbers;
uint32_t Characteristics;
} IMAGE_SECTION_HEADER;
/* GLOBAL VARIABLES */
uint32_t PE_align = 0x1000,
PE_sections = 0,
PE_size_code = 0,
PE_entry_point = 0,
PE_base_code = 0x00001000,
PE_image_base = 0,
PE_size_image = 0,
PE_Characteristics = 0,
PE_virtual_size = 0,
PE_file_offset = 0,
PE_raw_size = 0,
PE_rva = 0,
PE_export_rva = 0,
PE_export_size = 0,
PE_import_rva = 0,
PE_import_size = 0,
PE_iat_rva = 0,
PE_iat_size = 0,
PE_resource_rva = 0,
PE_resource_size = 0;
uint8_t PE_section_name[IMAGE_SIZEOF_SHORT_NAME];
/* FUNCTIONS */
void PE_dos_fwrite(FILE *fd) {
IMAGE_DOS hdr;
const static uint8_t dosdata[64] =
"\x0E\x1F\xBA\x0E\x00\xB4\x09\xCD\x21\xB8\x01\x4C\xCD\x21\x54\x68"
"\x69\x73\x20\x70\x72\x6F\x67\x72\x61\x6D\x20\x63\x61\x6E\x6E\x6F"
"\x74\x20\x62\x65\x20\x72\x75\x6E\x20\x69\x6E\x20\x44\x4F\x53\x20"
"\x6D\x6F\x64\x65\x2E\x0D\x0D\x0A\x24\x00\x00\x00\x00\x00\x00\x00";
memset(&hdr, 0, sizeof(hdr));
hdr.e_magic = IMAGE_DOS_SIGNATURE;
hdr.e_cblp = 0x0090;
hdr.e_cp = 0x0003;
hdr.e_cparhdr = 0x0004;
hdr.e_maxalloc = 0xffff;
hdr.e_sp = 0x00b8;
hdr.e_lfarlc = 0x0040;
hdr.e_lfanew = sizeof(hdr) + sizeof(dosdata);
fwrite(&hdr, sizeof(hdr), 1, fd);
fwrite(&dosdata, sizeof(dosdata), 1, fd);
}
void PE_sign_fwrite(FILE *fd) {
uint32_t hdr;
hdr = IMAGE_NT_SIGNATURE;
fwrite(&hdr, sizeof(hdr), 1, fd);
}
void PE_file_fwrite(FILE *fd) {
IMAGE_FILE hdr;
memset(&hdr, 0, sizeof(hdr));
hdr.Machine = IMAGE_FILE_MACHINE_I386;
hdr.NumberOfSections = PE_sections;
hdr.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL32);
hdr.Characteristics = PE_Characteristics;
fwrite(&hdr, sizeof(hdr), 1, fd);
}
void PE_optional_fwrite(FILE *fd) {
IMAGE_OPTIONAL32 hdr;
memset(&hdr, 0, sizeof(hdr));
hdr.Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC;
hdr.SizeOfCode = PE_size_code;
hdr.SizeOfInitializedData = PE_size_image - PE_size_code;
hdr.AddressOfEntryPoint = PE_entry_point;
hdr.BaseOfCode = PE_base_code;
hdr.ImageBase = PE_image_base;
hdr.SectionAlignment = PE_align;
hdr.FileAlignment = PE_align;
hdr.MajorOperatingSystemVersion = 4;
hdr.MajorSubsystemVersion = 4;
hdr.SizeOfImage = PE_size_image;
hdr.SizeOfHeaders = PE_base_code;
hdr.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
hdr.SizeOfStackReserve = 0x00100000;
hdr.SizeOfStackCommit = 0x00001000;
hdr.SizeOfHeapReserve = 0x00100000;
hdr.SizeOfHeapCommit = 0x00001000;
hdr.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
hdr.PE_DIR_ExportTable.VirtualAddress = PE_export_rva;
hdr.PE_DIR_ExportTable.Size = PE_export_size;
hdr.PE_DIR_ImportTable.VirtualAddress = PE_import_rva;
hdr.PE_DIR_ImportTable.Size = PE_import_size;
hdr.PE_DIR_Resource.VirtualAddress = PE_resource_rva;
hdr.PE_DIR_Resource.Size = PE_resource_size;
fwrite(&hdr, sizeof(hdr), 1, fd);
}
void PE_section_fwrite(FILE *fd) {
IMAGE_SECTION_HEADER hdr;
memset(&hdr, 0, sizeof(hdr));
strncpy(hdr.Name, PE_section_name, sizeof(hdr.Name));
hdr.Misc.VirtualSize = PE_virtual_size;
hdr.VirtualAddress = PE_rva - PE_image_base;
hdr.SizeOfRawData = PE_raw_size;
hdr.PointerToRawData = PE_file_offset;
hdr.Characteristics = PE_Characteristics;
fwrite(&hdr, sizeof(hdr), 1, fd);
}
thanks in advance,
vs49688