471 lines
No EOL
8.7 KiB
NASM
471 lines
No EOL
8.7 KiB
NASM
NOJUMPS
|
|
|
|
calccrc MACRO start,end
|
|
local l1
|
|
mov cx,OFFSET end-OFFSET start
|
|
mov si,OFFSET start
|
|
l1: add dl,cs:[si]
|
|
adc dh,0
|
|
rol dx,1
|
|
inc si
|
|
loop l1
|
|
ENDM
|
|
uncryptxor MACRO beg,key
|
|
local l1
|
|
mov bx,OFFSET beg
|
|
mov ax,key
|
|
mov cx,(OFFSET _unpack_endcrypt-OFFSET beg)/2
|
|
l1: xor ds:[bx],ax
|
|
add bx,2
|
|
dec cx
|
|
jnz l1
|
|
ENDM
|
|
uncryptadd MACRO beg,key ;actually sub, uncrypts add-crypting
|
|
local l1
|
|
mov bx,OFFSET beg
|
|
mov ax,key
|
|
mov cx,(OFFSET _unpack_endcrypt-OFFSET beg)/2
|
|
l1: sub ds:[bx],ax
|
|
add bx,2
|
|
dec cx
|
|
jnz l1
|
|
ENDM
|
|
|
|
unp_text SEGMENT para public 'CODE'
|
|
ASSUME cs:unp_text
|
|
PUBLIC _unpack_start,_unpack_end
|
|
PUBLIC _unpack_data,_unpack_dataend,_unpack_data2,_unpack_code
|
|
PUBLIC _unpack_stack0,_unpack_stack1
|
|
PUBLIC _unpack_crc0,_unpack_crc1
|
|
PUBLIC _unpack_crypt1 ;add 5f27h - INC
|
|
PUBLIC _unpack_crypt2 ;xor 4493h - INC
|
|
PUBLIC _unpack_crypt3 ;add 0073h - INC
|
|
PUBLIC _unpack_crypt4 ;xor 4536h - none
|
|
PUBLIC _unpack_crypt10 ;xor 0666h - none
|
|
PUBLIC _unpack_crypt11 ;add 0656h - DEC
|
|
PUBLIC _unpack_crypt12 ;xor 0466h - DEC
|
|
PUBLIC _unpack_crypt13 ;add 0663h - none
|
|
PUBLIC _unpack_crypt14 ;add DX - none
|
|
PUBLIC _unpack_crypt15 ;xor 5cach - none
|
|
PUBLIC _unpack_crypt16 ;add 3fach - INC
|
|
PUBLIC _unpack_endcrypt
|
|
_unpack_start LABEL BYTE
|
|
|
|
db 'FCP/IV' ;Future Protector IV
|
|
|
|
_unpack_code LABEL BYTE
|
|
startup PROC NEAR
|
|
mov sp,OFFSET _unpack_stack1
|
|
io21data LABEL BYTE
|
|
ret
|
|
pntds2 LABEL WORd
|
|
jmp cs:[farjump+2]
|
|
startup ENDP
|
|
int_iret PROC FAR
|
|
iret
|
|
int_iret ENDP
|
|
|
|
ALIGN 2
|
|
_unpack_stack0 LABEL BYTE
|
|
dw 50 dup(5555h)
|
|
_unpack_stack1 LABEL BYTE
|
|
dw OFFSET step1
|
|
dw 0 ;popped by step 1 => DS
|
|
dw OFFSET step2
|
|
dw OFFSET step3
|
|
dw OFFSEt step4
|
|
stck1: dw OFFSET stepx1 ;the cracker blew it :-)
|
|
dw 0fff0h,0000h
|
|
disk0 dw 0
|
|
disk1 dw 0
|
|
vram dw 01234h
|
|
hboottxt db '.;*',13,0
|
|
pntds dw 0
|
|
|
|
_unpack_crc0 LABEL BYTE
|
|
|
|
.386P
|
|
step1 PROC NEAR
|
|
in al,21h
|
|
mov cs:io21data,al
|
|
mov al,255
|
|
out 21h,al
|
|
cli
|
|
mov cs:pntds,ds
|
|
pop ds
|
|
cld
|
|
;disk detect
|
|
mov ah,08h
|
|
mov dl,128
|
|
mov dh,0
|
|
int 13h
|
|
cmp dh,0
|
|
je jjj1
|
|
mov cs:disk0,cx
|
|
mov cs:disk1,dx
|
|
jjj1: ;video detect
|
|
mov ah,0fh
|
|
int 10h
|
|
cmp al,7
|
|
je ismda
|
|
mov cs:vram,0800h+1234h
|
|
ismda: add cs:vram,0b000h-01234h
|
|
;processor detect, at return: BP=0=real BP=1=protected mode
|
|
push sp ; 86/186 will push SP-2;
|
|
pop ax ; 286/386 will push SP.
|
|
cmp ax, sp
|
|
jz not86 ; If equal, SP was pushed
|
|
;8086/80186
|
|
noprot: mov bp,0
|
|
ret
|
|
not86: smsw cx ; Protected? Machine status -> CX
|
|
ror cx,1 ; Protection bit -> carry flag
|
|
jnc noprot ; Real mode if no carry
|
|
mov bp,1
|
|
ret
|
|
step1 ENDP
|
|
.8086
|
|
|
|
step3 PROC NEAR
|
|
;DS=CS now (in step 2)
|
|
;uncode crap
|
|
mov byte ptr cs:int1code,40h ;INC AX
|
|
int 3 ;clc set at step2's end
|
|
uncryptadd _unpack_crypt1,5f27h
|
|
ret
|
|
step3 ENDP
|
|
|
|
ints PROC FAR ;SingleStep/DEBUG
|
|
int_01: stc
|
|
int_03: push bp
|
|
mov bp,sp
|
|
jnc int2
|
|
push bx
|
|
mov bx,ss:[bp+2] ;ip
|
|
cmp byte ptr cs:[bx],49h ;inc cx
|
|
jne int1
|
|
int1code: inc bx
|
|
int1: pop bx
|
|
int3: pop bp
|
|
iret
|
|
int2: xor ss:[bp+6],256
|
|
mov bp,cs:stck1to
|
|
mov word ptr cs:[stck1],bp
|
|
jmp int3
|
|
ints000:
|
|
ints ENDP
|
|
|
|
_unpack_crc1 LABEL BYTE
|
|
|
|
itable LABEL WORD
|
|
itablelen equ 4
|
|
dw OFFSET int_iret,0f000h ;int 0
|
|
dw OFFSET int_01,0f000h ;int 1
|
|
dw OFFSET int_iret,0f000h ;int 2
|
|
dw OFFSET int_03,0f000h ;int 3
|
|
;Stack contents on ints:
|
|
; [bp+6]: flags
|
|
; [bp+4]: cs
|
|
; [bp+2]: ip
|
|
; [bp+0]: bp
|
|
|
|
_startzeroing LABEL BYTE
|
|
|
|
step2 PROC NEAR ;WARNING! ROUTINE OVERWRITTEN BY INNER STACK
|
|
mov cs:hboottxt[0],'b'
|
|
;set interrupts
|
|
mov bx,'FG'
|
|
mov si,OFFSET itable
|
|
xor di,di
|
|
mov cx,itablelen
|
|
mov dx,'JM'
|
|
mov cs:hboottxt[1],'C'
|
|
st2a: segcs
|
|
lodsw
|
|
xchg ds:[di],ax
|
|
mov cs:[si-2],ax
|
|
mov ax,cs
|
|
xchg ds:[di+2],ax
|
|
mov cs:[si],ax
|
|
add si,2
|
|
add di,4
|
|
loop st2a
|
|
;carry=0 for di won't rotate
|
|
mov di,dx ;='JM'
|
|
mov dx,OFFSET hboottxt
|
|
mov ax,cs
|
|
mov ds,ax
|
|
mov si,bx ;='FG' ;if this enabled, ICE will reboot
|
|
mov ax,0911h
|
|
ret
|
|
step2 ENDP
|
|
|
|
stepx1 PROC NEAR
|
|
mov ax,0f000h
|
|
retf ;reboots
|
|
stepx1 ENDP
|
|
|
|
_unpack_crypt1 LABEL BYTE
|
|
|
|
step4 PROC NEAR
|
|
;DS=CS
|
|
mov ax,cs:pntds
|
|
mov cs:pntds2,ax
|
|
uncryptxor _unpack_crypt2,4493h
|
|
_unpack_crypt2 LABEL BYTE
|
|
uncryptadd _unpack_crypt3,0073h
|
|
_unpack_crypt3 LABEL BYTE
|
|
jmp stp4o
|
|
stck1to dw OFFSET step5
|
|
hboottxt2 db 'Bc*',13,0
|
|
stp4o: sub ax,ax
|
|
mov si,'FG'
|
|
mov di,'JM'
|
|
mov ax,0911h
|
|
mov dx,OFFSET hboottxt2
|
|
clc
|
|
int 3
|
|
uncryptxor _unpack_crypt4,4536h
|
|
ret ;goes to step5
|
|
step4 ENDP
|
|
|
|
_unpack_crypt4 LABEL BYTE
|
|
|
|
innerstack LABEL BYTE
|
|
dw OFFSET stepx1
|
|
|
|
step5 PROC NEAR
|
|
;enter inner stack
|
|
mov sp,OFFSET innerstack
|
|
uncryptxor _unpack_crypt10,0666h
|
|
_unpack_crypt10 LABEL BYTE
|
|
i1c0: mov dx,0656h
|
|
sub ax,ax
|
|
mov es,ax
|
|
mov ax,es:[6]
|
|
mov bx,cs
|
|
cmp ax,bx
|
|
je i1c1
|
|
mov word ptr cs:[i1c0+1],0CA3Fh
|
|
mov dx,3FC1H
|
|
i1c1: cmp word ptr es:[4],OFFSET int_01
|
|
je i1c2
|
|
mov word ptr cs:[i1c0+1],0CA3Fh
|
|
mov dx,3CF2H
|
|
i1c2: mov byte ptr cs:int1code,48h ;DEC AX
|
|
sub ax,ax
|
|
int 3
|
|
uncryptadd _unpack_crypt11,dx
|
|
_unpack_crypt11 LABEL BYTE
|
|
uncryptxor _unpack_crypt12,0466h
|
|
_unpack_crypt12 LABEL BYTE
|
|
mov byte ptr cs:int1code,40h ;INC AX
|
|
sub ax,ax
|
|
int 3
|
|
uncryptadd _unpack_crypt13,0663h
|
|
_unpack_crypt13 LABEL BYTE
|
|
;calc checksum of exe start
|
|
xor dx,dx
|
|
mov byte ptr cs:int1code,43h ;INC BX
|
|
calccrc _unpack_crc0,_unpack_crc1
|
|
uncryptadd _unpack_crypt14,0 ;dx
|
|
_unpack_crypt14 LABEL BYTE
|
|
uncryptxor _unpack_crypt15,5CACh
|
|
_unpack_crypt15 LABEL BYTE
|
|
mov byte ptr cs:int1code,40h ;INC AX
|
|
sub ax,ax
|
|
int 3
|
|
uncryptadd _unpack_crypt16,3FACh
|
|
_unpack_crypt16 LABEL BYTE
|
|
mov word ptr cs:innerstack,OFFSET execute
|
|
sub ax,ax
|
|
int 3
|
|
ret
|
|
step5 ENDP
|
|
|
|
ALIGN 2
|
|
|
|
execute PROC NEAR
|
|
;unpack data
|
|
mov dx,cs:pntds2
|
|
add dx,10h
|
|
xor si,si
|
|
xor di,di
|
|
cmp cs:mcrcon,0
|
|
je exec11
|
|
;calc machine crc
|
|
mov ax,0ff00h
|
|
mov ds,ax
|
|
mov bx,0
|
|
mov cx,1024
|
|
mcrc1: add si,ds:[bx]
|
|
add di,ds:[bx+2]
|
|
rol si,1
|
|
add bx,4
|
|
loop mcrc1
|
|
add si,cs:disk0
|
|
add di,cs:disk1
|
|
exec11: add si,cs:regcs
|
|
add di,cs:regip
|
|
add si,cs:regsp
|
|
add di,cs:regss
|
|
add si,cs:regkey
|
|
add di,cs:regkey
|
|
mov cx,cs:regcs0
|
|
exec1: mov ds,dx
|
|
sub ds:[0],si
|
|
sub ds:[2],di
|
|
xor si,5354h
|
|
xor di,1525h
|
|
sub ds:[4],si
|
|
sub ds:[6],di
|
|
add si,1234h
|
|
ror si,1
|
|
add di,4321h
|
|
rol di,1
|
|
sub ds:[8],si
|
|
sub ds:[10],di
|
|
xor si,5354h
|
|
xor di,1525h
|
|
sub ds:[12],si
|
|
sub ds:[14],di
|
|
add si,1234h
|
|
ror si,1
|
|
add di,4321h
|
|
rol di,1
|
|
inc dx
|
|
add si,ds:[0]
|
|
add di,ds:[8]
|
|
add si,ds:[2]
|
|
add di,ds:[10]
|
|
add si,ds:[4]
|
|
add di,ds:[12]
|
|
add si,ds:[6]
|
|
add di,ds:[14]
|
|
loop exec1
|
|
mov bp,OFFSET errormsg1
|
|
cmp si,cs:keychk0
|
|
jne error
|
|
cmp di,cs:keychk1
|
|
jne error
|
|
cld
|
|
_endzeroing LABEL BYTE ;may overflow a byte, but who cares
|
|
mov dx,cs:pntds2
|
|
mov ax,cs
|
|
mov es,ax
|
|
mov cx,(OFFSET _endzeroing-OFFSET _startzeroing+1)/2
|
|
mov di,OFFSET _startzeroing
|
|
mov ax,'..'
|
|
rep stosw
|
|
call resetints
|
|
mov al,cs:io21data
|
|
out 21h,al
|
|
mov ax,cs
|
|
mov es,ax
|
|
mov cx,OFFSET _startzeroing-OFFSET _unpack_code
|
|
mov di,OFFSET _unpack_code
|
|
mov al,'.'
|
|
rep stosb
|
|
;load stack and cs:ip for the actual program and run it.
|
|
mov ds,dx
|
|
mov es,dx
|
|
mov bx,cs
|
|
mov cx,cs:regcs0
|
|
mov ax,cs:regss
|
|
add ax,bx
|
|
sub ax,cx
|
|
mov ss,ax
|
|
mov sp,cs:regsp
|
|
add cs:regcs,bx
|
|
sub cs:regcs,cx
|
|
push cs:regcs
|
|
push cs:regip
|
|
mov cs:regcs,ax
|
|
mov cs:regip,ax
|
|
mov cs:regss,ax
|
|
mov cs:regcs0,ax
|
|
mov cs:keychk1,ax
|
|
mov cs:regkey,ax
|
|
sti
|
|
jmp endprg2
|
|
|
|
_endzeroing2 LABEL BYTE
|
|
error: ;destroy and exit with error at OFFSET BP
|
|
cld
|
|
mov dx,cs:pntds2
|
|
mov ax,cs
|
|
mov es,ax
|
|
mov cx,(OFFSET _endzeroing2-OFFSET _startzeroing+1)/2
|
|
mov di,OFFSET _startzeroing
|
|
mov ax,'..'
|
|
rep stosw
|
|
call resetints
|
|
mov al,cs:io21data
|
|
out 21h,al
|
|
mov ax,cs
|
|
mov es,ax
|
|
mov di,OFFSET _unpack_code
|
|
mov cx,OFFSET _startzeroing-OFFSET _unpack_code
|
|
mov al,'.'
|
|
rep stosb
|
|
mov cs:regcs,ax
|
|
mov cs:regip,ax
|
|
mov cs:regss,ax
|
|
mov cs:regcs0,ax
|
|
mov cs:keychk1,ax
|
|
mov cs:regkey,ax
|
|
mov sp,OFFSET _unpack_data
|
|
sti
|
|
jmp endprg1
|
|
execute ENDP
|
|
|
|
resetints PROC NEAR
|
|
;reset interrupts
|
|
xor ax,ax
|
|
mov es,ax
|
|
mov si,OFFSET itable
|
|
xor di,di
|
|
mov cx,itablelen*2
|
|
st20a: segcs
|
|
lodsw
|
|
stosw
|
|
loop st20a
|
|
ret
|
|
resetints ENDP
|
|
|
|
ALIGN 2
|
|
_unpack_data LABEL BYTE
|
|
farjump LABEL DWORD
|
|
regcs dw 0
|
|
regip dw 0
|
|
regss dw 0
|
|
regsp dw 0
|
|
regcs0 dw 0
|
|
errormsg1 db 'File corrupted!$'
|
|
_unpack_data2 LABEL BYTE
|
|
regkey dw 0
|
|
mcrcon dw 0 ;1=machine crc enabled
|
|
keychk0 dw 0
|
|
keychk1 dw 0
|
|
_unpack_dataend LABEL BYTE
|
|
|
|
ALIGN 2
|
|
|
|
endprg1: ;****************
|
|
mov dx,bp
|
|
mov ax,cs
|
|
mov ds,ax
|
|
mov ah,9h
|
|
int 21h
|
|
mov ax,4c03h
|
|
int 21h
|
|
endprg2: ;****************
|
|
retf
|
|
|
|
ALIGN 2
|
|
_unpack_endcrypt LABEL BYTE
|
|
db 000h,0fch
|
|
_unpack_end LABEL BYTE
|
|
unp_text ENDS
|
|
END
|
|
|