jumps .286 .model small .code org 100h start: sub sp, 4 pusha push ds push es call $+13 rIP1 dw offset pass_error rCS1 dw 0 rIP2 dw 100h rCS2 dw 0 rlcCnt dw 0 pop si push cs pop ax mov ds, ax mov es, ax mov di, ax sub di, word ptr cs:[si+6] ; mov word ptr cs:[si+6], di add di, word ptr cs:[si+2] mov ax, word ptr cs:[si] lea bp, cs:[si-9] mov ds:[bp+offset rpCS-100h], di mov ds:[bp+offset rpIP-100h], ax mov ah, 09h lea dx, ds:[bp+offset enter_pass-100h] int 21h ; Read password from stdin ;------------------------------- lea di, ds:[bp+offset pass-100h] mov cx, 20 chrloop:mov ah, 08h int 21h cmp al, 0Dh jz pass_end stosb mov ah, 02h mov dl, '*' int 21h dec cx jnz chrloop pass_end: mov ah, 09h lea dx, ds:[bp+offset newline-100h] int 21h sub cx, 20 neg cx mov ds:[bp+offset pass_len-100h], cx test cx, cx jz pass_error ;----------------------------------- ; Done ;Decode test string (to check password validity) and relocation table ;-------------------------------------------------------------------- lea di, ds:[bp+offset test_pass-100h] mov cx, 9 call decode ;---------- ;Done ;Check password validity ;------------------------------------ lea di, ds:[bp+offset test_pass-100h] mov cx, 10 xor ax, ax xor bx, bx loop_check: mov bl, [di] add al, bl inc di loop loop_check test al, al jnz pass_error ;------------- ; Password OK! ; Decode reloc table lea di, ds:[bp+offset reloc-100h] mov cx, ds:[si+8] bg_reloc_loop: cmp cx, 100 jb lst_reloc push cx mov cx, 399 push di call decode pop di call submagic call alignESDI pop cx sub cx, 100 jmp bg_reloc_loop lst_reloc: shl cx, 2 dec cx push di call decode pop di call submagic push cs pop es ;Start decoding program ;---------------------- mov cx, cs:[si+6] ; First, we need to calculate size of coded prog mov ax, cs:[si+4] mov bx, cx shr cx, 12 and bx, 0FFFh shl bx, 4 add bx, ax adc cx, 0 ; In cx:bx we got host size push cs pop ax sub ax, word ptr cs:[si+6] mov cs:[si+6], ax mov es, ax xor di, di ; In es:di we've got offset to prog begin ;First - decode full segments (0xFFFF length) seg_loop: test cx, cx jz resudary_part push cx xor cx, cx not cx call decode call submagic mov ax, es add ax, 1000h mov es, ax pop cx dec cx jmp seg_loop resudary_part: mov cx, bx dec cx call decode xor di, di call submagic ; Substitite relocation table ;---------------------------- push cs pop es mov cx, ds:[si+8] ; Relo item count mov bx, ds:[si+6] lea di, ds:[bp+offset reloc-100h] relowork: call alignESDI mov si, es:[di] mov ax, es:[di+2] add ax, bx mov ds, ax add word ptr ds:[si], bx add di, 4 loop relowork ;Normal return to parent proc ;---------------------------- push ss pop es push sp pop di mov ax, cs:[bp+offset rpIP-100h] mov es:[di+14h], ax mov ax, cs:[bp+offset rpCS-100h] mov es:[di+16h], ax pop es pop ds popa retf ;----------------------------- ; Done! ;--------------------------------- pass_error: mov ah, 09h lea dx, ds:[bp+offset bad_pass-100h] int 21h mov ax, 4CFFh int 21h ;------------------ ; es:di - what to decode ; cx - length decode proc near push si push ax push cx loops2: lea si, ds:[bp+offset pass-100h] cmp cx, ds:[bp+offset pass_len-100h] jb lasts2 push cx mov cx, ds:[bp+offset pass_len-100h] addmag2: mov al, ds:[si] xor es:[di], al inc si inc di loop addmag2 pop cx sub cx, ds:[bp+offset pass_len-100h] jmp loops2 lasts2: inc cx lasts3: mov al, ds:[si] xor es:[di], al inc si inc di loop lasts3 pop cx pop ax pop si ret endp submagic proc near push si push ax push cx loops: lea si, ds:[bp+offset test_pass-100h] cmp cx, 10 jb lasts push cx mov cx, 10 addmag: mov al, ds:[si] sub es:[di], al inc si inc di loop addmag pop cx sub cx, 10 jmp loops lasts: inc cx lasts0: mov al, ds:[si] sub es:[di], al inc si inc di loop lasts0 pop cx pop ax pop si ret endp ;------------------ alignESDI proc near push ax push cx mov ax, di shr ax, 4 mov cx, es add ax, cx mov es, ax and di, 0Fh pop cx pop ax ret endp ;---------------------- rpIP dw 0 rpCS dw 0 newline db 0dh, 0ah, '$' enter_pass db 'Please enter pass: $' bad_pass db 'Sorry, you''ve entred a bad password',0Dh,0Ah,'$' pass db 20 dup (0) pass_len dw 0 test_pass db 10, 12, 15, 17, -20, -13, 05, -30, 55, -51 reloc dd ? end start