www.pudn.com > 29a_fu.zip > 29A-7.027


 
;------------------------------------------------------------------------------- 
; DISCLAIMER : All these informations and documentations are given :REMIALCSID ; 
; DISCLAIMER :    to public in order to understand how is made a   :REMIALCSID ; 
; DISCLAIMER :    virus, I'm not responsible of the use of this    :REMIALCSID ; 
; DISCLAIMER :  (cool) paper. Virus writting is not forbiden!      :REMIALCSID ; 
; DISCLAIMER :       but virus distribution is forbiden!!!         :REMIALCSID ; 
;------------------------------------------------------------------------------- 
 
 
                    ************************************************ 
                    *  POLYMORPHISM AND INTEL INSTRUCTION FORMAT   * 
                    ************************************************ 
 
 
   1  - INTRODUCTION 
   2  - INTEL INSTRUCTION FORMAT 
   3  - INSTRUCTION PREFIXE 
   4  - OP CODE 
   5  - ModR/M 
   6  - SIB 
   7  - DISPLACEMENT 
   8  - IMMEDIATE 
   9  - ALGO OF DISASSEMBLY 
   10 - HOW TO WRITE YOUR OWN ASSEMBLY PROCESS 
   11 - APPENDIX ( SCHEMAS AND TABLES ) 
 
   ********************* 
   ***               *** 
   **  INTRODUCTION   ** 
   ***               *** 
   ********************* 
 
   This quick tutorial will help you to understood the way to disassemble opcodes. 
   It is not an 'intel looks like' document...It is only an introduction to intel 
   opcode, after reading this you should read intel doc, or all doc speaking about 
   intel instruction format... 
 
 
   NOTION REQUIRED before learning this tutorial: 
 
     - asm, the only way to code nice vx... 
     - english, only the bad english used to wrote vx tutorials ;-) 
     - Encryption 
     - Polymorphisme 
 
   DOCUMENTS YOU SHOULD FIND: 
 
     - The Art Of Assembly (pdf)    http://aod.anticrack.de 
     - Intel Architecture Manual    http://intel.com 
     - Code source of NASM (in C++) 
 
   In the 'The Art Of Assembly Tutorial' you will find some exe prog to 
   play with opcodes! 
 
   In virus world there is a terrible war: Against virus writers and antivirus  
   software. Most virus writters code for pleasure but AV company for money... 
 
   I will not explain here the concept of polymorphism (see older zines!)  
   The principe is simple: in a polymorph virus, the body of the virus is encrypted 
   to avoid AV string scanning, and polymorphism is use in the 'decryptage' code. 
   The part of the code which decrypt all the rest of the virus is'nt encrypted but 
   his appeareance change in the next infection. There is severals ways to do that. 
   If will explain here a cool technique: The virus is able to disasm the 
   'decryptage loop', change him, and re-asm it. 
 
   example: 
 
;---------------------------------------------------------------- 
      lea esi,[VirusBody+ebp]           ; (ebp=delta offset of course) 
      mov ecx,EndOfVirusBody-VirusBody  ; lenght of virus body 
      mov al,byte[key+ebp]              ; key to decrypte data 
Decrypt: 
      xor byte[esi],al 
      inc esi 
   loop Decrypt 
VirusBody: 
   . 
   . 
   . 
EndOfVirusBody: 
;---------------------------------------------------------------- 
   can be change in: 
;---------------------------------------------------------------- 
      mov esi,[VirusBody] 
      add esi,ebp 
      xor ebx,ebx 
      mov bl,byte[key+ebp] 
      xchg eax,ebx 
      push dword EndOfVirusBody-VirusBody 
      pop ecx 
Decrypt: 
      xor byte[esi],al 
      add esi,1 
      nop 
   loop Decrypt 
VirusBody: 
   . 
   . 
   . 
EndOfVirusBody: 
;---------------------------------------------------------------- 
 
 
 
   The problem is to Disasm, and Re-asm the code...To do this I will explain 
   brievely the Intel Instruction Format: 
   To know how to convert the hex string '40h' in his "humanly readeable code" 'inc eax' 
   for example 
 
 
   ******************************** 
   ***                          *** 
   **  INTEL INSTRUCTION FORMAT  ** 
   ***                          *** 
   ******************************** 
 
 
   An intel instruction has a specific format: 
 
 
                         INTEL INSTRUCTION FORMAT 
 
+-------------+--------+----------+---------+--------------+------------+ 
; instruction ; opcode ;  ModR/M  ;   SIB   ; Displacement ; Immediate  ; 
;   prefixe   ;        ;          ;         ;              ;            ; 
+-------------+--------+----------+---------+--------------+------------+ 
 Up to four    1 or 2   1 byte(if  1 byte(if address        immediate 
 prefixe of    bytes    required)  required) displacement   data 
 1 byte each   opcode         /         \    of 1,2 or 4    of 1,2 or 4  
 (optional)                  /           \   bytes or none  bytes or none 
                            /             \ 
                           /               \ 
                          /                 \ 
                         /                   \ 
             7   6 5      3 2   0         7     6 5     3 2    0 
            +-----+--------+-----+       +-------+-------+------+ 
            ; Mod ;  Reg/  ; R/M ;       ; scale ; index ; base ; 
            ;     ; opcode ;     ;       ;       ;       ;      ; 
            +-----+--------+-----+       +-------+-------+------+ 
 
 
   Intel instructions can vary in size, but they still have the same six 
   groups. We need to understand each group , and know it is purpose in order 
   to be able to learn the sizes of the diferent instructions. 
   I will not describe all in detail because it's annoying, find doc about intel 
   instruction format (see on intel web site) 
 
 
   *************************** 
   ***                     *** 
   **  INSTRUCTION PREFIXE  ** 
   ***                     *** 
   *************************** 
 
 
   The instruction prefix is optional but they change the behavior of the instruction 
   in many ways. an instruction can have (or not) 0,1,2,3 or 4 prefixes. 
   There are 5 type of prefixes: 
 
   - SEGMENT PREFIX      : Prefixes that specify the segment 
                           2E 36 3E 26 64 65 
 
   - Operand-Size Prefix : Prefix that changes the default operand size 
                           66 
 
   - Address-Size Prefix : Prefix that changes the default address size 
                           67 
 
   - REP/REPNE Prefixes  : Prefixes that change the string operation n loops 
                           F3 F2 
 
   - Bus LOCK Prefix     : Prefix that controls the processor BUS 
                           F0 
 
 
   * One opcode can have several prefix: none,1,2,3 or 4 
   * the order of the prefixes is not important 
   * Each prefix is 1 byte size 
    
 
   +----------------+ 
   ; Segment prefix ; 
   +----------------+ 
 
   The segment prefix change the default segment of the instruction, the default 
   segment prefix is DS: 
 
   2EH : CS  segment override prefix. 
   36H : SS  segment override prefix. 
   3EH : DS  segment override prefix. 
   26H : ES  segment override prefix. 
   64H : FS  segment override prefix. 
   65H : GS  segment override prefix. 
 
 
   expl:     8B00    MOV EAX,DWORD PTR DS:[EAX]   (none prefix) 
          2E:8B00    MOV EAX,DWORD PTR CS:[EAX] 
             8B00    MOV EAX,DWORD PTR DS:[EAX]   (none prefix) 
          36:8B00    MOV EAX,DWORD PTR SS:[EAX] 
 
   +---------------------+ 
   ; OPERAND-SIZE PREFIX ; 
   +---------------------+ 
 
The operand size prefix allows a programm to switch between 16 n' 32 bit operand sizes. 
This prefix select the non-default size...It is to say that if there is not the prefix 
66h so it is the default operand size. It 's recommended not to use this prefix after 
MMX, SSE and/or SSE2 instructions! 
    
 
   Quick example(in a win32 environement): 
 
      89 C0   MOV EAX,EAX   (none prefix) 
   66 89 C0   MOV AX, AX    (prefix=66h) 
 
   +---------------------+ 
   ; Address-Size Prefix ; 
   +---------------------+ 
 
