Results 1 to 18 of 18

Thread: Microsoft EXEPACK in old executables->

  1. #1
    Member
    Join Date
    Jul 2018
    Location
    Netherlands
    Posts
    37
    Thanks
    22
    Thanked 0 Times in 0 Posts

    Microsoft EXEPACK in old executables->

    Hi,

    I am trying to write an unpacker for Microsoft EXEPACK packed executables in Visual Basic 6.0 using the information at http://www.shikadi.net/moddingwiki/Microsoft_EXEPACK. I translated the C code provided to vb6. I've attached a small project attempting to apply this translated code to a packed executable, but I immediately run into an error: there is no "command byte" where it's expected. The information provided on the Shikadi page is limited and the C algorithm an incomplete program so I had to do some guesswork.

    Could someone here who has experience with packed executables help me out?

    Note:
    The code also contains the executable of an old DOS game I am testing the code on. The Shikadi page mentions it as being packed - which I confirmed btw. Also: I did not attach the entire game.

    Thanks.
    Last edited by Peter Swinkels; 20th April 2019 at 14:07. Reason: Fixed a typo.

  2. #2
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    3,134
    Thanks
    179
    Thanked 921 Times in 469 Posts
    paq8pxd has a handler for this: https://github.com/kaitz/paq8pxd/blo...pxd.cpp#L13054
    Code:
    344,923 ikernel.ex_
    304,802 ikernel.ex_.paq8p
    301,652 ikernel.ex_.paq8px178
    120,429 ikernel.ex_.paq8pxd64
    855,552 paq8pxd_v64.exe
    757,760 paq8px_v178.exe
    129,024 paq8p_sse2.exe

  3. The Following User Says Thank You to Shelwien For This Useful Post:

    Peter Swinkels (7th April 2019)

  4. #3
    Member
    Join Date
    Jul 2018
    Location
    Netherlands
    Posts
    37
    Thanks
    22
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Shelwien View Post
    paq8pxd has a handler for this: https://github.com/kaitz/paq8pxd/blo...pxd.cpp#L13054
    Code:
    344,923 ikernel.ex_
    304,802 ikernel.ex_.paq8p
    301,652 ikernel.ex_.paq8px178
    120,429 ikernel.ex_.paq8pxd64
    855,552 paq8pxd_v64.exe
    757,760 paq8px_v178.exe
    129,024 paq8p_sse2.exe
    Hi, thanks for the quick reply. I checked the link you posted and see a lot of code, could you be more specific as to what I should look for? Also, what does that code block with those filenames in your post mean?

  5. #4
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    3,134
    Thanks
    179
    Thanked 921 Times in 469 Posts
    > what I should look for?

    I gave you a link to source line which checks for exepack signature.
    It then creates an instances of LZSS class, which is used to decompress the data: https://github.com/kaitz/paq8pxd/blo...pxd.cpp#L12216
    Its supposedly made based on this: http://my.execpc.com/~geezer/code/lzss.c

    > Also, what does that code block with those filenames in your post mean?

    Its a proof that paq8pxd really can recompress exepack files.

  6. The Following User Says Thank You to Shelwien For This Useful Post:

    Peter Swinkels (7th April 2019)

  7. #5
    Member
    Join Date
    Jul 2018
    Location
    Netherlands
    Posts
    37
    Thanks
    22
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Shelwien View Post
    > what I should look for?

    I gave you a link to source line which checks for exepack signature.
    It then creates an instances of LZSS class, which is used to decompress the data: https://github.com/kaitz/paq8pxd/blo...pxd.cpp#L12216
    Its supposedly made based on this: http://my.execpc.com/~geezer/code/lzss.c

    > Also, what does that code block with those filenames in your post mean?

    Its a proof that paq8pxd really can recompress exepack files.
    Hi Shelwien, I appreciate you taking the time reply, but I don't think your links have much to do with what I am looking for, there's no reference to "EXEPACK" anywhere. Perhaps I didn't explain it properly: I am not looking for a way to decompress to LZSS compressed executables. The algorithm I was talking about is a simpler (older?) run-length algorithm. Unlike with LZSS compressed executables text strings in the file are still legible, it seems that only stretches of identical bytes are shortened.

    EDIT:
    I attached a program that already does what I am looking for, but it only runs under MS-DOS, 32-bit Windows or an emulator such as DOSBox.
    Last edited by Peter Swinkels; 20th April 2019 at 14:08. Reason: Added an attachment.

  8. #6
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    3,134
    Thanks
    179
    Thanked 921 Times in 469 Posts
    ok, sorry, I somehow remembered it wrong.
    What about this then? https://github.com/w4kfu/unEXEPACK
    shikadi is certainly not the only source here.

  9. The Following User Says Thank You to Shelwien For This Useful Post:

    Peter Swinkels (8th April 2019)

  10. #7
    Member
    Join Date
    Jul 2018
    Location
    Netherlands
    Posts
    37
    Thanks
    22
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Shelwien View Post
    ok, sorry, I somehow remembered it wrong.
    What about this then? https://github.com/w4kfu/unEXEPACK
    shikadi is certainly not the only source here.
    Hi Shelwien, yes that appears to be it. Thank you! And, I should have mentioned that I looked at several other sites but couldn't find anything that looked useful (to me.) I will have to see if I can get Microsoft Visual Studio's C++ compiler to run this code to be sure. Of course there are other compilers...

  11. #8
    Member
    Join Date
    Jul 2018
    Location
    Netherlands
    Posts
    37
    Thanks
    22
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Shelwien View Post
    ok, sorry, I somehow remembered it wrong.
    What about this then? https://github.com/w4kfu/unEXEPACK
    shikadi is certainly not the only source here.
    Just wanted to say, I successfully compiled the source with GCC ... and it works! Thanks again.

    EDIT:
    Intending to convert it to vb.net, I stripped the unpacker's C code to basically its bare minimum:
    Code:
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    
    #ifndef O_BINARY
        #define O_BINARY 0
    #endif
    
    
    #define DOS_SIGNATURE 23117
    #define EXEPACK_SIGNATURE 16978
    
    
    struct memstream {
        unsigned char *buf;
        unsigned int length;
        unsigned int pos;
    };
    
    
    struct dos_header {
        unsigned short e_magic;
        unsigned short e_cblp;
        unsigned short e_cp;
        unsigned short e_crlc;
        unsigned short e_cparhdr;
        unsigned short e_minalloc;
        unsigned short e_maxalloc;
        unsigned short e_ss;
        unsigned short e_sp;
        unsigned short e_csum;
        unsigned short e_ip;
        unsigned short e_cs;
        unsigned short e_lfarlc;
        unsigned short e_ovno;
    };
    
    
    struct exepack_header {
        unsigned short real_ip;
        unsigned short real_cs;
        unsigned short mem_start;
        unsigned short exepack_size;
        unsigned short real_sp;
        unsigned short real_ss;
        unsigned short dest_len;
        unsigned short skip_len;
        unsigned short signature;
    };
    
    
    void reverse(unsigned char *s, size_t length);
    void unpack_data(unsigned char *unpacked_data, unsigned char *buf, unsigned int *unpacked_data_size, unsigned int packed_data_len);
    void unpack(struct memstream *ms);
    unsigned char *create_reloc_table(struct memstream *ms, struct dos_header *dh, struct exepack_header *eh, unsigned int *reloc_table_size);
    void writeexe(struct dos_header *dh, unsigned char *unpacked_data, unsigned int unpacked_data_size, unsigned char *reloc, size_t reloc_size, size_t padding);
    void craftexec(struct dos_header *dh, struct exepack_header *eh, unsigned char *unpacked_data, unsigned int unpacked_data_size, unsigned char *reloc, unsigned int reloc_size);
    
    
    // utils
    void msopen(const char *filename, struct memstream *ms);
    unsigned int msread(struct memstream *ms, void *buf, unsigned int count);
    int mscanread(struct memstream *ms, unsigned int count);
    unsigned int msgetavailable(struct memstream *ms);
    void msseek(struct memstream *ms, unsigned int offset);
    void msclose(struct memstream *ms);
    void *memmem(const void *l, size_t l_len, const void *s, size_t s_len);
    
    
    char *output_file = "D:\\Other\\Unpacked.exe";
    
    
    int main(int argc, char *argv[])
    {
        struct memstream ms;
    
    
        msopen(argv[1], &ms);
        unpack(&ms);
        msclose(&ms);
        return 0;
    }
    
    
    void reverse(unsigned char *s, size_t length)
    {
        size_t i = 0;
        size_t j = length - 1;
        unsigned char c;
    
    
        if (length == 0) return;
    
    
        for (i; i < j; i++) {
            c = s[i];
            s[i] = s[j];
            s[j] = c;
            j = j - 1;
        }
    }
    
    /* buf is already reversed, because EXEPACK use backward processing */
    void unpack_data(unsigned char *unpacked_data, unsigned char *buf, unsigned int *unpacked_data_size, unsigned int packed_data_len)
    {
        unsigned char opcode;
        unsigned short count;
        unsigned char fillbyte;
        unsigned char *save_buf = NULL;
        unsigned char *save_unp = NULL;
        unsigned int cur_unpacked_data_size = 0;
    
    
        save_buf = buf;
        save_unp = unpacked_data;
        while (*buf == 255) {
            buf = buf + 1;
        }
        while (1) {
            opcode = *buf;
            buf = buf + 1;
            count = *(buf) * 256 + *(buf + 1);
            buf += 2;
            if ((opcode & 254) == 176) {
                fillbyte = *buf;
                buf = buf + 1;
                if ((cur_unpacked_data_size + count) > *unpacked_data_size) printf("overflow\n");
                memset(unpacked_data, fillbyte, count);
                unpacked_data += count;
                cur_unpacked_data_size += count;
            }
            else if ((opcode & 254) == 178) {
                if ((cur_unpacked_data_size + count) > *unpacked_data_size) printf("overflow\n");
                memcpy(unpacked_data, buf, count);
                unpacked_data += count;
                cur_unpacked_data_size += count;
                buf += count;
            }
            else {
                printf("unknown opcode\n");
            }
    
    
            if ((opcode & 1) == 1) break;
            if (buf - save_buf >= packed_data_len) break;
        }
        if (buf - save_buf < packed_data_len) {
            if ((packed_data_len - (buf - save_buf)) > (*unpacked_data_size - (unpacked_data - save_unp))) printf("Data left are too large!\n");
            memcpy(unpacked_data, buf, packed_data_len - (buf - save_buf));
            cur_unpacked_data_size += packed_data_len - (buf - save_buf);
        }
        *unpacked_data_size = cur_unpacked_data_size;
    }
    
    
    unsigned char *create_reloc_table(struct memstream *ms, struct dos_header *dh, struct exepack_header *eh, unsigned int *reloc_table_size)
    {
        unsigned int exepack_offset = 0;
        unsigned int reloc_length;
        int nb_reloc;
        unsigned char *buf_reloc = NULL;
        unsigned char *reloc = NULL;
        int i;
        int j;
        unsigned short count = 0;
        unsigned short entry;
        unsigned int reloc_position = 0;
    
    
        exepack_offset = (dh->e_cparhdr + dh->e_cs) * 16;
        msseek(ms, exepack_offset);
        reloc = memmem(ms->buf + exepack_offset, msgetavailable(ms), "Packed file is corrupt", strlen("Packed file is corrupt"));
        if (!reloc) printf("Cannot find string \"Packed file is corrupt\", is it really EXEPACK ?\n");
    
    
        reloc_length = (unsigned int)(eh->exepack_size - ((reloc - (ms->buf + exepack_offset)) & 0xFFFFFFFF) + strlen("Packed file is corrupt"));
        nb_reloc = (reloc_length - 16 * sizeof (unsigned short)) / 2;
        *reloc_table_size = nb_reloc * 2 * sizeof(unsigned short);
        buf_reloc = malloc(sizeof (char) * *reloc_table_size);
        if (buf_reloc == NULL) printf("malloc\n");
        reloc += strlen("Packed file is corrupt");
        msseek(ms, (reloc - ms->buf) & 0xFFFFFFFF);
        for (i = 0; i < 16; i++) {
            if (msread(ms, &count, sizeof (unsigned short)) != sizeof (unsigned short)) printf("msread failed\n");
    
    
            for (j = 0; j < count; j++) {
                if (msread(ms, &entry, sizeof (unsigned short)) != sizeof (unsigned short)) printf("msread failed\n");
                if (reloc_position >= *reloc_table_size) printf("overflow\n");
    
    
                *(unsigned short*)(buf_reloc + reloc_position) = entry;
                reloc_position += 2;
                if (reloc_position >= *reloc_table_size) printf("overflow\n");
                *(unsigned short*)(buf_reloc + reloc_position) = (i * 4096) & 65535;
                reloc_position += 2;
            }
        }
        *reloc_table_size = reloc_position;
        return buf_reloc;
    }
    
    
    void writeexe(struct dos_header *dh, unsigned char *unpacked_data, unsigned int unpacked_data_size, unsigned char *reloc, size_t reloc_size, size_t padding)
    {
        int fd;
        int i;
    
    
        fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
        if (fd == -1) printf("open\n");
    
    
        write(fd, dh, sizeof (struct dos_header));
        write(fd, reloc, reloc_size);
        for (i = 0; i < padding; i++) {
            write(fd, "\x00", 1);
        }
        write(fd, unpacked_data, unpacked_data_size);
        close(fd);
    }
    
    
    void craftexec(struct dos_header *dh, struct exepack_header *eh, unsigned char *unpacked_data, unsigned int unpacked_data_size, unsigned char *reloc, unsigned int reloc_size)
    {
        struct dos_header dhead;
        int header_size;
        int total_length;
        int padding_length;
    
    
        memset(&dhead, 0, sizeof (struct dos_header));
        header_size = sizeof (struct dos_header) + reloc_size;
        dhead.e_magic = DOS_SIGNATURE;
        dhead.e_cparhdr = (header_size / 16) & 65535;
        dhead.e_cparhdr = (dhead.e_cparhdr / 32 + 1) * 32;
        padding_length = dhead.e_cparhdr * 16 - header_size;
        total_length = header_size + padding_length + unpacked_data_size;
        dhead.e_ss = eh->real_ss;
        dhead.e_sp = eh->real_sp;
        dhead.e_ip = eh->real_ip;
        dhead.e_cs = eh->real_cs;
        dhead.e_minalloc = dh->e_minalloc;
        dhead.e_maxalloc = 65535;
        dhead.e_lfarlc = sizeof (struct dos_header);
        dhead.e_crlc = (reloc_size / (2 * sizeof (unsigned short))) & 65535;
        dhead.e_cblp = total_length % 512;
        dhead.e_cp = (total_length / 512 + 1) & 65535;
        writeexe(&dhead, unpacked_data, unpacked_data_size, reloc, reloc_size, padding_length);
    }
    
    
    void unpack(struct memstream *ms)
    {
        struct dos_header dh;
        struct exepack_header eh;
        unsigned int exepack_offset = 0;
        unsigned char *unpacked_data = NULL;
        unsigned int unpacked_data_size = 0;
        unsigned int packed_data_start;
        unsigned int packed_data_end;
        unsigned int packed_data_len;
        unsigned int reloc_size;
        unsigned char *reloc = NULL;
    
    
        if (msread(ms, &dh, sizeof (struct dos_header)) != sizeof (struct dos_header)) return;
    
    
        exepack_offset = (dh.e_cparhdr + dh.e_cs) * 16;
        msseek(ms, exepack_offset);
        if (msread(ms, &eh, sizeof (struct exepack_header)) != sizeof (struct exepack_header)) return;
    
    
        if ((eh.signature != EXEPACK_SIGNATURE && eh.skip_len != EXEPACK_SIGNATURE) || eh.exepack_size == 0) {
            printf("This is not a valid EXEPACK executable\n");
            return;
        }
        printf("Header exepack = %X\n", exepack_offset);
        unpacked_data_size = eh.dest_len * 16;
        unpacked_data = malloc(sizeof (char) * unpacked_data_size);
        if (unpacked_data == NULL) printf("malloc\n");
    
    
        memset(unpacked_data, 0, sizeof (char) * unpacked_data_size);
        packed_data_start = dh.e_cparhdr * 16;
        packed_data_end = exepack_offset;
        packed_data_len = packed_data_end - packed_data_start;
        msseek(ms, packed_data_start);
        if (mscanread(ms, packed_data_len) == 0) {
            free(unpacked_data);
            return;
        }
        reverse(ms->buf + packed_data_start, packed_data_len);
        unpack_data(unpacked_data, ms->buf + packed_data_start, &unpacked_data_size, packed_data_len);
        reverse(unpacked_data, unpacked_data_size);
        reloc = create_reloc_table(ms, &dh, &eh, &reloc_size);
        craftexec(&dh, &eh, unpacked_data, unpacked_data_size, reloc, reloc_size);
        free(unpacked_data);
    }
    
    
    void *memmem(const void *l, size_t l_len, const void *s, size_t s_len)
    {
        register char *cur;
        register char *last;
        const char *cl = (const char *)l;
        const char *cs = (const char *)s;
    
    
        if (l_len == 0 || s_len == 0) return NULL;
        if (l_len < s_len)  return NULL;    
        if (s_len == 1) return (void*)memchr(l, (int)*cs, l_len);
    
    
        last = (char *)cl + l_len - s_len;
        for (cur = (char *)cl; cur <= last; cur++) {
            if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) return cur;
        }
        return NULL;
    }
    
    
    void msopen(const char *filename, struct memstream *ms)
    {
        int fd;
        struct stat st;
    
    
        if (ms == NULL) exit(EXIT_FAILURE);
    
    
        fd = open(filename, O_RDONLY | O_BINARY);
        if (fd == -1) printf("open\n");
    
    
        if (fstat(fd, &st) == -1) {
            close(fd);
            printf("fstat\n");
        }
        ms->buf = (unsigned char*)malloc(sizeof (char) * st.st_size);
        if (ms->buf == NULL) {
            close(fd);
            printf("malloc()\n");
        }
        if (read(fd, ms->buf, st.st_size) != st.st_size) {
            close(fd);
            free(ms->buf);
            printf("read()\n");
        }
        ms->pos = 0;
        ms->length = st.st_size;
        close(fd);
    }
    
    
    unsigned int msread(struct memstream *ms, void *buf, unsigned int count)
    {
        unsigned int length;
    
    
        if (buf == NULL) return 0;
    
    
        if (ms->pos > ms->length) printf("invalid read\n");
        
        if (count < (ms->length - ms->pos)) length = count; else length = ms->length - ms->pos;
        
        if (length > 0) memcpy(buf, ms->buf + ms->pos, length);
    
    
        ms->pos += length;
        return length;
    }
    
    
    int mscanread(struct memstream *ms, unsigned int count)
    {
        if (ms->pos > ms->length) return 0;
        if (count > (ms->length - ms->pos)) return 0;
        
        return 1;
    }
    
    
    unsigned int msgetavailable(struct memstream *ms)
    {
        if (ms->pos > ms->length) return 0;
    
    
        return ms->length - ms->pos;
    }
    
    
    void msseek(struct memstream *ms, unsigned int offset)
    {
        if (offset > ms->length) printf("invalid seek : 0x%X\n", offset);
        
        ms->pos = offset;
    }
    
    
    void msclose(struct memstream *ms)
    {
        if (ms != NULL) {
            if (ms->buf != NULL) {
                free(ms->buf);
                ms->buf = NULL;
            }
        }
    }
    Note: the code is also somewhat more BASIC like now, and most safety checks will need to be reimplemented if serious use is intended.
    Last edited by Peter Swinkels; 13th April 2019 at 13:49. Reason: Posted code for those interested.

  12. #9
    Member
    Join Date
    Jul 2018
    Location
    Netherlands
    Posts
    37
    Thanks
    22
    Thanked 0 Times in 0 Posts
    Turns out more could be stripped out:

    Code:
    #include <ctype.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    
    
    #ifndef O_BINARY
        #define O_BINARY 0
    #endif
    
    
    #define DOS_SIGNATURE 23117
    #define EXEPACK_SIGNATURE 16978
    
    
    struct dos_header {
        unsigned short e_magic;
        unsigned short e_cblp;
        unsigned short e_cp;
        unsigned short e_crlc;
        unsigned short e_cparhdr;
        unsigned short e_minalloc;
        unsigned short e_maxalloc;
        unsigned short e_ss;
        unsigned short e_sp;
        unsigned short e_csum;
        unsigned short e_ip;
        unsigned short e_cs;
        unsigned short e_lfarlc;
        unsigned short e_ovno;
    };
    
    
    struct exepack_header {
        unsigned short real_ip;
        unsigned short real_cs;
        unsigned short mem_start;
        unsigned short exepack_size;
        unsigned short real_sp;
        unsigned short real_ss;
        unsigned short dest_len;
        unsigned short skip_len;
        unsigned short signature;
    };
    
    
    struct memstream {
        unsigned char *buf;
        unsigned int length;
        unsigned int pos;
    };
    
    
    void reverse(unsigned char *s, size_t length);
    void unpack_data(unsigned char *unpacked_data, unsigned char *buf, unsigned int *unpacked_data_size, unsigned int packed_data_len);
    void unpack(struct memstream *ms);
    unsigned char *create_reloc_table(struct memstream *ms, struct dos_header *dh, struct exepack_header *eh, unsigned int *reloc_table_size);
    void writeexe(struct dos_header *dh, unsigned char *unpacked_data, unsigned int unpacked_data_size, unsigned char *reloc, size_t reloc_size, size_t padding);
    void craftexec(struct dos_header *dh, struct exepack_header *eh, unsigned char *unpacked_data, unsigned int unpacked_data_size, unsigned char *reloc, unsigned int reloc_size);
    
    
    void msopen(const char *filename, struct memstream *ms);
    unsigned int msread(struct memstream *ms, void *buf, unsigned int count);
    int mscanread(struct memstream *ms, unsigned int count);
    unsigned int msgetavailable(struct memstream *ms);
    void msseek(struct memstream *ms, unsigned int offset);
    void msclose(struct memstream *ms);
    void *memmem(const void *l, size_t l_len, const void *s, size_t s_len);
    
    
    char *input_file = "D:\\Other\\Other\\Cartoons.exe";
    char *output_file = "D:\\Other\\Other\\CartUnpk.exe";
    
    
    int main(int argc, char *argv[])
    {
        struct memstream ms;
    
    
        msopen(input_file, &ms);
        unpack(&ms);
        msclose(&ms);
        return 0;
    }
    
    
    void craftexec(struct dos_header *dh, struct exepack_header *eh, unsigned char *unpacked_data, unsigned int unpacked_data_size, unsigned char *reloc, unsigned int reloc_size)
    {
        struct dos_header dhead;
        int header_size;
        int total_length;
        int padding_length;
    
    
        memset(&dhead, 0, sizeof (struct dos_header));
        header_size = sizeof (struct dos_header) + reloc_size;
        dhead.e_magic = DOS_SIGNATURE;
        dhead.e_cparhdr = (header_size / 16) & 65535;
        dhead.e_cparhdr = (dhead.e_cparhdr / 32 + 1) * 32;
        padding_length = dhead.e_cparhdr * 16 - header_size;
        total_length = header_size + padding_length + unpacked_data_size;
        dhead.e_ss = eh->real_ss;
        dhead.e_sp = eh->real_sp;
        dhead.e_ip = eh->real_ip;
        dhead.e_cs = eh->real_cs;
        dhead.e_minalloc = dh->e_minalloc;
        dhead.e_maxalloc = 65535;
        dhead.e_lfarlc = sizeof (struct dos_header);
        dhead.e_crlc = (reloc_size / (2 * sizeof (unsigned short))) & 65535;
        dhead.e_cblp = total_length % 512;
        dhead.e_cp = (total_length / 512 + 1) & 65535;
        writeexe(&dhead, unpacked_data, unpacked_data_size, reloc, reloc_size, padding_length);
    }
    
    
    unsigned char *create_reloc_table(struct memstream *ms, struct dos_header *dh, struct exepack_header *eh, unsigned int *reloc_table_size)
    {
        unsigned int exepack_offset = 0;
        unsigned int reloc_length;
        int nb_reloc;
        unsigned char *buf_reloc = NULL;
        unsigned char *reloc = NULL;
        int i;
        int j;
        unsigned short count = 0;
        unsigned short entry;
        unsigned int reloc_position = 0;
    
    
        exepack_offset = (dh->e_cparhdr + dh->e_cs) * 16;
        msseek(ms, exepack_offset);
        reloc = memmem(ms->buf + exepack_offset, msgetavailable(ms), "Packed file is corrupt", strlen("Packed file is corrupt"));
    
    
        reloc_length = (unsigned int)(eh->exepack_size - ((reloc - (ms->buf + exepack_offset)) & 0xFFFFFFFF) + strlen("Packed file is corrupt"));
        nb_reloc = (reloc_length - 16 * sizeof (unsigned short)) / 2;
        *reloc_table_size = nb_reloc * 2 * sizeof(unsigned short);
        buf_reloc = malloc(sizeof (char) * *reloc_table_size);
        reloc += strlen("Packed file is corrupt");
        msseek(ms, (reloc - ms->buf) & 0xFFFFFFFF);
        for (i = 0; i < 16; i++) {
            msread(ms, &count, sizeof (unsigned short));
    
    
            for (j = 0; j < count; j++) {
                msread(ms, &entry, sizeof (unsigned short));
    
    
                *(unsigned short*)(buf_reloc + reloc_position) = entry;
                reloc_position += 2;
                *(unsigned short*)(buf_reloc + reloc_position) = (i * 4096) & 65535;
                reloc_position += 2;
            }
        }
        *reloc_table_size = reloc_position;
        return buf_reloc;
    }
    
    
    void *memmem(const void *l, size_t l_len, const void *s, size_t s_len)
    {
        char *cur;
        char *last;
        char *cl = (char *)l;
        char *cs = (char *)s;
    
    
        if (s_len == 1) return (void*)memchr(l, (int)*cs, l_len);
    
    
        last = (char *)cl + l_len - s_len;
        for (cur = (char *)cl; cur <= last; cur++) {
            if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) return cur;
        }
        return NULL;
    }
    
    
    int mscanread(struct memstream *ms, unsigned int count)
    {
        if (ms->pos > ms->length) return 0;
        if (count > (ms->length - ms->pos)) return 0;
        
        return 1;
    }
    
    
    void msclose(struct memstream *ms)
    {
        if (ms != NULL) {
            if (ms->buf != NULL) {
                free(ms->buf);
                ms->buf = NULL;
            }
        }
    }
    
    
    unsigned int msgetavailable(struct memstream *ms)
    {
        if (ms->pos > ms->length) return 0;
    
    
        return ms->length - ms->pos;
    }
    
    
    void msopen(const char *filename, struct memstream *ms)
    {
        int fd;
        struct stat st;
    
    
        fd = open(filename, O_RDONLY | O_BINARY);
    
    
        if (fstat(fd, &st) == -1) close(fd);
    
    
        ms->buf = (unsigned char*)malloc(sizeof (char) * st.st_size);
        if (ms->buf == NULL) close(fd);
    
    
        if (read(fd, ms->buf, st.st_size) != st.st_size) {
            close(fd);
            free(ms->buf);
        }
        ms->pos = 0;
        ms->length = st.st_size;
        close(fd);
    }
    
    
    unsigned int msread(struct memstream *ms, void *buf, unsigned int count)
    {
        unsigned int length;
    
    
        if (count < (ms->length - ms->pos)) length = count; else length = ms->length - ms->pos;
        
        if (length > 0) memcpy(buf, ms->buf + ms->pos, length);
    
    
        ms->pos += length;
    
    
        return length;
    }
    
    
    void msseek(struct memstream *ms, unsigned int offset)
    {
        if (offset > ms->length) printf("invalid seek : 0x%X\n", offset);
        
        ms->pos = offset;
    }
    
    
    void unpack(struct memstream *ms)
    {
        struct dos_header dh;
        struct exepack_header eh;
        unsigned int exepack_offset = 0;
        unsigned char *unpacked_data = NULL;
        unsigned int unpacked_data_size = 0;
        unsigned int packed_data_start;
        unsigned int packed_data_end;
        unsigned int packed_data_len;
        unsigned int reloc_size;
        unsigned char *reloc = NULL;
    
    
        if (msread(ms, &dh, sizeof (struct dos_header)) != sizeof (struct dos_header)) return;
    
    
        exepack_offset = (dh.e_cparhdr + dh.e_cs) * 16;
        msseek(ms, exepack_offset);
        if (msread(ms, &eh, sizeof (struct exepack_header)) != sizeof (struct exepack_header)) return;
    
    
        unpacked_data_size = eh.dest_len * 16;
        unpacked_data = malloc(sizeof (char) * unpacked_data_size);
    
    
        memset(unpacked_data, 0, sizeof (char) * unpacked_data_size);
        packed_data_start = dh.e_cparhdr * 16;
        packed_data_end = exepack_offset;
        packed_data_len = packed_data_end - packed_data_start;
        msseek(ms, packed_data_start);
    
    
        reverse(ms->buf + packed_data_start, packed_data_len);
        unpack_data(unpacked_data, ms->buf + packed_data_start, &unpacked_data_size, packed_data_len);
        reverse(unpacked_data, unpacked_data_size);
        reloc = create_reloc_table(ms, &dh, &eh, &reloc_size);
        craftexec(&dh, &eh, unpacked_data, unpacked_data_size, reloc, reloc_size);
        free(unpacked_data);
    }
    
    
    void unpack_data(unsigned char *unpacked_data, unsigned char *buf, unsigned int *unpacked_data_size, unsigned int packed_data_len)
    {
        unsigned char opcode;
        unsigned short count;
        unsigned char fillbyte;
        unsigned char *save_buf = NULL;
        unsigned char *save_unp = NULL;
        unsigned int cur_unpacked_data_size = 0;
    
    
        save_buf = buf;
        save_unp = unpacked_data;
        while (*buf == 255) {
            buf = buf + 1;
        }
        while (1) {
            opcode = *buf;
            buf = buf + 1;
            count = *(buf) * 256 + *(buf + 1);
            buf += 2;
            if ((opcode & 254) == 176) {
                fillbyte = *buf;
                buf = buf + 1;
                memset(unpacked_data, fillbyte, count);
                unpacked_data += count;
                cur_unpacked_data_size += count;
            }
            else if ((opcode & 254) == 178) {
                memcpy(unpacked_data, buf, count);
                unpacked_data += count;
                cur_unpacked_data_size += count;
                buf += count;
            }
            else {
                printf("unknown opcode\n");
            }
    
    
            if ((opcode & 1) == 1) break;
            if (buf - save_buf >= packed_data_len) break;
        }
        if (buf - save_buf < packed_data_len) {
            memcpy(unpacked_data, buf, packed_data_len - (buf - save_buf));
            cur_unpacked_data_size += packed_data_len - (buf - save_buf);
        }
        *unpacked_data_size = cur_unpacked_data_size;
    }
    
    
    void reverse(unsigned char *s, size_t length)
    {
        size_t i = 0;
        size_t j = length - 1;
        unsigned char c;
    
    
        if (length == 0) return;
    
    
        for (i; i < j; i++) {
            c = s[i];
            s[i] = s[j];
            s[j] = c;
            j = j - 1;
        }
    }
    
    
    void writeexe(struct dos_header *dh, unsigned char *unpacked_data, unsigned int unpacked_data_size, unsigned char *reloc, size_t reloc_size, size_t padding)
    {
        int fd;
        int i;
    
    
    
    
        fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
    
    
        write(fd, dh, sizeof (struct dos_header));
        write(fd, reloc, reloc_size);
        for (i = 0; i < padding; i++) {
            write(fd, "\x00", 1);
        }
        write(fd, unpacked_data, unpacked_data_size);
        close(fd);
    }
    This code should work, be warned however: pretty much all error checks, debug output and helpful messages are gone!

  13. #10
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    3,134
    Thanks
    179
    Thanked 921 Times in 469 Posts
    Here I fixed it to take cmdline arguments and added a test exe, seems to work?
    http://nishi.dreamhosters.com/u/exeunpack_v0.rar

  14. The Following User Says Thank You to Shelwien For This Useful Post:

    Peter Swinkels (19th April 2019)

  15. #11
    Member
    Join Date
    Jul 2018
    Location
    Netherlands
    Posts
    37
    Thanks
    22
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Shelwien View Post
    Here I fixed it to take cmdline arguments and added a test exe, seems to work?
    http://nishi.dreamhosters.com/u/exeunpack_v0.rar
    Hello again, thanks for taking the time to try and help me out with this project. I will take a look at your modified code in a minute. While preparing the code to be converted to vb.net I found a sitiuation where it seems C's way of handling character strings and pointers has become an obstacle. As far as I understand what's going on C uses pointers referring to a character's memory location in a character array (string). Making do with character arrays for the time being is fine by me, I believe these pointers will have to be replaced by variables containing referring to an index inside an array. Here's an example I cobbled together:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    void FillBuffer_Method_1();
    void FillBuffer_Method_2(char *BufferP);
    
    
    unsigned char *Buffer = NULL;
    
    
    int main()
    {
        Buffer = (unsigned char*)malloc(100);
    
    
        FillBuffer_Method_1();
        printf(">>> %s\n", Buffer);
    
    
        free(Buffer);
    
    
        return 0;
    }
    
    
    void FillBuffer_Method_1()
    {
        for (int i = 0; i < 95; i++)
        {
            Buffer[i] = (char)(i + 32);
        };
    }
    
    
    void FillBuffer_Method_2(char *BufferP)
    {
        for (int i = 0; i < 95; i++)
        {
            *BufferP = (char)(i + 32);
            BufferP++;
        };
    }
    The method being used by the Fill_Method_2 procedure appears to be used inside the unpacker. Fill_Method_1's method is probably best suited for migration to vb.net.

    Okay, and now I will download your code and have a look.

    And just to be sure, here's the latest unpacker code.

    Code:
    #include <ctype.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    
    
    #ifndef O_BINARY
        #define O_BINARY 0
    #endif
    
    
    #define DOS_SIGNATURE 23117
    #define EXEPACK_SIGNATURE 16978
    
    
    struct dos_header {
        unsigned short e_magic;
        unsigned short e_cblp;
        unsigned short e_cp;
        unsigned short e_crlc;
        unsigned short e_cparhdr;
        unsigned short e_minalloc;
        unsigned short e_maxalloc;
        unsigned short e_ss;
        unsigned short e_sp;
        unsigned short e_csum;
        unsigned short e_ip;
        unsigned short e_cs;
        unsigned short e_lfarlc;
        unsigned short e_ovno;
    };
    
    
    struct exepack_header {
        unsigned short real_ip;
        unsigned short real_cs;
        unsigned short mem_start;
        unsigned short exepack_size;
        unsigned short real_sp;
        unsigned short real_ss;
        unsigned short dest_len;
        unsigned short skip_len;
        unsigned short signature;
    };
    
    
    struct memstream {
        unsigned char *buf;
        unsigned int length;
        unsigned int pos;
    };
    
    
    void reverse(char *s, size_t length);
    void unpack_data(unsigned char *unpacked_data, unsigned char *buf, unsigned int *unpacked_data_size, unsigned int packed_data_len);
    void unpack(struct memstream *ms);
    unsigned char *create_reloc_table(struct memstream *ms, struct dos_header *dh, struct exepack_header *eh, unsigned int *reloc_table_size);
    void writeexe(struct dos_header *dh, unsigned char *unpacked_data, unsigned int unpacked_data_size, unsigned char *reloc, size_t reloc_size, size_t padding);
    void craftexec(struct dos_header *dh, struct exepack_header *eh, unsigned char *unpacked_data, unsigned int unpacked_data_size, unsigned char *reloc, unsigned int reloc_size);
    
    
    void msopen(const char *filename, struct memstream *ms);
    unsigned int msread(struct memstream *ms, void *buf, unsigned int count);
    unsigned int msgetavailable(struct memstream *ms);
    void *memmem(char *l, size_t l_len, char *s, size_t s_len);
    
    
    char *input_file = "D:\\Other\\Other\\Cartoons.exe";
    char *output_file = "D:\\Other\\Other\\CartUnpk.exe";
    char *packed_file_error = "Packed file is corrupt";
    
    
    int main(int argc, char *argv[])
    {
        struct memstream ms;
    
    
        msopen(input_file, &ms);
        unpack(&ms);
    
    
        free((&ms)->buf);
        (&ms)->buf = NULL;
    
    
        return 0;
    }
    
    
    void craftexec(struct dos_header *dh, struct exepack_header *eh, unsigned char *unpacked_data, unsigned int unpacked_data_size, unsigned char *reloc, unsigned int reloc_size)
    {
        struct dos_header dhead;
    
    
        memset(&dhead, 0, sizeof (struct dos_header));
    
    
        int header_size = sizeof (struct dos_header) + reloc_size;
        dhead.e_magic = DOS_SIGNATURE;
        dhead.e_cparhdr = (header_size / 16) & 65535;
        dhead.e_cparhdr = (dhead.e_cparhdr / 32 + 1) * 32;
    
    
        int padding_length = dhead.e_cparhdr * 16 - header_size;
        int total_length = header_size + padding_length + unpacked_data_size;
        dhead.e_ss = eh->real_ss;
        dhead.e_sp = eh->real_sp;
        dhead.e_ip = eh->real_ip;
        dhead.e_cs = eh->real_cs;
        dhead.e_minalloc = dh->e_minalloc;
        dhead.e_maxalloc = 65535;
        dhead.e_lfarlc = sizeof (struct dos_header);
        dhead.e_crlc = (reloc_size / 4) & 65535;
        dhead.e_cblp = total_length % 512;
        dhead.e_cp = (total_length / 512 + 1) & 65535;
        writeexe(&dhead, unpacked_data, unpacked_data_size, reloc, reloc_size, padding_length);
    }
    
    
    unsigned char *create_reloc_table(struct memstream *ms, struct dos_header *dh, struct exepack_header *eh, unsigned int *reloc_table_size)
    {
        int nb_reloc;
        unsigned char *buf_reloc = NULL;
        unsigned int exepack_offset = (dh->e_cparhdr + dh->e_cs) * 16;
        unsigned char *reloc = memmem(ms->buf + exepack_offset, msgetavailable(ms), packed_file_error, strlen(packed_file_error));
        unsigned int reloc_length = (unsigned int)(eh->exepack_size - ((reloc - (ms->buf + exepack_offset)) & 0xFFFFFFFF) + strlen(packed_file_error));
        unsigned int reloc_position = 0;
        unsigned short count = 0;
        unsigned short entry;
    
    
        ms->pos = exepack_offset;
    
    
        nb_reloc = (reloc_length - 16 * 4) / 2;
        *reloc_table_size = nb_reloc * 4;
        buf_reloc = malloc(*reloc_table_size);
        reloc += strlen(packed_file_error);
        ms->pos = (reloc - ms->buf) & 0xFFFFFFFF;
        for (int i = 0; i < 16; i++) {
            msread(ms, &count, 2);
    
    
            for (int j = 0; j < count; j++) {
                msread(ms, &entry, 2);
    
    
                *(unsigned short*)(buf_reloc + reloc_position) = entry;
                reloc_position += 2;
                *(unsigned short*)(buf_reloc + reloc_position) = (i * 4096) & 65535;
                reloc_position += 2;
            }
        }
        *reloc_table_size = reloc_position;
    
    
        return buf_reloc;
    }
    
    
    void *memmem(char *cl, size_t l_len, char *cs, size_t s_len)
    {
        char *last;
     
        if (s_len == 1) return (void*)memchr(cl, (int)*cs, l_len);
    
    
        last = cl + l_len - s_len;
        for (char *cur = cl; cur <= last; cur++) {
            if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) return cur;
        }
    
    
        return NULL;
    }
    
    
    unsigned int msgetavailable(struct memstream *ms)
    {
        return ms->length - ms->pos;
    }
    
    
    void msopen(const char *filename, struct memstream *ms)
    {
        int fd = open(filename, O_RDONLY | O_BINARY);
        struct stat st;
    
    
        fstat(fd, &st);
    
    
        ms->buf = (unsigned char*)malloc(st.st_size);
    
    
        if (read(fd, ms->buf, st.st_size) != st.st_size) {
            close(fd);
            free(ms->buf);
        }
        ms->pos = 0;
        ms->length = st.st_size;
        close(fd);
    }
    
    
    unsigned int msread(struct memstream *ms, void *buf, unsigned int count)
    {
        unsigned int length;
    
    
        if (count < (ms->length - ms->pos)) length = count; else length = ms->length - ms->pos;
        
        if (length > 0) memcpy(buf, ms->buf + ms->pos, length);
    
    
        ms->pos += length;
    
    
        return length;
    }
    
    
    void unpack(struct memstream *ms)
    {
        struct dos_header dh;
        struct exepack_header eh;
        unsigned int packed_data_end;
        unsigned int packed_data_len;
        unsigned int packed_data_start;
        unsigned int reloc_size;
        unsigned char *reloc = NULL;
    
    
        msread(ms, &dh, sizeof (struct dos_header));
        unsigned int exepack_offset = exepack_offset = (dh.e_cparhdr + dh.e_cs) * 16;
        ms->pos = exepack_offset;
        msread(ms, &eh, sizeof (struct exepack_header));
    
    
        unsigned int unpacked_data_size = eh.dest_len * 16;
        unsigned char *unpacked_data = malloc(unpacked_data_size);
    
    
        memset(unpacked_data, 0, unpacked_data_size);
        packed_data_start = dh.e_cparhdr * 16;
        packed_data_end = exepack_offset;
        packed_data_len = packed_data_end - packed_data_start;
        ms->pos = packed_data_start;
    
    
        reverse(ms->buf + packed_data_start, packed_data_len);
        unpack_data(unpacked_data, ms->buf + packed_data_start, &unpacked_data_size, packed_data_len);
        reverse(unpacked_data, unpacked_data_size);
        reloc = create_reloc_table(ms, &dh, &eh, &reloc_size);
        craftexec(&dh, &eh, unpacked_data, unpacked_data_size, reloc, reloc_size);
        free(unpacked_data);
    }
    
    
    void unpack_data(unsigned char *unpacked_data, unsigned char *buf, unsigned int *unpacked_data_size, unsigned int packed_data_len)
    {
        unsigned char opcode;
        unsigned char fillbyte;
        unsigned char *save_buf = buf;
        unsigned char *save_unp = unpacked_data;
        unsigned int cur_unpacked_data_size = 0;
        unsigned short count;
    
    
        while (*buf == 255) {
            buf += 1;
        }
    
    
        while (1) {
            opcode = *buf;
            buf += 1;
            count = *(buf) * 256 + *(buf + 1);
            buf += 2;
            if ((opcode & 254) == 176) {
                fillbyte = *buf;
                buf += 1;
                memset(unpacked_data, fillbyte, count);
                unpacked_data += count;
                cur_unpacked_data_size += count;
            }
            else if ((opcode & 254) == 178) {
                memcpy(unpacked_data, buf, count);
                unpacked_data += count;
                cur_unpacked_data_size += count;
                buf += count;
            }
            else {
                printf("unknown opcode\n");
            }
    
    
            if ((opcode & 1) == 1) break;
        }
        if (buf - save_buf < packed_data_len) {
            memcpy(unpacked_data, buf, packed_data_len - (buf - save_buf));
            cur_unpacked_data_size += packed_data_len - (buf - save_buf);
        }
        *unpacked_data_size = cur_unpacked_data_size;
    }
    
    
    void reverse(char *s, size_t length)
    {
        size_t i = 0;
        size_t j = length - 1;
        char c;
    
    
        if (length == 0) return;
    
    
        for (i; i < j; i++) {
            c = s[i];
            s[i] = s[j];
            s[j] = c;
            j = j - 1;
        }
    }
    
    
    void writeexe(struct dos_header *dh, unsigned char *unpacked_data, unsigned int unpacked_data_size, unsigned char *reloc, size_t reloc_size, size_t padding)
    {
        int fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
    
    
        write(fd, dh, sizeof (struct dos_header));
        write(fd, reloc, reloc_size);
        for (int i = 0; i < padding; i++) {
            write(fd, "\x00", 1);
        }
        write(fd, unpacked_data, unpacked_data_size);
        close(fd);
    }

    It's been tested and it produces a stable executable. One of the reasons it's been stripped down isn't just easy conversion. I am intending to work it into a module which will be part of an existing program. I could post it here, but be warned: it's only distantly related to this forum's topic ... and rather large.

    EDIT:
    What ever: https://drive.google.com/open?id=1Vx...5eiol5GbGuBucC

  16. #12
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    3,134
    Thanks
    179
    Thanked 921 Times in 469 Posts
    Dunno if it can help, but here I tried running automated converter with my cpp source:
    (https://www.tangiblesoftwaresolution...r_details.html)
    Attached Files Attached Files

  17. The Following User Says Thank You to Shelwien For This Useful Post:

    Peter Swinkels (19th April 2019)

  18. #13
    Member
    Join Date
    Jul 2018
    Location
    Netherlands
    Posts
    37
    Thanks
    22
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Shelwien View Post
    Dunno if it can help, but here I tried running automated converter with my cpp source:
    (https://www.tangiblesoftwaresolution...r_details.html)
    Dunno, there's a lot of TODO's in there. Looks like it's going to be good old fashioned manually untangling the code... Oh, and I looked at your project, are you using 32-bit Windows or an emulator for the DOS based exes?
    Last edited by Peter Swinkels; 19th April 2019 at 14:13. Reason: Too many typo's.

  19. #14
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    3,134
    Thanks
    179
    Thanked 921 Times in 469 Posts
    > Oh, and I looked at your project, are you using 32-bit Windows or an emulator for the DOS based exes?

    I just compiled a 16-bit exe there, using only 32-bit tools. I didn't try running it.
    Normally I'd use DOSBox to run it, though I have a WinXP VM too.

  20. The Following User Says Thank You to Shelwien For This Useful Post:

    Peter Swinkels (19th April 2019)

  21. #15
    Member
    Join Date
    Jul 2018
    Location
    Netherlands
    Posts
    37
    Thanks
    22
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Shelwien View Post
    > Oh, and I looked at your project, are you using 32-bit Windows or an emulator for the DOS based exes?

    I just compiled a 16-bit exe there, using only 32-bit tools. I didn't try running it.
    Normally I'd use DOSBox to run it, though I have a WinXP VM too.
    Hah, DOSBox is a pretty emulator. The latest version of my project can be downloaded at https://drive.google.com/open?id=1f0...Vttx34zVzqywJj - for anyone who's interested.

  22. #16
    Member
    Join Date
    Jul 2018
    Location
    Netherlands
    Posts
    37
    Thanks
    22
    Thanked 0 Times in 0 Posts
    I have put this project on hold for now and removed a few attachments from this thread, at this moment it's too much time and effort with all other things going on (in my life). Once again: thanks for all the help Shelwein.

    If anyone is interested in this project, ask and I will upload it somewhere.
    Last edited by Peter Swinkels; 20th April 2019 at 14:22. Reason: Clarification

  23. #17
    Member
    Join Date
    Jul 2018
    Location
    Netherlands
    Posts
    37
    Thanks
    22
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Peter Swinkels View Post
    I have put this project on hold for now and removed a few attachments from this thread, at this moment it's too much time and effort with all other things going on (in my life). Once again: thanks for all the help Shelwein.

    If anyone is interested in this project, ask and I will upload it somewhere.
    Turns out I had more time than expected. Attached is a completely stripped down version of the C code Shelwein so kindly provided the url for. And a really ugly conversion to vb.net. But hey, it works! Now it just needs to be cleaned up. Without breaking it.
    Attached Files Attached Files

  24. #18
    Member
    Join Date
    Jul 2018
    Location
    Netherlands
    Posts
    37
    Thanks
    22
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Peter Swinkels View Post
    Turns out I had more time than expected. Attached is a completely stripped down version of the C code Shelwein so kindly provided the url for. And a really ugly conversion to vb.net. But hey, it works! Now it just needs to be cleaned up. Without breaking it.
    Okay, after a rather busy week (not just coding) I finally got round to uploading this to vbforums: http://www.vbforums.com/showthread.p...85#post4646585

    That program contains a completely revised EXEPACK module and a lot of other features.

    This is a personal hobby project and the code focusses more on ease of use than efficiency. Feedback and questions are still welcome, however.
    Last edited by Peter Swinkels; 16th May 2019 at 16:56. Reason: Provided a new url. And updated the description.

Similar Threads

  1. exepack
    By Shelwien in forum Data Compression
    Replies: 4
    Last Post: 13th August 2018, 01:30
  2. Compression of arm executables.
    By osk in forum Data Compression
    Replies: 2
    Last Post: 19th August 2014, 02:10
  3. how toe Pipe RZM > SREP > final file
    By SvenBent in forum The Off-Topic Lounge
    Replies: 5
    Last Post: 7th December 2011, 21:52
  4. .NETZ - .NET EXEcutables Compressor & Packer
    By LovePimple in forum Data Compression
    Replies: 0
    Last Post: 4th July 2009, 11:14
  5. 7zip >> Sfx optimized - 23,7 kb
    By Yuri Grille. in forum Data Compression
    Replies: 22
    Last Post: 12th April 2009, 21:33

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •