Author Topic: zip_store from MyDoom  (Read 1054 times)

0 Members and 1 Guest are viewing this topic.

xC

  • Guest
zip_store from MyDoom
« on: April 13, 2013, 01:17:58 pm »
Found this when looking through the code of MyDoom/Bloodred, has also been used in many of the MSN spreading techniques.

Code: [Select]
zip_store( "C:\file.exe", "lawl.exe", "lawl.zip" );
Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#pragma pack(push, 1)
 
struct zip_header_t {
    DWORD signature;       
    WORD ver_needed;
    WORD flags;
    WORD method;
    WORD lastmod_time;
    WORD lastmod_date;
    DWORD crc;
    DWORD compressed_size;
    DWORD uncompressed_size;
    WORD filename_length;
    WORD extra_length;
};
 
struct zip_eod_t {
    DWORD signature;       
    WORD disk_no;
    WORD disk_dirst;
    WORD disk_dir_entries;
    WORD dir_entries;
    DWORD dir_size;
    DWORD dir_offs;
    WORD comment_len;
};
 
struct zip_dir_t {
    DWORD signature;   
    WORD made_by;
    WORD ver_needed;
    WORD flags;
    WORD method;
    WORD lastmod_time;
    WORD lastmod_date;
    DWORD crc;
    DWORD compressed_size;
    DWORD uncompressed_size;
    WORD filename_length;
    WORD extra_length;
    WORD comment_length;
    WORD disk_no;
    WORD internal_attr;
    DWORD external_attr;
    DWORD local_offs;
};
#pragma pack(pop)
 
 
 
 
unsigned long crc32(unsigned long crc, const unsigned char *buf, int len)
                   
