Copy Link
Add to Bookmark
Report
29A Issue 03 03 08
;=====================================;
; S T R C ;
;-------------------------------------;
; Super Tiny Reloc Compressor ;
;=====================================;
; Made by Super/29A ;
;=====================================;
Pushd equ 4
Pushad_edi equ 00h
Pushad_esi equ 04h
Pushad_ebp equ 08h
Pushad_esp equ 0ch
Pushad_ebx equ 10h
Pushad_edx equ 14h
Pushad_ecx equ 18h
Pushad_eax equ 1ch
;-----------------------------------------------------------;
; Routine "STRC_max_compress"
;
; Tries different methods and compresses with the best ratio.
;
; INPUT:
; ESI = offset of start of reloc section
; EDI = buffer to store the compressed reloc data
; ECX = number of *bytes* of reloc section (not aligned)
;
; OUTPUT:
; BL = selected method of compression
; (number of bits to encode relative offset)
; ECX = number of *bits* of compressed reloc data
;-----------------------------------------------------------;
STRC_max_compress proc near
push eax
stc
sbb eax,eax ;eax=-1
mov bl,0eh ;try with 14 bits
@@1:
inc ebx
push ecx
call STRC_compress ;compress it
cmp ecx,eax ;this method better?
jnb @@2 ;jump if not
xchg ecx,eax
dec ebx
dec ebx ;go for next method
@@2:
pop ecx
jnz @@1 ;try again if we havent found the perfect method
xchg ecx,eax
pop eax
ret
STRC_max_compress endp
;-----------------------------------------------------------;
; Routine "STRC_compress"
;
; Compresses the reloc section.
;
; INPUT:
; BL = method of compression
; (number of bits to encode relative offset)
; ESI = offset of start of reloc section
; EDI = buffer to store the compressed reloc data
; ECX = number of *bytes* of reloc section (not aligned)
;
; OUTPUT:
; ECX = number of *bits* of compressed reloc data
;-----------------------------------------------------------;
STRC_compress proc near
add ecx,esi ;ecx=end of input buffer
pushad
xor ebp,ebp
xor ebx,ebx ;bit count
@@1:
lodsd
xchg edx,eax ;edx=virtual address
lodsd
lea ecx,[eax-8] ;ecx=size of this block
@@2:
push ecx
push edx
lodsw
sub ah,40h
jnb @@6 ;jump if invalid relocation
add ah,10h
jnb @@6 ;jump if invalid relocation
cwde
add eax,edx ;add the virtual address of actual page
sub eax,ebp ;calculate relative address
add ebp,eax ;update last virtual address
push ebx
db 0fh,0bdh,0d8h ; bsr ebx,eax ;calculate number of bits taken
movzx ecx,byte ptr [esp+(Pushd*3)+Pushad_ebx] ;cl=bits chosen for this method
cmp bl,cl ;we need more bits to store it?
jb @@3 ;nope
shld edx,eax,cl ;
shl eax,cl ;
shr ebx,3 ;
or al,bl ; insert number of bytes needed to store it
lea ecx,[ecx+(ebx*8)+8] ;
@@3:
pop ebx
@@4:
btr [edi],ebx ;
shr edx,1 ;
rcr eax,1 ;
jnb @@5 ;
bts [edi],ebx ; store information bit by bit
@@5: ;
inc ebx ;
loop @@4 ;
@@6:
pop edx
pop ecx
dec ecx
loop @@2 ;next word of actual block
cmp esi,[esp+Pushad_ecx] ;have we processed all blocks?
jb @@1 ;nope
STRC_exit:
mov [esp+Pushad_ecx],ebx ;return number of bits of compressed data
popad
ret
STRC_compress endp
;-----------------------------------------------------------;
; Routine "STRC_decompress"
;
; Decompresses the reloc section.
;
; INPUT:
; BL = method of compression
; (number of bits to encode relative offset)
; ESI = offset of compressed reloc data
; EDI = buffer to store the reloc section
; ECX = number of *bits* of compressed reloc data
;
; OUTPUT:
; ECX = number of *bytes* of decompressed reloc section
;-----------------------------------------------------------;
STRC_decompress proc near
pushad
xor ebp,ebp
xor ebx,ebx
@@1:
cmp ebx,ecx ;have we finished?
jnb @@7 ;nope
push ecx
movzx ecx,byte ptr [esp+(Pushd*1)+Pushad_ebx] ;cl=bits chosen for this method
@@2:
xor eax,eax
push ecx
@@3:
bt [esi],ebx ;
rcr eax,1 ;
inc ebx ; get relative offset
loop @@3 ;
pop ecx ;
rol eax,cl ;
lea ecx,[(eax*8)+8] ;ax=0--> 8 bits
;ax=1--> 16 bits
;ax=2--> 24 bits
;ax=3--> 32 bits
cmp eax,4 ;do we need to read more bits to get the whole relative offset
jb @@2 ;yes
pop ecx
add eax,ebp
dec ebp
mov ebp,eax ;update last virtual address
jns @@5 ;jump if this is not the first time
@@4:
mov eax,ebp
and eax,-1000h
stosd ;store start virtual address of this page
xor eax,eax
mov al,8
mov edx,edi
stosd ;store size of this block
@@5:
mov eax,ebp
sub eax,[edx-4]
cmp eax,1000h
jnb @@7 ;jump if we are in next page
sub ah,-30h ;make it of type 3 :-)
@@6:
stosw ;store relocation
inc dword ptr [edx] ;
inc dword ptr [edx] ; increment block size by two
jb @@1
@@7:
xor eax,eax
test byte ptr [edx],2
jnz @@6 ;align this block if necesary
cmp ebx,ecx ;finished?
jb @@4 ;nope
mov ebx,edi
sub ebx,[esp] ;calculate size of decompressed data
jmp STRC_exit
STRC_decompress endp
;-------------------------------------------------------------------
ends
end start