The address-size prefix allow a program to switch between 16 n' 32 bits 
addressing. the prefix select the non default size 
 
   I will put here an example because it's no really use for us 
   (I hope you code in win32...) 
 
   expl:     8B00   MOV EAX,DWORD PTR DS:[EAX]     32bits addressing mode 
          67:8B00   MOV EAX,DWORD PTR DS:[BX+SI]   16bits adressing mode 
 
   +--------------------+ 
   ; REP/REPNE Prefixes ; 
   +--------------------+ 
 
   I will put here only examples: 
 
         AD         LODS DWORD PTR DS:[ESI] 
      F3 AD   REP   LODS DWORD PTR DS:[ESI] 
      F2 AD   REPNE LODS DWORD PTR DS:[ESI] 
   3E F2 AD   REPNE LODS DWORD PTR DS:[ESI] 
 
   +-----------------+ 
   ; Bus LOCK Prefix ; 
   +-----------------+ 
 
   No use for us...Execpt if you want to know all the mystery of intel instruction 
   format in order to disasm the host, find a good place for the virus inside 
   the disassembled host code and reassembly all the infected file... 
 
 
   *************************** 
   **                       ** 
   **        OP CODE        ** 
   **                       ** 
   *************************** 
 
   +------------------+ 
   ; One Byte Opcodes ; 
   +------------------+ 
 
   in intel doc you can find something like this for the description of the 
   PUSH REG instruction: 
    
   PUSH REG <------> 01010reg   (where 'reg' are 3 bits) 
 
   For the description of all instruction, I let you see the big pdf file from intel 
   (I've put some description in APPENDIX about the most used instructions you can 
    use in a decryptor LOOP) 
    
   Let’s study this following instruction (it is 1byte instruction): 
 
    PUSH EAX  --->  50h  --->  01010000   ---> 01010 000 
                                                /      \ 
                                               /        \ 
                                              /          \ 
                                    bits   7 6 5 4 3   2 1 0 
                                         +-----------+--------+ 
                                         ;  OPCODE   ;REGISTER; 
                                         +-----------+--------+ 
                                         ; 0 1 0 1 0 ; 0 0 0  ; 
                                         +-----------+--------+ 
 
The 5 bits (01010) on the left  are responsible for the instruction 'push' 
The 3 bits (000)   on the right are responsible for the register 'eax' (see register table) 
 
let's look at some instruction encoding: 
 
        Little Opcode Table:              Register Table: 
  
                                         REG 8bit 16bit 32bit 
        01000reg : INC  REG              000 : AL : AX : EAX 
        01001reg : DEC  REG              001 : CL : CX : ECX 
        01010reg : PUSH REG              010 : DL : DX : EDX 
        01011reg : POP  REG              011 : BL : BX : EBX 
        10010reg : XCHG EAX,REG          100 : AH : SP : ESP 
        10111reg : MOV  REG,IMM32        101 : CH : BP : EBP 
                                         110 : DH : SI : ESI 
                                         111 : BH : DI : EDI 
 
   One another (fun) example: 
 
   90h --->  10010 000 ---> XCHG EAX,EAX  (NOP) 
 
   Only the instruction inc reg, dec reg, push reg, pop reg, xchg eax,reg, mov reg,imm32 
   can be decoded like this! for the others one byte instructions, I let you see an  
   one-byte-opcode map... 
 
   Let’s take a look at this opcode now, it is a another way to decode opcode: 
 
   89C1h ---> 1000100111000001b  ---> mov ecx,eax 
 
   It is still an one byte opcode: C1h is the [ModR/M] field! 
 
               89h      C1h 
            10001001 11000001  
             [CODE]  [ModR/M] 
              /          \ 
             /            \ 
            /              \ 
   +----------------+   +------------------+ 
   ; instr  ; d ; w ;   ; Mod; REG1 ; REG2 ; 
   +--------+---+---;   +----+------+------+ 
   ; 100010 ; 0 ; 1 ;   ; 11 ; 000  ; 001  ; 
   +--------+---+---+   +----+------+------+ 
 
 instr  : responsible for the opcode instruction 
 
 (d)bit: if (d)=0 then the order is REG2-REG1 
         if (d)=1 then the order is REG1-REG2 
 
 (w)bit: if (w)=0 we are in 8  bits mode in 32bits environement(Win32) 
         if (w)=1 we are in 32 bits mode in 32bits environement(Win32) 
 
         if (w)=0 we are in 8  bits mode in 16bits environement 
         if (w)=1 we are in 16 bits mode in 16bits environement 
 
  Mod  : we will see it later... 
 
   Ok, it's not very clear in your mind yet but you will understand with examples: 
 
 
                            ############################ 
                            # example for the (d) bit: # 
                            ############################ 
                              (in 32bits environement) 
 
       [CODE]             [ModR/M]            [CODE]             [ModR/M] 
