All pastes #809019 Raw Edit

Mine

public text v1 · immutable
·published 2007-12-08 03:52 UTC
rendered paste body
;
;=============================================================================
;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                                ;
                                                    ;