Member Avatar for vs49688

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

Recommended Answers

All 3 Replies

Member Avatar for vs49688

is nobody going to help. I really need to do this.

is nobody going to help. I really need to do this.

My best advice is to contact the original author ( Luigi Auriemma) about this. I'm not going to waste hours of work on this, when the OP (you) isn't showing any effort whatsoever.
Besides: this smells a bit to illegal for my taste

Hello,

I've researched the cryptographic algorithm (needed it to fix a bug in hw.dll).

Here goes:

Decryption algorithm:

key = 'W'
for all bytes:
    new_byte = byte^key
    key += new_byte+'W'

Encryption algorithm:

key = 'W'
for all bytes:
    new_byte = byte^key
    key += byte^'W'

For people interested in (fixing) the hw.dll bug; it's the bug where, on systems with more than 2147483647 (2^31-1) bytes of RAM, Half-Life exits with the error message "Available memory less than 15MB!!!".

To fix this bug, I decrypted hw.dll, then patched the opcode at offset 0xB5464:

From:
3D 00 00 F0 00: cmp eax, 0xF00000
A3 B4 14 80 02: mov [0x28014B4], eax
7D 12:          jge 0xB5478          ; Bug. We should ignore the OF (overflow flag).

To:
3D 00 00 F0 00: cmp eax, 0xF00000
A3 B4 14 80 02: mov [0x28014B4], eax
73 12:          jnb 0xB5478          ; Patched. Ignores the OF (overflow flag).

...and then encrypted the DLL again using the aforementioned algorithm.

I've hosted the encryption/decryption source code for the algorithm over here:
http://my-svn.assembla.com/svn/slipstream/valve_crypt/
(I figure source code is just a description of the inner workings, so as long as I distribute only information instead of binaries, there should be no legal issues.)

Jelle Geerts

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.