+----------------;;------------------+  +----------------;;------------------+ 
; instr  ; d ; w ;; Mod; REG1 ; REG2 ;  ; instr  ; d ; w ;; Mod; REG1 ; REG2 ; 
+--------+---+---;;----+------+------+  +--------+---+---;;----+------+------+ 
; 100010 ; 0 ; 1 ;; 11 ; 000  ; 001  ;  ; 100010 ; 1 ; 1 ;; 11 ; 000  ; 001  ; 
+--------+---+---;;----+------+------+  +--------+---+---;;----+------+------+ 
    !      !   \          EAX    ECX        !      !   \          EAX    ECX 
    !      !    !       or AX  or CX        !      !    !       or AX  or CX 
   \!/     !   \!/      or AL  or CL       \!/     !   \!/      or AL  or CL 
    '      !    '                           '      !    ' 
   MOV     !   32bits                      MOV     !   32bits 
          \!/                                     \!/ 
           ' 
        the order                               the order 
      is REG2-REG1                             is REG1-REG2 
 \_______________  _________________/      \_______________  _________________/ 
                 \/                                        \/ 
             MOV ECX,EAX                              MOV EAX,ECX 
 
                            ############################ 
                            # example for the (w) bit: # 
                            ############################ 
 
 
       [CODE]             [ModR/M]             [CODE]             [ModR/M] 
