ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[1.c]ÄÄ // Advanced ZCME // Permutating Engine Research // Copyright (C) 1997, 1998 Z0MBiE/29A // // *** NOT FOR [RE]PUBLISHING/DISASM IN VX-ZINES, EXCEPT 29A *** // Internal version: 0.04 // Last modified: 18-07-98 #include "params.h" char ZERO_FILL_ARRAY[max_size-0x1300] = {0}; #include "system.h" #include "crt.h" #include "fileio.h" #include "random.h" #include "disasm.h" #include "engine.h" void main(void) { pchar p; #ifdef SKIP_PRINTF asm __1: lea di, printf mov al, 0xC3 stosb lea di, __1 mov cx, __2 - __1 mov al, 0x90 rep stosb end; #endif clrscr(3); asm __2:end; printf("Startup code executed\n"); run_engine(); printf("Terminating\n"); exit(0); } ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[1.c]ÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[params.h]ÄÄ /* DEBUG parameters */ #define SKIP_PRINTF #define SKIP_DEBUGFILES /* ENGINE parameters */ #define SKIP_JMPS //#define SKIP_JMPS_BUT_ADD_NOPS #define RANDOM_JCC //#define INVERSE_JCC #define SKIP_NOP //#define SKIP_INT3 #define SKIP_RANDOM #define ADD_RANDOM 30 #define CHANGE_CMD //#define FILL_UNUSED_CC #define FILL_UNUSED_RANDOM #define USE_RANDOM_IP 20 #define min_left 20 #define min_right 40 #define min_right_left 20 #define KILL_J2J #define MAKE_SHORT_JMPS #define max_size 0x3000+0x0100 #define max_cmd 3000 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[params.h]ÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[system.h]ÄÄ #define make_ptr( seg,ofs ) ( (void _seg * )( seg ) +( void near * )( ofs )) #define ptr_seg( fp ) ( (unsigned )( void _seg * )( void far * )( fp )) #define ptr_ofs( fp ) ( (unsigned )( fp )) typedef unsigned char byte; typedef unsigned int word; typedef unsigned long dword; #define short signed char #define pchar const far char * #define MAX(a,b) a > b ? a : b #define MIN(a,b) a < b ? a : b #define asm asm { #define end } void exit(byte exitcode); void fillchar(pchar buf, word bufsize, char filler); void move(pchar src, pchar dest, word size); word len(pchar str); void beep(void) { asm mov al, 7 int 29h end; } void exit(byte exitcode) { asm mov al, exitcode add al, '0' int 29h mov ah, 4Ch mov al, exitcode int 21h end; } void fillchar(pchar buf, word bufsize, char filler) { asm mov cx, bufsize or cx, cx jz __1 les di, buf mov al, filler cld rep stosb __1: end; } void move(pchar src, pchar dest, word size) { asm mov cx, size or cx, cx jz __1 push ds lds si, src les di, dest cld rep movsb pop ds __1: end; } word len(pchar str) { asm les di, str mov cx, 0ffffh xor al, al repnz scasb neg cx dec cx dec cx xchg cx, ax end; } ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[system.h]ÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[crt.h]ÄÄ void clrscr(byte mode); void pascal printf_char(char c); void pascal printf_dword(dword d); void printf_word(word w); void printf_byte(byte b); void pascal printf_long(long l); void printf_int(int i); void printf_short(short s); void pascal printf_hexchar(byte b); void pascal printf_hexbyte(byte b); void pascal printf_hexword(word w); void pascal printf_hexdword(dword d); void pascal printf_crlf(void); void printf(pchar format, ...); void clrscr(byte mode) { asm xor ax, ax mov al, mode int 10h end; } void pascal printf_char(char c) { asm mov ah, 2 mov dl, c int 21h end; } void pascal printf_crlf(void) { printf_char(13); printf_char(10); } void pascal printf_dword(dword d) { asm mov eax, d call __1 jmp __3 __1: xor edx, edx mov ebx, 10 div ebx push dx or eax, eax jz __2 call __1 __2: pop ax add al, '0' push ax call printf_char ret __3: end; } void printf_word(word w) { printf_dword(w); } void printf_byte(byte b) { printf_dword(b); } void pascal printf_long(long l) { if (l < 0) { printf_char('-'); l = -l; } printf_dword(l); } void printf_int(int i) { printf_long(i); } void printf_short(short s) { printf_long(s); } void pascal printf_hexchar(byte b) { if (b <= 9) printf_char('0'+b); else printf_char('A'+b-10); } 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 printf(pchar format, ...) { int stack_ptr = 0; asm push ds lds si, format cld __nextchar: lodsb or al, al jz __exit cmp al, '%' je __percent cmp al, 10 je __crlf __putchar: push ax call printf_char jmp __nextchar __crlf: call printf_crlf jmp __nextchar __percent: lodsb or al, al jz __exit cmp al, 'c' je __c cmp al, 'i' je __i cmp al, 'l' je __l cmp al, 'b' je __b cmp al, 'w' je __w cmp al, 'd' je __d cmp al, 'B' je __B_ cmp al, 'W' je __W_ cmp al, 'D' je __D_ jmp __putchar __pop_ax: mov di, stack_ptr add word ptr stack_ptr, 2 mov ax, [bp+8+di] ret __pop_eax: mov di, stack_ptr add word ptr stack_ptr, 4 mov eax, [bp+8+di] ret __c: call __pop_ax push ax call printf_char jmp __nextchar __s: call __pop_ax push ax call printf_short jmp __nextchar __i: call __pop_ax push ax call printf_int jmp __nextchar __l: call __pop_eax push eax call printf_long jmp __nextchar __b: call __pop_ax push ax call printf_byte jmp __nextchar __w: call __pop_ax push ax call printf_word jmp __nextchar __d: call __pop_eax push eax call printf_dword jmp __nextchar __B_: call __pop_ax push ax call printf_hexbyte jmp __nextchar __W_: call __pop_ax push ax call printf_hexword jmp __nextchar __D_: call __pop_eax push eax call printf_hexdword jmp __nextchar __exit: pop ds end; } ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[crt.h]ÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[fileio.h]ÄÄ #define handle word handle openfile(pchar fname); handle createfile(pchar fname); void closefile(handle h); word readfile(handle h, pchar buf, word bufsize); word writefile(handle h, pchar buf, word bufsize); dword filepos(handle h); dword seekfile(handle h, dword newpos); dword seekeof(handle h); dword filesize(handle h); handle openfile(pchar fname) { asm push ds mov ax, 3d02h lds dx, fname int 21h pop ds end; } handle createfile(pchar fname) { asm push ds mov ah, 3Ch xor cx, cx lds dx, fname int 21h pop ds end; } void closefile(handle h) { asm mov ah, 3Eh mov bx, h int 21h end; } word readfile(handle h, pchar buf, word bufsize) { asm push ds mov ah, 3Fh mov bx, h mov cx, bufsize lds dx, buf int 21h pop ds end; } word writefile(handle h, pchar buf, word bufsize) { asm push ds mov ah, 40h mov bx, h mov cx, bufsize lds dx, buf int 21h pop ds end; } dword filepos(handle h) { asm mov ax, 4201h mov bx, h int 21h end; } dword seekfile(handle h, dword newpos) { asm mov ax, 4200h mov bx, h mov cx, word ptr newpos + 2 mov dx, word ptr newpos + 0 int 21h end; } dword seekeof(handle h) { asm mov ax, 4202h mov bx, h xor cx, cx cwd int 21h end; } dword filesize(handle h) { dword savepos, retvalue; savepos = filepos(h); retvalue = seekeof(h); seekfile(h, savepos); return(retvalue); } ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[fileio.h]ÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[random.h]ÄÄ int rndword; word random_word(void); word rnd_word(word range); word rnd_word_minmax(word min, word max); word random_word(void) { asm mov bx, rndword in al, 40h 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; } word rnd_word(word range) { if (range == 0) return(0); else return(random_word() % range); } word rnd_word_minmax(word min, word max) { return(rnd_word(max-min+1) + min); } ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[random.h]ÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[disasm.h]ÄÄ #define cf_is66 0x0001 #define cf_is67 0x0002 #define cf_isSEG 0x0004 #define cf_isREP 0x0008 #define cf_isLOCK 0x0010 #define cf_is0F 0x0020 #define cf_isMODRM 0x0040 #define cf_isSIB 0x0080 #define cf_isMEM 0x0100 #define cf_isDATA 0x0200 #define cf_isDATAREL 0x0400 #define ct_UNKNOWN 0 #define ct_JMP 1 #define ct_JCC 2 #define ct_CALL 3 #define ct_RET 4 typedef union datauion { word w[3]; byte b[6]; } dataunion; typedef struct tcmdrec { word flags; // cf_xxxx word type; // ct_xxxx word size; // total cmd. size word base; // instruction offset (16-bit) byte px_SEG; // prefix: segment prefix byte px_REP; // prefix: repz/repnz byte opcode; byte modrm; byte mod; byte reg; byte rm; byte sib; word memsize; byte mem[4]; word datasize; dataunion data; word jmpptr; // jmp/call ABSOLUTE pointer (+base), 16-bit } tcmdrec; void dump(pchar cmd, word size) { printf("%W ",(word) cmd); for (; size>0; size--, cmd++) printf(" %B", (byte) (*cmd)); printf("\n"); } #define getbyte(x) { x = (byte) (*cmd_ptr++); }; #define getword(x) { x = (word) (*cmd_ptr+=1); }; #define getdword(x) { x = (dword) (*cmd_ptr+=2); }; #define getnextbyte(x) { x = ((byte) (*cmd_ptr)); } tcmdrec r; pchar cmd_ptr; word disasm_base; void modrm_proc(void) { getbyte(r.modrm); r.mod = r.modrm >> 6; r.reg = (r.modrm >> 3) & 7; r.rm = r.modrm & 7; if ((r.flags & cf_is67) == 0) { // 16-bit MODR/M if (((r.mod == 0) && (r.rm == 6)) || (r.mod == 2)) r.memsize = 2; if (r.mod == 1) r.memsize = 1; } else { // 32-bit MODR/M if (((r.mod == 0) && (r.rm == 5)) || (r.mod == 2)) r.memsize = 4; if (r.mod == 1) r.memsize = 1; if (r.rm == 4) { r.flags |= cf_isSIB; getbyte(r.sib); }; }; } void disasm(pchar cmd, tcmdrec far *rec) { byte b,nextbyte; int i; fillchar(&r, sizeof(tcmdrec), 0x00); r.base = (word) cmd; r.jmpptr = -1; cmd += disasm_base; cmd_ptr = cmd; // begin disasm prefix: getbyte(b); if ((b==0x2E) || (b==0x26) || (b==0x3E) || (b==0x36) || (b==0x64) || (b==0x65)) { r.flags |= cf_isSEG; r.px_SEG = b; goto prefix; } if ((b==0xF2) || (b==0xF3)) { r.flags |= cf_isREP; r.px_REP = b; goto prefix; } switch(b) { case 0x66: r.flags |= cf_is66; goto prefix; case 0x67: r.flags |= cf_is67; goto prefix; case 0xF0: r.flags |= cf_isLOCK; goto prefix; }; // prefix analyzed r.opcode = b; if (b == 0x0F) goto prefix_0F; getnextbyte(nextbyte); if (b == 0xE9) { r.type = ct_JMP; goto data_offs_rel; } if (b == 0xE8) { r.type = ct_CALL; goto data_offs_rel; } if ((b & 0xF0) == 0x70) { r.type = ct_JCC; goto data_byte_rel; } if (b == 0xEB) { r.type = ct_JMP; goto data_byte_rel; } if ((b == 0xC3) || (b == 0xCF)) { r.type = ct_RET; goto okey; } if (b == 0xC2) { r.type = ct_RET; goto data_word; } if (b == 0xC8) goto data_3xbyte; if ( (b == 0xC9) || (b == 0xFC) || (b == 0xAA) || (b == 0xA4) || (b == 0xAE) || (b == 0x98) || (b == 0x99) || (b == 0xAC) || (b == 0xCC) // int 3 ) goto okey; if ((b & 0xFC) == 0x88) goto modrm; if ((b & 0xFE) == 0xC6) goto modrm_data_w_66; if ((b & 0xF0) == 0xB0) goto data_w3_66; if ((b & 0xFC) == 0xA0) goto data_offs; if ( (b == 0xCD) || (b == 0xE4) ) goto data_byte; if ((b & 0xF0) == 0x50) goto okey; if ((b == 0xFF) && ( (((nextbyte >> 3) & 7) == 0) || (((nextbyte >> 3) & 7) == 6) )) goto modrm; if ((b & 0xFE) == 0xC4) // gluk ! goto modrm; if ((b & 0xE6) == 0x06) goto okey; if ((b & 0xC4) == 0x00) goto modrm; if ((b & 0xFC) == 0x80) goto modrm_data_sw_66; if ((b & 0xC6) == 0x04) goto data_w_66; if ( ((b & 0xFE) == 0xF6) && (((nextbyte >> 3) & 6) == 2) ) goto modrm; if ((b & 0xF0) == 0x40) goto okey; if ( ((b & 0xFE) == 0xFE) && (((nextbyte >> 3) & 6) == 0) ) goto modrm; if ((b & 0xF8) == 0x90) goto okey; if (b == 0x6A) goto data_byte; if (b == 0x68) goto data_66; if ( ((b & 0xFE) == 0xF6) && (((nextbyte >> 3) & 6) == 6) ) goto modrm; if ((b & 0xFC) == 0xD0) goto modrm; if ((b & 0xFE) == 0xC0) goto modrm_data_byte; if ((b & 0xFE) == 0x84) goto modrm; if ( ((b & 0xF6) == 0xF6) && (((nextbyte >> 3) & 7) == 0) ) goto modrm_data_w_66; if ((b & 0xFE) == 0xA8) goto data_w_66; if ((b & 0xFD) == 0x8C) goto modrm; if (b == 0x8D) goto modrm; if ( ((b & 0xFE) == 0xF6) && (((nextbyte >> 3) & 7) == 4) ) goto modrm; if ((b & 0xFE) == 0x86) goto modrm; error: dump(cmd, 10); printf("<- unknown command\n"); exit(1); prefix_0F: r.flags |= cf_is0F; getbyte(b); r.opcode = b; getnextbyte(nextbyte); if ((b & 0xF0) == 0x80) { r.type = ct_JCC; goto data_offs_rel; } if ((b & 0xF6) == 0xB6) goto modrm; goto error; modrm_data_byte: modrm_proc(); goto data_byte; modrm_data_w_66: modrm_proc(); goto data_w_66; modrm_data_sw_66: modrm_proc(); goto data_sw_66; modrm: modrm_proc(); goto okey; data_w3_66: if ((r.opcode & 0x08) != 0) goto data_66; else goto data_byte; data_sw_66: if ((r.opcode & 0x02) != 0) goto data_byte; goto data_w_66; data_w_66: if ((r.opcode & 0x01) != 0) goto data_66; else goto data_byte; data_byte: r.datasize = 1; goto data; data_66: if ((r.flags & cf_is66) == 0) goto data_word; else goto data_dword; data_dword: r.datasize = 4; goto data; data_word: r.datasize = 2; goto data; data_3xbyte: r.datasize = 3; goto data; data_offs: if ((r.flags & cf_is67) == 0) r.datasize = 2; else r.datasize = 4; goto data; data_offs_rel: if ((r.flags & cf_is66) == 0) r.datasize = 2; else r.datasize = 4; goto data_rel; data_byte_rel: r.datasize = 1; goto data_rel; data_rel: r.flags |= cf_isDATAREL; goto data; data: r.flags |= cf_isDATA; goto okey; okey: if (r.datasize != 0) for (i=0; i 0; size--) buf_mark[ofs++] = marker; } void store_byte(byte b) { output[out_ip++] = b; } void store_word(word w) { store_byte(w & 255); store_byte(w >> 8); } void store_link(word old_ip, word new_ip) { if (link_max >= max_cmd) { printf("Too many links(commands)\n"); exit(1); } link_1[link_max] = old_ip; link_2[link_max] = new_ip; link_max++; printf("link #%w: %W <--> %W\n", link_max,old_ip,new_ip); } void store_jmp(word to_ip) { printf("*** STORE_JMP: offs=%W\n", to_ip); store_link(0xFFFE, out_ip); store_byte(0xE9); store_word(to_ip); } void store_jmp_output(word to_ip) { word w; printf("*** STORE_JMP_OUTPUT: offs=%W\n", to_ip); store_link(0xFFFF, out_ip); //store_byte(0x90); store_byte(0xE9); store_word(to_ip - (out_ip+2)); } word free_space(word start) { int i; for (i=0; (start+i) (min_left+min_right) ) goto found; }; printf("***WARNING***: No free space in output buffer\n"); return; found: i += min_left; printf("New IP found at %W\n", i); store_jmp_output(i); out_ip = i; } void random_new_ip(void) { #ifdef USE_RANDOM_IP printf("Executing RANDOM_NEW_IP\n"); if (rnd_word(USE_RANDOM_IP) == 0) { make_new_ip(); }; #endif } byte store_inversed_jmp; void store_cmd(word ip, word size) { pchar p; tcmdrec r; word i; if (free_space(out_ip) < min_right_left) make_new_ip(); else random_new_ip(); printf("*** STORE_CMD: offs=%W size=%W\n", ip, size); store_link(ip, out_ip); disasm(make_ptr(_CS,ip), &r); if ((r.type == ct_JMP) || (r.type == ct_JCC) || (r.type == ct_CALL)) { if ( (store_inversed_jmp == 1) && (r.type == ct_JCC) ) { r.jmpptr = ip-disasm_base + r.size; r.opcode ^= 1; } if ((r.opcode & 0xF0) == 0x80) { store_byte(0x0F); store_byte(r.opcode); store_word(r.jmpptr); return; } if ((r.opcode & 0xF0) == 0x70) { store_byte(0x0F); store_byte(r.opcode - 0x70 + 0x80); store_word(r.jmpptr); return; } if (r.opcode == 0xEB) { store_byte(0xE9); store_word(r.jmpptr); return; } if ( (r.opcode == 0xE8) || (r.opcode == 0xE9) ) { store_byte(r.opcode); store_word(r.jmpptr); return; } printf("ERROR 1, X=%B\n", r.opcode); exit(2); } #ifdef SKIP_NOP if (r.opcode == 0x90) return; #endif #ifdef SKIP_INT3 if (r.opcode == 0xCC) return; #endif #ifdef SKIP_RANDOM if (r.size == 2) if ( ( ((r.opcode & 0xFE) == 0x86) || ((r.opcode & 0xFE) == 0x88) ) && (r.mod == 3) ) return; #endif #ifdef CHANGE_CMD i = r.opcode & 0xFE; if (r.size == 2) if (r.mod == 3) if ( (i == 0x08) || (i == 0x0A) || (i == 0x20) || (i == 0x22) || (i == 0x84) ) { i = rnd_word(5); if (i == 0) i = 0x08; if (i == 1) i = 0x0A; if (i == 2) i = 0x20; if (i == 3) i = 0x22; if (i == 4) i = 0x84; store_byte(((r.opcode & 0x01) + i)); store_byte(r.modrm); return; }; #endif for (; size>0; size--) { p = make_ptr(_CS,ip++); store_byte( (byte) *p ); } #ifdef ADD_RANDOM if (rnd_word(ADD_RANDOM) == 0) { word f; store_byte(0x86 + rnd_word(4)); f = (random_word() & 7); store_byte(0xC0 + (f << 3) + f); }; #endif } byte pass_action; void process_1(word ip) { tcmdrec rec; nextcmd: if ((ip < 0x0100) || (ip >= max_size)) { printf("IP range check error, exiting\n"); return; } disasm(make_ptr(_CS,ip), &rec); printf("Marking: "); dump(make_ptr(_CS,ip+disasm_base), rec.size); if (pass_action == 2) { printf("PASS 2: Saving offset %W to LINK_2[%w]\n", ip, link_max); if (link_max > max_cmd*2) // *2 becoz using 2 arrays: ..._2 & 1 { printf("Too many links!!!"); exit(3); }; link_2[link_max] = ip; link_max++; } if (buf_mark[ip] == MARKED) { printf("Alredy marked, exiting\n"); if (pass_action == 1) store_jmp(ip+disasm_base); return; }; mark_cmd(rec.base, rec.size, MARKED); if (rec.type == ct_UNKNOWN) { if (pass_action == 1) store_cmd(ip+disasm_base, rec.size); ip += rec.size; }; if (rec.type == ct_RET) { if (pass_action == 1) store_cmd(ip+disasm_base, rec.size); printf("[RET] Exiting\n"); return; }; if (rec.type == ct_JMP) { if (pass_action == 1) { #ifndef SKIP_JMPS store_cmd(ip+disasm_base, rec.size); #else store_link(ip+disasm_base, out_ip); #ifdef SKIP_JMPS_BUT_ADD_NOPS store_byte(0x90); #endif #endif } printf("[JMP] Changing IP to %W\n", rec.jmpptr); ip = rec.jmpptr; }; if (rec.type == ct_CALL) { if (pass_action == 1) store_cmd(ip+disasm_base, rec.size); ip+=rec.size; printf("[CALL] Marking for next pass: %W\n", rec.jmpptr); mark_cmd(rec.jmpptr, 1, FORNEXTPASS); }; if (rec.type == ct_JCC) { #ifdef RANDOM_JCC word rnd = rnd_word(2); #else #ifdef INVERSE_JCC word rnd = 1; #else word rnd = 0; #endif #endif if (rnd == 0) { store_inversed_jmp = 0; if (pass_action == 1) store_cmd(ip+disasm_base, rec.size); ip+=rec.size; printf("[Jcc] Marking for next pass: %W\n", rec.jmpptr); mark_cmd(rec.jmpptr, 1, FORNEXTPASS); }; if (rnd == 1) { store_inversed_jmp = 1; if (pass_action == 1) store_cmd(ip+disasm_base, rec.size); ip+=rec.size; printf("[Jcc] ***INVERSED*** Marking for next pass: %W\n", ip); mark_cmd(ip, 1, FORNEXTPASS); printf("Changing IP to %W\n", rec.jmpptr); ip = rec.jmpptr; }; }; goto nextcmd; } void mark_unused(void) { int i; fillchar(buf_mark, max_size, UNUSED); link_max = 0; printf("Marking entry point(s)\n"); process_1(0x0100); cycle: printf("Searching for FORNEXTPASS mark(s)\n"); for (i = 0; i < max_size; i++) if (buf_mark[i] == FORNEXTPASS) { printf("Found at %W\n", i); process_1(i); goto cycle; } printf("No FORNEXTPASS-mark(s) found\n"); } void run_engine(void) { handle h; word i; word j; word k; word w; word q; word e; pchar p; tcmdrec r1; tcmdrec r2; tcmdrec r3; printf("Engine!\n {\n"); fillchar(output, max_size, OUTPUT_FILLER); out_ip = 0x100; disasm_base = 0; pass_action = 1; printf("Marking UNUSED commands (1)\n"); mark_unused(); #ifndef SKIP_DEBUGFILES printf("Writing file(s)\n"); h = createfile("buf_mark.1"); writefile(h, buf_mark, max_size); closefile(h); h = createfile("link_1.1"); writefile(h, link_1, link_max * 2); closefile(h); h = createfile("link_2.1"); writefile(h, link_2, link_max * 2); closefile(h); h = createfile("output.1"); writefile(h, &output[0x100], max_size-0x100); closefile(h); #endif printf("Updating JMPs...\n"); fillchar(buf_mark, max_size, UNUSED); for (i=0; i> 8; q++; } if (q != 1) { printf("ERROR 2, q=%w\n",q); exit(4); } }; }; skip_cycle: }; disasm_base = ((word) &output[0x0100]) - 0x100; pass_action = 2; printf("Marking UNUSED commands (2)\n"); mark_unused(); #ifndef SKIP_DEBUGFILES printf("Writing file(s)\n"); h = createfile("buf_mark.2"); writefile(h, buf_mark, max_size); closefile(h); h = createfile("link_1.2"); writefile(h, link_1, link_max * 2); closefile(h); h = createfile("link_2.2"); writefile(h, link_2, link_max * 2); closefile(h); #endif #ifdef KILL_J2J printf("Searching for Jxx-JMP, CALL-JMP, CALL-RET situations\n"); for (i=0; i %W \n", r1.base, r1.jmpptr, r2.jmpptr ); j=r1.base; if ((r1.flags & cf_is0F) != 0) j++; // 0F j++; // opcode w = r2.jmpptr - (j+2); output[j ] = w & 255; output[j+1] = w >> 8; }; }; }; printf("Marking UNUSED commands (3)\n"); mark_unused(); #endif #ifdef MAKE_SHORT_JMPS printf("Searching for Jxx/JMPs\n"); for (i=0; i