SecondReality/FCP/UNPACK.ASM
2017-09-24 01:45:36 +02:00

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