Mine
public text v1 · immutable;
;=============================================================================
;LZ32Decompression subroutines.
;All rights may be reserved by SexyDufus
;Disassembled by IDA v3.xx with little help of Green Monster ;-)
;==============================================================================
;
;Interface:
;int lz_decompresss(char *inbuf, char *outbuf, int size, char *buf)
;
;-----------------------------------------------------------------------------
;Decompress data from inbuf, write output to outbuf.
;External buffer (buf) used for dictionary.
;Returns number of bytes placed in outbuf.
;=============================================================================
;
VarFrame struc ;
vf_Const01FF dw ? ;Mask (perverted)
vf_Const03FF dw ? ;Other one
vf_Const07FF dw ? ;Third
vf_Const0FFF dw ? ;Last
;
vf_Sym1 dw ? ;Symbols
vf_Sym2 dw ? ;
vf_Sym3 dw ? ;
;
vf_FreeSym dw ? ;Free symbol
vf_CharCount dw ? ;Character count
vf_DictSize dw ? ;Dictionary size
vf_BitSize dw ? ;Bits in char
vf_SimpleChar db ? ;Character
vf_CharToLink db ? ;explains itself
;
vf_InBufRelPos dw ? ;Position in the input buffer
field_1A dw ? ;
vf_OutBufPos dd ? ;Position in the output buffer
field_20 dw ? ;
field_22 dw ? ;
;Parameters
vf_InBuf dd ? ;char *inbuf
vf_OutBuf dd ? ;char *outbuf
vf_SuxxSize dd ? ;char *size (not used)
vf_Malloced dd ? ;char *buf (dictionary)
VarFrame ends ;
;
;=============================================================================
;Main subroutine
;=============================================================================
lz_decompress proc near ;
sub eax, eax ;
push eax ;Structure init
push eax ;
push 9 ;
push 2000000h ;
push 1020000h ;
push eax ;
push 0FFF07FFh ;Perverted masks
push 3FF01FFh ;
mov ebp, esp ;
;
get_next_sym: ;
call Get_Sym ;Get symbol
cmp ax, 101h ; 101h - end of data
jz lzd_exit ;
cmp ax, 100h ; 100h - dictionary reset
jnz short other_syms ;
;
call lzd_init ;Reset
;
call Get_Sym ;
mov [ebp+VarFrame.vf_Sym1], ax ;
mov [ebp+VarFrame.vf_Sym2], ax ;
mov [ebp+VarFrame.vf_CharToLink], al ;
mov [ebp+VarFrame.vf_SimpleChar], al ;
call Save_Char ;First symbol is always simple
jmp short get_next_sym ;
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
other_syms: ;
mov [ebp+VarFrame.vf_Sym1], ax ;
mov [ebp+VarFrame.vf_Sym3], ax ;
cmp ax, [ebp+VarFrame.vf_FreeSym] ;Symbol is already in
jl short already_in_dict ;dictionary?
;
movzx eax, [ebp+VarFrame.vf_Sym2] ;
mov [ebp+VarFrame.vf_Sym1], ax ;
movzx eax, [ebp+VarFrame.vf_SimpleChar]
push eax ;Leave it in stack
inc [ebp+VarFrame.vf_CharCount] ;
;
already_in_dict: ;
cmp [ebp+VarFrame.vf_Sym1], 0FFh ;
jle short one_time_again ;
; ;
movzx ebx, [ebp+VarFrame.vf_Sym1] ;
call _Calc_Sym_Pos ;
mov al, [ebx+2] ;
push eax ;Create chain in stack
inc [ebp+VarFrame.vf_CharCount] ;
movzx eax, word ptr [ebx] ;
mov [ebp+VarFrame.vf_Sym1], ax ;
jmp short already_in_dict ;
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
one_time_again: ;
movzx eax, [ebp+VarFrame.vf_Sym1] ;
mov [ebp+VarFrame.vf_SimpleChar], al ;
mov [ebp+VarFrame.vf_CharToLink], al ;
push eax ;
inc [ebp+VarFrame.vf_CharCount] ;
movzx ecx, [ebp+VarFrame.vf_CharCount] ;
jcxz no_chars ;
;
save_from_stack: ;Write chain from stack
pop eax ;
call Save_Char ;into output stream
loop save_from_stack ;
;
no_chars: ;
mov [ebp+VarFrame.vf_CharCount], cx ;
;
call Add_Chain ;
movzx eax, [ebp+VarFrame.vf_Sym3] ;
mov [ebp+VarFrame.vf_Sym2], ax ;
movzx ebx, [ebp+VarFrame.vf_FreeSym] ;
; ;
cmp bx, [ebp+VarFrame.vf_DictSize] ;
jl get_next_sym ;
; ;
;-------->replaced<----------------- ;
; cmp [ebp+VarFrame.vf_BitSize], 0Ch ;
cmp [ebp+VarFrame.vf_BitSize], MAX_BITS ;Check amount of bits
;-------->end<--------------------- ;
jz get_next_sym ;
;
inc [ebp+VarFrame.vf_BitSize] ;Increase it
shl [ebp+VarFrame.vf_DictSize], 1 ;And dictionary size
jmp get_next_sym ;
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
lzd_exit: ;
xchg eax, edi ;EAX = end-start = size
sub eax, [ebp+VarFrame.vf_OutBuf] ;
add esp, 20h ;
retn 10h ;
lz_decompress endp ;
;
;-----------------------------------------------------------------------------
;Calculate address of dictionary element from symbol nubmer
;-----------------------------------------------------------------------------
_Calc_Sym_Pos proc near ;
lea ebx, [ebx+ebx*2] ;EBX *= 3
add ebx, [ebp+VarFrame.vf_Malloced] ;
retn ;
_Calc_Sym_Pos endp ;
;
;-----------------------------------------------------------------------------
;Read symbol of variable size from the input stream
;-----------------------------------------------------------------------------
Get_Sym proc near ;
movzx eax, [ebp+VarFrame.vf_BitSize] ;
add eax, dword ptr [ebp+VarFrame.vf_InBufRelPos]
xchg eax, dword ptr [ebp+VarFrame.vf_InBufRelPos]
mov ecx, 8 ;
sub edx, edx ;
div ecx ; /8 (bits per byte)
add eax, [ebp+VarFrame.vf_InBuf] ;
xchg eax, esi ;
lodsw ;Load 3 bytes
movzx ebx, ax ;
lodsb ;
movzx ecx, dx ;
jcxz getsym_exit ;
;Select what we need
select_bits: ;
shr al, 1 ;
rcr bx, 1 ;
loop select_bits ;
;
getsym_exit: ;
movzx eax, bx ;
movzx ebx, [ebp+VarFrame.vf_BitSize] ;
;
;------------>replaced<--------------------------------- ;
; sub ebx, 9 ;
; and ax, [ebp+ebx*2+VarFrame.vf_Const01FF]
;
mov cl, bl ;
xor ebx, ebx ;
inc ebx ;
shl bx, cl ;
dec bx ;
and ax, bx ;
;
;------------>end<-------------------------------------- ;
;
retn ;
Get_Sym endp ;
;
;-----------------------------------------------------------------------------
;Dictionary reset
;-----------------------------------------------------------------------------
lzd_init proc near ;
mov [ebp+VarFrame.vf_BitSize], 9 ;Size in bits
mov [ebp+VarFrame.vf_DictSize], 200h ;Dictionary size
mov [ebp+VarFrame.vf_FreeSym], 102h ;First free symbol
retn ;
lzd_init endp ;
;
;-----------------------------------------------------------------------------
;Write char into output stream
;-----------------------------------------------------------------------------
Save_Char proc near ;
mov edi, [ebp+VarFrame.vf_OutBufPos] ;
add edi, [ebp+VarFrame.vf_OutBuf] ;
stosb ;
inc [ebp+VarFrame.vf_OutBufPos] ;
retn ;
Save_Char endp ;
;
;-----------------------------------------------------------------------------
;Write links into the dictionary
;-----------------------------------------------------------------------------
Add_Chain proc near ;
movzx ebx, [ebp+VarFrame.vf_FreeSym] ;
call _Calc_Sym_Pos ;
movzx eax, [ebp+VarFrame.vf_CharToLink] ;
mov [ebx+2], al ;
movzx eax, [ebp+VarFrame.vf_Sym2] ;
mov [ebx], ax ;
inc [ebp+VarFrame.vf_FreeSym] ;
retn ;
Add_Chain endp ;
;
;
;=============================================================================
;LZ32Compression subroutines.
;All rights may be reserved by SexyDufus [nah - SD;]
;Disassembled by IDA v3.xx with little help of Green Monster ;-)
;==============================================================================
;
;Interface:
;int lz_compresss(char *inbuf, char *outbuf, int size, char *buf)
;
;-----------------------------------------------------------------------------
;Compresses $size bytes from inbuf, writes output to outbuf.
;Uses external buffer (buf) to store dictionary
;Returns size of the compressed data
;=============================================================================
;
include lzcd.asi
;---------------------------------------------------
;Local variables structure (one for both subroutines)
ProcFrame struc ;
FirstSym dw ? ;First symbol
Link dw ? ;Link
DictBound dw ? ;Current dictionary limit
BitsPerSym dw ? ;Bits in the output element
;(increases as the dictionary
;becomes full)
;
NextInChar db ? ;Next char in the input stream
field_9 db ? ; something
field_A db ? ; other something
field_B db ? ; third one
;Resume: NextChar was DWORD ;-)
;
OutBufPos dd ? ;Current output pointer
InBufRelPos dd ? ;Current input pointer
RetEIP dd ? ;return address lz_compress
;
;Parameters:
InBuf dd ? ;Input buffer
OutBuf dd ? ;Output buffer
SuxxSize dd ? ;Size of data in the output buffer
Malloced dd ? ;Temporary buffer for dictionary
ProcFrame ends ;
;
;-------------------------------------------
;Dictionary record ;
; ;
TableItem struc ;
Sym dw ? ;Symbol
NextSym dw ? ;Next symbol
NextChar db ? ;Next character in the chain
TableItem ends ;
;
;=============================================================================
; Main function
;=============================================================================
lz_compress proc near ;
sub eax, eax ;
push eax ;All fielst in the structure are
push eax ;zeroed
push eax ;
push eax ;
push eax ;
mov ebp, esp ;EBP -> ProcFrame
;
call lz_init ;Dictionary Reset
; ;
sub eax, eax ;
inc ah ;Symbol 100h = "dictionary reset"
call Save_And_Step ;Dump it into the output
;
call Get_Byte ;Get first byte
;
@@compess_cycle: ;AL = character
sub ah, ah ;
;AX = symbol
@@get_chain: ;Searching for the unique string
;of characters
mov [ebp+ProcFrame.FirstSym], ax
call Get_Byte ;
jb short lzc_exit ;
;
mov [ebp+ProcFrame.NextInChar], al
movzx ebx, [ebp+ProcFrame.FirstSym]
call Search_Table ;
jnb short @@get_chain ;
;Chain found
call Set_Char_Link ;
;Dump symbol into the output
push ebx ;
movzx eax, [ebp+ProcFrame.FirstSym]
call Save_And_Step ;
pop ebx ;
mov al, [ebp+ProcFrame.NextInChar]
cmp bx, [ebp+ProcFrame.DictBound]
jl short @@compess_cycle
;
;--------->replaced<------------------------
; cmp [ebp+ProcFrame.BitsPerSym], 0Ch
cmp [ebp+ProcFrame.BitsPerSym], MAX_BITS
;Index bits limit
;--------->end<-----------------------------
jl short next_bit ;
;
sub eax, eax ;
inc ah ; 100h - dictionary reset
call Save_And_Step ;
call lz_init ; and reset it
mov al, [ebp+ProcFrame.NextInChar]
jmp short @@compess_cycle
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
next_bit: ;
inc [ebp+ProcFrame.BitsPerSym] ;Increase index
shl [ebp+ProcFrame.DictBound], 1 ;Increase dictionary
jmp short @@compess_cycle
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
lzc_exit: ;
movzx eax, [ebp+ProcFrame.FirstSym]
call Save_And_Step ;
mov eax, 101h ; 101h - end of chain
call Save_And_Step ;
xchg eax, edi ;
sub eax, [ebp+ProcFrame.OutBuf] ;EAX = end-start = size
add esp, 14h ;
retn 10h ;
lz_compress endp ;
;
;-----------------------------------------------------------------------------
;Dinctionary reset
;-----------------------------------------------------------------------------
lz_init proc near ;
pusha ;
mov [ebp+ProcFrame.BitsPerSym], 9
;9 bits ber each output symbol
mov [ebp+ProcFrame.DictBound], 200h
;512 symbols in the dictionary
sub eax, eax ;
dec eax ;
;REset dictionary
mov ecx, COMPR_BUFFER_SIZE/2
;
mov edi, [ebp+ProcFrame.Malloced]
repe stosw ;
;
mov [ebp+ProcFrame.Link], 102h ;First symbol
;
;(00-FF) - simpe symbols-characters
; (elementary dictionary)
; 100 - dictionary reset
; 101 - end of data
; 102-... - free symbols
;
popa ;
retn ;
lz_init endp ;
;
;------------------------------------------------------------------------------------
;Writes N bits (9-...) from the EAX to the output sream
;------------------------------------------------------------------------------------
Save_And_Step proc near ;
push eax ;
mov eax, [ebp+ProcFrame.OutBufPos]
;EAX -> bit int the output buffer
movzx ecx, word ptr [ebp.ProcFrame.BitsPerSym]
;ECX = how many bits to write
add [ebp+ProcFrame.OutBufPos], ecx
;Step
;Calculate the bit offset
mov ecx, 8 ;
sub edx, edx ;
div ecx ; EDX = OutBufPos mod 8
add eax, [ebp+ProcFrame.OutBuf]
xchg eax, edi ; EDI -> where to write
pop eax ;
;
mov ecx, edx ;
sub edx, edx ;
jcxz save_3bytes ; jump if on the byte's border
;
shl eax, cl ;
or al, [edi] ;
;
save_3bytes: ;
stosw ;
shr eax, 10h ;
stosb ;
retn ;
Save_And_Step endp ;
;
;-----------------------------------------------------------------------------
;Read character from the input sream in AL
;-----------------------------------------------------------------------------
Get_Byte proc near ;
mov esi, [ebp+ProcFrame.InBuf] ; ESI -> InBuf
mov edi, [ebp+ProcFrame.InBufRelPos] ; EDI -> RelInBufPos
cmp edi, [ebp+ProcFrame.SuxxSize] ; End already?
jnb short byaka ;
; ;
mov al, [esi+edi] ; Read
inc [ebp+ProcFrame.InBufRelPos] ;
clc ;
retn ;
byaka: ;
stc ;
retn ;
Get_Byte endp ;
;
;-----------------------------------------------------------------------------
;Dictionary search
;-----------------------------------------------------------------------------
Search_Table proc near
call Calc_Sym_Pos ;ESI -> TableItem
sub edi, edi ;EDI=0=success flag
cmp [esi+TableItem.Sym], 0FFFFh ;Do we have such symbol?
jz short not_found ;
;
inc edi ;set flag
movzx ebx, [esi+TableItem.Sym] ;EBX=symbol
;
scan_chain: ;
call Calc_Sym_Pos ;
cmp [esi+TableItem.NextChar], al ;Is link exists?
jnz short next_char ;
;
clc ;
movzx eax, bx ;EAX=chain symbol
retn ;
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
next_char: ;
cmp [esi+TableItem.NextSym], 0FFFFh ;End of the chain
jz short not_found ;
movzx ebx, [esi+TableItem.NextSym] ;EBX=next symbol
jmp short scan_chain ;
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
not_found: ;
stc ;No such chain
retn ;
Search_Table endp ;
;
;-----------------------------------------------------------------------------
;Calculate TableItem address in the dictionary using symbol in EBX
;-----------------------------------------------------------------------------
Calc_Sym_Pos proc near ;
lea esi, [ebx+ebx*4] ; ESI = EBX*sizeof(TableItem)
add esi, [ebp+ProcFrame.Malloced] ;ESI += buffer offset
retn ;
Calc_Sym_Pos endp ;
;
;-----------------------------------------------------------------------------
;Link character and symbol in the dictionary
;-----------------------------------------------------------------------------
Set_Char_Link proc near ;
movzx ebx, [ebp+ProcFrame.Link] ;
cmp edi, 0 ; EDI=Search_Table status
jz short set_link ;
mov [esi.TableItem.NextSym], bx ;
jmp short test_sym ;
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
set_link: ;
mov [esi.TableItem.Sym], bx ;Write symbol
;
test_sym: ;
;------>replaced<------ ;
; cmp bx, 1000h ;
cmp bx, BITS_DEPENDED_BUFF_SIZE ;Last symbol in the dictionary?
;------>end<----------- ;
jz short scl_exit ;
;
call Calc_Sym_Pos ; Mark as unused (FFFF)
mov word ptr [esi.TableItem.Sym], 0FFFFh
mov word ptr [esi.TableItem.NextSym], 0FFFFh
mov [esi.TableItem.NextChar], al
inc [ebp+ProcFrame.Link] ;
;
scl_exit: ;
retn ;
Set_Char_Link endp ;
;