{
    #define CRC32_POLYNOMIAL 0xEDB88320
unsigned long crc_table[256];
    unsigned long crc32;
    int i, j;
 
    for (i = 0; i < 256; i++) {
        crc32 = i;
        for (j = 8; j > 0; j--) {
            if (crc32 & 1)
                crc32 = (crc32 >> 1) ^ CRC32_POLYNOMIAL;
            else
                crc32 >>= 1;
        }
        crc_table[i] = crc32;
    }
 
  if (buf == NULL) return 0L;
#define CRC32(c, b) (crc_table[((int)(c) ^ (b)) & 0xff] ^ ((c) >>)
#define DO1(buf)  crc = CRC32(crc, *buf++)
#define DO2(buf)  DO1(buf); DO1(buf)
#define DO4(buf)  DO2(buf); DO2(buf)
#define DO8(buf)  DO4(buf); DO4(buf)
  crc = crc ^ 0xffffffffL;
#ifndef NO_UNROLLED_LOOPS
  while (len >= {
    DO8(buf);
    len -= 8;
  }
#endif
  if (len) do {
    DO1(buf);
  } while (--len);
  return crc ^ 0xffffffffL;   
}
 
static void zip_putcurtime(WORD *f_time, WORD *f_date)
{
    SYSTEMTIME systime;
 
    GetSystemTime(&systime);
    if ((systime.wYear < 1999) || (systime.wYear > 2010))
        systime.wYear = 2004;
    if (systime.wMonth < 1 || systime.wMonth > 12) systime.wMonth = 1;
    if (systime.wDay < 1 || systime.wDay > 31) systime.wDay = 10;
 
    *f_date =
        ((systime.wYear-1980) << 9) |
        (systime.wMonth << 5) |
        systime.wDay;
 
    *f_time =
        (systime.wHour << 11) |
        (systime.wMinute << 5) |
        (systime.wSecond / 2);
}
 
static unsigned long zip_calc_crc32(HANDLE hFileIn)
{
    unsigned long reg, i;
    unsigned char buf[1024];
    SetFilePointer(hFileIn, 0, NULL, FILE_BEGIN);
    for (reg=0; {
        i = 0;
        if (ReadFile(hFileIn, buf, sizeof(buf), &i, NULL) == 0) break;
        if (i == 0) break;
        reg = crc32(reg, buf, i);
    }
    SetFilePointer(hFileIn, 0, NULL, FILE_BEGIN);
    return reg;
}
 
int zip_store(char *in, char *out, char *store_as)
{
    HANDLE hFileIn, hFileOut;
    struct zip_header_t hdr1;
    struct zip_eod_t eod1;
    struct zip_dir_t dir1;
    char buf[1024];
    unsigned long i, j, offs;
 
    hFileIn = CreateFile(in, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFileIn == INVALID_HANDLE_VALUE || hFileIn == NULL)
        return 1;
    hFileOut = CreateFile(out, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
        NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFileOut == INVALID_HANDLE_VALUE || hFileOut == NULL) {
        CloseHandle(hFileIn);
        return 2;
    }
 
    memset(&hdr1, '\0', sizeof(hdr1));
    memset(&dir1, '\0', sizeof(dir1));
    memset(&eod1, '\0', sizeof(eod1));
    offs = 0;
 
    hdr1.signature = 0x04034b50;
    dir1.ver_needed = hdr1.ver_needed = 10;
    dir1.flags = hdr1.flags = 0;
    dir1.method = hdr1.method = 0;
    zip_putcurtime(&hdr1.lastmod_time, &hdr1.lastmod_date);
    dir1.lastmod_time = hdr1.lastmod_time;
    dir1.lastmod_date = hdr1.lastmod_date;
    hdr1.crc = zip_calc_crc32(hFileIn);
    dir1.crc = hdr1.crc;
 
    hdr1.compressed_size = GetFileSize(hFileIn, NULL);
    dir1.compressed_size = hdr1.compressed_size;
    hdr1.uncompressed_size = GetFileSize(hFileIn, NULL);
    dir1.uncompressed_size = hdr1.uncompressed_size;
    hdr1.filename_length = lstrlen(store_as);
    dir1.filename_length = hdr1.filename_length;
    dir1.extra_length = hdr1.extra_length = 0;
 
    dir1.local_offs = offs;
 
    WriteFile(hFileOut, &hdr1, sizeof(hdr1), &i, NULL);
    offs += sizeof(hdr1);
    WriteFile(hFileOut, store_as, lstrlen(store_as), &i, NULL);
    offs += lstrlen(store_as);
    SetFilePointer(hFileIn, 0, NULL, FILE_BEGIN);
    for (; {
        i = 0;
        if (ReadFile(hFileIn, buf, sizeof(buf), &i, NULL) == 0) break;
        if (i == 0) break;
        WriteFile(hFileOut, buf, i, &j, NULL);
        offs += i;
    }
 
    eod1.dir_offs = offs;
 
    dir1.signature = 0x02014b50;
    dir1.made_by = 20;     
    dir1.internal_attr = 0;
    dir1.external_attr = 0x20; 
    WriteFile(hFileOut, &dir1, sizeof(dir1), &i, NULL);
    offs += sizeof(dir1);
    WriteFile(hFileOut, store_as, lstrlen(store_as), &i, NULL);
    offs += lstrlen(store_as);
 
    eod1.signature = 0x06054b50;
    eod1.disk_no = 0;
    eod1.disk_dirst = 0;
    eod1.disk_dir_entries = 1;
    eod1.dir_entries = eod1.disk_dir_entries;
    eod1.dir_size = offs - eod1.dir_offs;
    eod1.comment_len = 0;
    WriteFile(hFileOut, &eod1, sizeof(eod1), &i, NULL);
 
    CloseHandle(hFileOut);
    CloseHandle(hFileIn);
    return 0;}
« Last Edit: April 21, 2013, 04:37:13 am by xC »

Offline Kulverstukas

  • Administrator
  • Zeus
  • *
  • Posts: 6627
  • Cookies: 542
  • Fascist dictator
    • View Profile
    • My blog
Re: zip_store
« Reply #1 on: April 13, 2013, 01:30:49 pm »
ehrrm... do I know you? I believe you haven't introduced yourself.
« Last Edit: April 13, 2013, 01:31:06 pm by Kulverstukas »

xC

  • Guest
Re: zip_store
« Reply #2 on: April 13, 2013, 01:54:12 pm »
I made a proper greeting in the introduction section.

Offline Xires

  • Noob Eater
  • Administrator
  • Knight
  • *
  • Posts: 379
  • Cookies: 149
    • View Profile
    • Feed The Trolls - Xires
Re: zip_store
« Reply #3 on: April 13, 2013, 07:07:52 pm »
I can see evidence that someone has attempted to optimize this for efficiency.  It could benefit from far more.  You could introduce additional flexibility via further modularity as well.  You may also consider benchmarking things like memset vs calloc vs OS native calls.  As well, '\0' and 0 are the same; use the latter.  Specific signatures & special values should be #defined and not necessarily hardcoded within the body of the source.  The code could even benefit from some generalization and made more cross-platform compatible.
-Xires