+----------------;;------------------+  +----------------;;------------------+ 
; instr  ; d ; w ;; Mod; REG1 ; REG2 ;  ; instr  ; d ; w ;; Mod; REG1 ; REG2 ; 
+--------+---+---;;----+------+------+  +--------+---+---;;----+------+------+ 
; 100010 ; 0 ; 1 ;; 11 ; 000  ; 001  ;  ; 100010 ; 0 ; 0 ;; 11 ; 000  ; 001  ; 
+--------+---+---;;----+------+------+  +--------+---+---;;----+------+------+ 
    !      !   \          EAX    ECX        !      !   \          EAX    ECX 
    !      !    !       or AX  or CX        !      !    !       or AX  or CX 
   \!/     !   \!/      or AL  or CL       \!/     !   \!/      or AL  or CL 
    '      !    '                           '      !    ' 
   MOV     !   32bits                      MOV     !   8bits 
          \!/                                     \!/ 
           ' 
        the order                               the order 
      is REG2-REG1                             is REG2-REG1 
 \_______________  _________________/      \_______________  _________________/ 
                 \/                                        \/ 
             MOV ECX,EAX                              MOV CL,AL 
 
 
                examples with 66h prefix: 
 
  ;-------+-----------+----------+   ;-------+-----------+----------+ 
  ; Pref. ;   [CODE]  ; [ModR/M] ;   ; Pref. ;   [CODE]  ; [ModR/M] ; 
  +-------+-----------+----------+   +-------+-----------+----------+ 
  ; 66h   ;   89h     ;  C1h     ;   ;       ;   88h     ;  C1h     ; 
  +-------+-----------+----------+   +-------+-----------+----------+ 
  ; 66h   ; 10001001  ; 11000001 ;   ;       ; 10001000  ; 11000001 ;  
  ;       ;   (w)=1   ;          ;   ;       ;    (w)=0  ;          ; 
  +-------+-----------+----------+   +-------+-----------+----------+ 
               MOV CX,AX                          MOV CL,AL 
 
 
   Little Instruction Opcode table: 
 
       BINARY       OPCODE 
      ----------------------- 
      000010dw    OR  REG,REG 
      001000dw    AND REG,REG 
      001010dw    SUB REG,REG 
      001100dw    XOR REG,REG 
      001110dw    CMP REG,REG 
      100000dw    ADD REG,REG 
      100010dw    MOV REG,REG 
 
 
 
   I Hope You see the interest of this part for us to code polymorphe instructions! 
   NO !!!!!? Try to decode these two (hex) instructions: 
 
   First Instruction  : 8BF8  ---> mov edi, eax 
   Second Instruction : 89C7  ---> mov edi, eax 
 
   NICE! is'nt it? 
 
   +-------------------+ 
   ; Two Bytes Opcodes ; 
   +-------------------+ 
 
  Some instruction are 2 bytes long: 
 
   expl: 0f22 c0    mov cr0,eax 
 
 
   ****************** 
   **              ** 
   **    ModR/M    ** 
   **              ** 
   ****************** 
 
 
   If the instruction needs it, the [ModR/M] block tells to the processor which 
   registers or memory locations to be used by the instruction. 
   
   The [ModRM] Byte is decoded in a special way, the 8 Bits are divided into three  
   groups (2:3:3). Most of the time. Let us understand each of them. 
 
                         7   6 5      3 2   0       
                        +-----+--------+-----+ 
                        ; Mod ;  Reg/  ; R/M ; 
                        ;     ; opcode ;     ; 
                        +-----+--------+-----+ 
 
      * [Mod]: 
  
        00  : memory address                           expl: eax, [eax]       
        01  : memory address with 1 byte displacement  expl: [eax+00]   
        10  : memory address with 1 dword displacement expl: [eax+00000000] 
        11  : both operands are memory                 expl: eax,eax 
 
 
      * [Reg/opcode]: 
 
        This field can be considered as a Code extension field or as a Reg fielf. 
        The processor knows which is the right decoding for this field. 
 
         -If it is a Code extension: 
 
          There are instructions that require 1-Operand and others that require 
          2-Operands. For example: 
 
          ADD: instruction requires 2-Operands     (add eax, eax) 
          MUL: instruction requires only 1-Operand (mul eax) 
 
          If we’re working with an instruction that requires only 1-operand 
          then, the middle 3-Bits [Reg/opcode]field is Code extension bits. 
           
          example: 
  
          F7D0 : 11110111 11 010 000   not eax 
          F7E0 : 11110111 11 100 000   mul eax 
          F7F0 : 11110111 11 110 000   div eax 
 
          they all have 0xF7 for the [CODE] byte, only [Reg/opcode] is different. 
          (000 is for the reg eax!) 
           
         -If it is a Reg field: 
 
          example with the hex instruction:   
 
         [CODE] [MorR/M] 
           39    d0 
           CMP     \_ 
            \        \ 
             \        \ 
              \          7 6   5 4 3    2 1 0   bits 
               \        +-----+--------+-------+ 
                \       ; Mod ;  Reg/  ; R/M   ; 
                 \      ;     ; opcode ;       ; 
                  |     +-----+--------+-------+ 
                   \    ; 1 1 ; 0 1 0  ; 0 0 0 ; 
                    \   +-----+--------+-------+ 
                      CMP        EDX      EAX 
 
       So 39d0h is CMP EAX,EDX  (because of the (d) bits in [CODE] field) 
 
 
       * [R/M] 
 
        Depending on the (Mode) Bits in the ModRM byte:  
 
 
  - If [Mod]=00 and [R/M]=101 : then no register is used to calculate address, 
                                instead the address is in the DWORD after [ModR/M] 
                                Byte.  
                                expl: 3305 563412   xor eax,[12345678h] 
 
  - If [Mod]=00 and [R/M]=100 : It means that there’s a SIB byte right after 
                                the [ModR/M] byte. 
 
  - If [Mod]=01 and [R/M]=100 : It means that there’s a SIB byte right after 
                                the [ModR/M] byte. 
 
  - If [Mod]=10 and [R/M]=100 : It means that there’s a SIB byte right after 
                                the [ModR/M] byte. 
 
  - If [Mod]=11               : this field means --> registers 
                                exmpl: 89:C0 =  mov eax, eax  
 
   (P.S.: I've not verify this part, if [Mod]=xx then it means....) 
   (Let's make your own mind about that) 
 
   ****************** 
   **              ** 
   **     SIB      ** 
   **              ** 
   ****************** 
 
   SIB  Stands for (Scale : Index :Base). 
   The general Format Of The SIB Byte is ( Scale * Index + Base ).  
 
                          7 6   5 4 3    2 1 0   bits 
                        +-----+--------+-------+ 
                        ;Scale;  Index ; Base  ; 
                        +-----+--------+-------+ 
                         Scale * Index + Base  
 
   * Scale : can be considered as the multiplier (of the index register) 
 
   00:xxx:xxx = 2^0 = 1  (*1) 
   01:xxx:xxx = 2^1 = 2  (*2) 
   10:xxx:xxx = 2^2 = 4  (*4) 
   11:xxx:xxx = 2^3 = 8  (*8) 
 
   * Index : it is a Register (All register except esp) 
   * Base  : it is a Base Register 
 
   expl: 
 
        [SIB]      | 
   ----------------+---------------------------- 
   00 : 000 : 001  |  mov reg, [1 * eax + ecx] 
   01 : 001 : 010  |  mov reg, [2 * ecx + edx] 
   01 : 110 : 111  |  mov reg, [2 * edi + esi] 
   10 : 010 : 011  |  mov reg, [4 * edx + ebx] 
   11 : 011 : 000  |  mov reg, [8 * eax + ebx] 
 
 
   - If Index register code is the code for (esp), then the index is IGNORED, 
     and in this case, the value of the scale is also IGNORED, and only the 
     Base register is used to calculate the address. 
   - If we need to encode an instruction like (add reg, [esp]) it can’t be done 
     with simply using an SIB byte. But it would be encoded like this: 
     (add reg, [esp + DISPLACEMENT]) 
 
   ****************** 
   **              ** 
   ** DISPLACEMENT ** 
   **              ** 
   ****************** 
 
   Just a quik example with the instruction 8b bd 78563412 : 
 
                         8b      bd    78563412 
                       [CODE] [MorR/M]  [???] 
                        /         \ 
                       /           \ 
                      /             \ 
                     /               \ 
   +----------------;               +-----+--------+-------+ 
   ; instr  ; d ; w ;               ; Mod ;  Reg/  ; R/M   ; 
   +--------+---+---;               ;     ; opcode ;       ; 
   ; 100010 ; 1 ; 1 ;               +-----+--------+-------+ 
   +--------+---+---;               ; 1 0 ; 1 1 1  ; 1 0 1 ; 
   (d)=0 : the order is             +-----+--------+-------+ 
           REG1-REG2                         EDI      EBP 
   (w)=1 : 32 bits mode                    or code 
   instr : MOV r32,r/m32                  extension 
 
 
[CODE]       = 8b        : opcode 
                          ---> MOV r32,r/m32 
 
[Mod]        = 10        : memory address with 1 dword displacement  
                          ---> MOV REG,[REG+DWORD]         
 
[Reg/opcode] = 111       : this instruction don't need an code extension 
                           so it is a register 
                          ---> MOV EDI,[EBP+DWORD] 
 
[R/M]        = 101       : there is no [SIB] after the byte[ModR/M] 
  
[78563412]   = 12345678h : it is the deplacement 
                          ---> MOV EDI,[EBP+12345678h] 
 
 
So the instruction 8b bd 78563412 is mov edi,[ebp+12345678h] 
 
   ***************** 
   **             ** 
   **  IMMEDIATE  ** 
   **             ** 
   ***************** 
 
  expl:   05h          is the opcode for ADD EAX,imm32 
          05h 00000010 is the instruction for add eax, 10000000 
 
 
   **************************** 
   **                        ** 
   **  ALGO OF DISASSEMBLY   ** 
   **                        ** 
   **************************** 
 
       ! 
      \!/ 
 +-----'-------+ 
 ; Read 1 byte ; <--------- 
 +-------------+           \ 
       !                    \               +------------------+ 
      \!/                    --------<----- ; Convert to ASCII ; 
 +-----'------------+                       +-------.----------+ 
 ; Check for prefix ;                              /!\ 
 +------------------+                               ! 
       !                                            ! 
      \!/                                   +-----------------+ 
 ;-----'----------------+                   ; [IMMEDIATE]     ; 
 ; Decode [CODE] byte(s);                   +-----------------+ 
 +----------------------+                   ; [DISPLACEMENT]  ; 
       !                                    +-----------------+ 
      \!/                                   ; decode [SIB]    ; 
 +-----'-----------------+                  +-----------------+ 
 ; JMP or CALL opcodes ? ; -------->------> ; decode [ModR/M] ; 
 +-----------------------+                  +-----------------+ 
 
   ************************************************ 
   **                                            ** 
   ** HOW TO WRITE YOUR OWN DIS/ASSEMBLY PROCESS ** 
   **                                            ** 
   ************************************************ 
 
 
   Of course you can code a process which is able to disassemble all the code 
   of the virus, to morph all the code and to reassemble the virus. I think 
   it is better to deal only with the decryptor LOOP because it is more speed 
   and your code will be not too much big... 
 
   You should choose first the opcodes and morphed opcodes you want to include 
   in your decryptor LOOP. Next you can write a code which is able to disasm and reasm 
   them. 
   You will find a problem: JMP,LOOP and CALL instructions...Use your brain! 
   
   You should considered your decryptor like inside a larger field: 
 
+-----------------+                    +-----------------+    +-----------------+  
; POLY DECRYPTOR  ;                    ; POLY DECRYPTOR  ;    ; POLY DECRYPTOR  ; 
+-----------------+  because it        ;    MORPHED      ;    ; MORE MORPHED    ; 
;                 ;  can looks like    ;                 ;--->;                 ; 
;     EMPTY       ;  this next ------> +-----------------+    ;                 ; 
;     SPACE       ;                    ;                 ;    +-----------------+  
; (NOP or other)  ;                    ;    EMPTY SPACE  ;--->;   empty space   ; 
+-----------------+ <- fixed offset -> +-----------------+    +-----------------+  
;                 ;                    ;                 ;    ;                 ; 
;     VIRUS       ;                    ;     VIRUS       ;    ;      VIRUS      ; 
 
   of course you should check if your 'reasm code' isn't larger than your empty space... 
 
  +--------------------+ 
  + MORPHING YOUR CODE + 
  +--------------------+ 
 
 
   There is 4 ways to do that: 
 
 method 1 :  change the code 'xor ecx,ecx' in 'mov ecx,0' for example 
 
 method 2 :  change the encoding of instruction: 
 
            8BF8    mov edi,eax 
            89C7    mov edi,eax  (see the (d)bits in [CODE]field) 
 
            8b00    mov eax,dword ptr DS:[EAX] 
            3e8b00  mov eax,dword ptr DS:[EAX] (see default segment prefix) 
 
 
 method 3 :  insert instruction which don't change the result of your code 
 
 method 4 :  Change the registers used 
 
  Decrypt:                   Decrypt: 
        xor byte[esi],al           xor byte[edx],bl 
        inc esi                    inc edx 
     loop Decrypt                loop Decrypt 
 
 
   ****************** 
   **              ** 
   **   APPENDIX   ** 
   **              ** 
   ****************** 
 
 
                        ############################ 
                        # INTEL INSTRUCTION FORMAT # 
                        ############################ 
 
 
+-----------+--------+    +----------------;  
;  OPCODE   ;REGISTER;    ; instr  ; d ; w ; 
+-----------+--------+ OR +--------+---+---;  
; 0 1 0 1 0 ; 0 0 0  ;    ; 100010 ; 0 ; 1 ; 
+-----------+--------+    +--------+---+---;  
             \            / 
              \          / 
               \        / 
                \      / 
                 \    / 
+-------------+--------+----------+---------+--------------+------------+ 
; instruction ; opcode ;  ModR/M  ;   SIB   ; Displacement ; Immediate  ; 
;   prefixe   ;        ;          ;         ;              ;            ; 
+-------------+--------+----------+---------+--------------+------------+ 
 Up to four    1 or 2   1 byte(if  1 byte(if address        immediate 
 prefixe of    bytes    required)  required) displacement   data 
 1 byte each   opcode         /         \    of 1,2 or 4    of 1,2 or 4  
 (optional)                  /           \   bytes or none  bytes or none 
                            /             \ 
                           /               \ 
                          /                 \ 
                         /                   \ 
             7   6 5      3 2   0         7     6 5     3 2    0 
            +-----+--------+-----+       +-------+-------+------+ 
            ; Mod ;  Reg/  ; R/M ;       ; scale ; index ; base ; 
            ;     ; opcode ;     ;       ;       ;       ;      ; 
            +-----+--------+-----+       +-------+-------+------+ 
 
 
                        ############################ 
                        #          PREFIX          # 
                        ############################ 
 
 
   - SEGMENT PREFIX      : 2E(CS) 36(SS) 3E(DS) 26(ES) 64(FS) 65(GS) 
                           (default is DS) 
   - Operand-Size Prefix : 66 (default is none) 
   - Address-Size Prefix : 67 (default is none) 
   - REP/REPNE Prefixes  : F3 F2 
   - Bus LOCK Prefix     : F0 
 
 
                        ############################ 
                        #          [CODE]          # 
                        ############################ 
 
 
 
+-----------+--------+    Commone Opcode Table:      Register Table: 
;  OPCODE   ;REGISTER;                             REG 8bit 16bit 32bit 
+-----------+--------+     01000 : INC  REG        000 : AL : AX : EAX 
; 0 1 0 1 0 ; 0 0 0  ;     01001 : DEC  REG        001 : CL : CX : ECX 
+-----------+--------+     01010 : PUSH REG        010 : DL : DX : EDX 
                           01011 : POP  REG        011 : BL : BX : EBX 
                           10010 : XCHG EAX,REG    100 : AH : SP : ESP 
                           10111 : MOV  REG,IMM32  101 : CH : BP : EBP 
                                                   110 : DH : SI : ESI 
                                                   111 : BH : DI : EDI 
 
 
       [CODE]             [ModR/M]      Common Instruction Opcode table: 
+----------------;;------------------+ 
; instr  ; d ; w ;;    ; REG1 ; REG2 ;       BINARY       OPCODE 
+--------+---+---;;----+------+------+      ----------------------- 
; 100010 ; 0 ; 1 ;; 11 ; 000  ; 001  ;      000010dw    OR  REG,REG 
+--------+---+---;;----+------+------+      001000dw    AND REG,REG 
                                            001010dw    SUB REG,REG 
if (d)=0 , the order is REG2-REG1           001100dw    XOR REG,REG 
if (d)=1 , the order is REG1-REG2           001110dw    CMP REG,REG 
if (w)=0 we are in 8  bits mode(Win32)      100000dw    ADD REG,REG 
if (w)=1 we are in 32 bits mode(Win32)      100010dw    MOV REG,REG 
 
 
MORE ABOUT [CODE] : 
 
        ENCODING                      MEANING 
------------------------------+----------------------------+ 
000010dw  OR  REG,REG         ; or reg,reg                 ; 
00000101  imm32               ; add eax,imm32              ; 
000000dw  Mod,R/M,Reg         ; add reg,mem add mem,reg    ;  
001000dw  AND REG,REG         ; and reg,reg                ; 
001010dw  Mod,R/M,Reg         ; SUB reg,mem  SUB mem, reg  ;  
00101101  imm32               ; sub eax,imm32              ; 
001100dw  Mod,r/m,Reg data    ; xor reg,mem xor mem,reg    ; 
001110dw  CMP REG,REG         ; cmp reg,reg                ; 
01000reg                      ; inc reg32                  ; 
01001reg                      ; dec reg32                  ; 
01010reg  PUSH REG            ; push reg                   ; 
01011reg  POP  REG            ; pop reg                    ; 
1000000w  11101reg  data32    ; SUB reg, imm               ;  
1000000w  11000reg data32     ; add reg,imm                ;  
100010dw  MdRegReg  data32bit ; mov reg,reg/mem            ; 
10010reg  XCHG EAX,REG        ; xchg eax,reg               ; 
10111reg  data32bits          ; mov reg,imm32              ; 
11100010  imm16               ; loop imm16                 ; 
------------------------------+----------------------------+ 
 
                        ############################ 
                        #          [ModR/M]        # 
                        ############################ 
                                             
 
                         7   6 5      3 2     0       
                        +-----+--------+-------+ 
                        ; Mod ;  Reg/  ;  R/M  ; 
                        ;     ; opcode ;       ; 
                        +-----+--------+-------+ 
                        ; 0 0 ; 0 0 0  ; 0 0 0 ;  
                        +-----+--------+-------+ 
 
[Mod]        : 00   : mem address                     expl: eax, [eax]       
               01   : mem address with 1 byte displ.  expl: [eax+00]   
               10   : mem address with 1 dword displ. expl: [eax+00000000] 
               11   : both operands are memory        expl: eax,eax 
 
[Reg/opcode] : Code extension field or Reg fielf 
 
[R/M]        : Depending on the (Mode) Bits in the ModRM byte:  
 
  - [Mod]=00 [R/M]=101 : the address is in the DWORD after [ModR/M] Byte. 
  - [Mod]=00 [R/M]=100 : there’s a SIB byte after the [ModR/M] byte. 
  - [Mod]=01 [R/M]=100 : there’s a SIB byte after the [ModR/M] byte. 
  - [Mod]=10 [R/M]=100 : there’s a SIB byte after the [ModR/M] byte. 
  - [Mod]=11           : this field means --> registers  
 
 
========================================================================== 
========================================================================== 
 
 thanks to : Intel              to make polymorph instructions 
             Micro$oft Windows  Let's give us more n' more exe food for our baby! 
             29A menbers        For their zines!!!  VIVA 29A!!! 
 
 no thanks to : ME !!! for my bad english ;-) 
                All destructiv virus writers 
 
 
   I hope that this tutorial will help you but don't forget this: 
 
   DON'T DESTROY ANYTHING !!! 
 
   PEACE ! 
 
   LiTlLe VxW 
 
   December 2003