mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-15 15:29:23 +00:00
Folder structure change, added README
This commit is contained in:
@@ -0,0 +1,416 @@
|
||||
; ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
|
||||
; ÚÄ Benny's Compression Engine for Win32 Ä¿ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
|
||||
; ³ by ³ ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
|
||||
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄ Benny / 29A ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
|
||||
; ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
|
||||
;
|
||||
;
|
||||
;
|
||||
;Hello everybody,
|
||||
;
|
||||
;let me introduce my second compression engine for Win32 enviroment (u can
|
||||
;find my first engine in Win32.Benny and Win98.Milennium). This engine
|
||||
;worx on "compressin' bit groups" base. When I started to write this stuff,
|
||||
;i wanted to write engine, that would work on Huffmann base. Then I decided
|
||||
;it's not needed to implement this complicated algorithm here, coz I wanna
|
||||
;be this engine small and effective.
|
||||
;
|
||||
;Not only this is truth. This engine is very fast, very small (only 478 bytes)
|
||||
;and has implemented my special compression algorithm, that is simple and has
|
||||
;very, ehrm, let's call it "interesting" compression ratio X-D.
|
||||
;
|
||||
;
|
||||
;
|
||||
;So how does it work ?
|
||||
;======================
|
||||
;
|
||||
;I said, this engine worx on "compressin' bit groups" base. What does it mean ?
|
||||
;Bit group (as I call it) is group of two bits. U know, every byte has 8 bits.
|
||||
;
|
||||
;Example: byte 9Ah group0 group1 group2 group3
|
||||
; 10011010 ===> 10 10 01 10
|
||||
;
|
||||
;As u can see, every byte has 4 bit groups and I said, it compresses
|
||||
;bit groups. Heh, u think i'm crazy when im tryin' to compress
|
||||
;two bits, yeah :?)
|
||||
;
|
||||
;
|
||||
;This engine will (on the beginnin') calculate, which bit group has
|
||||
;the biggest count of repetency, which second biggest, etc...
|
||||
;
|
||||
;Example: group count
|
||||
; 00 ===> 74
|
||||
; 01 ===> 32
|
||||
; 10 ===> 12
|
||||
; 11 ===> 26
|
||||
;
|
||||
;
|
||||
;That's not all. It has to sort items to know, which group has the biggest
|
||||
;count. I decided it's best to use "bubble sort algorithm". Then there isn't
|
||||
;any problem to use "our algorithm".
|
||||
|
||||
;Look at this table, when in first column r sorted groups and in second
|
||||
;comlumn r <another> bits, which will represent new compressed data.
|
||||
;
|
||||
;Sorted by count: 1. ===> 1
|
||||
; 2. ===> 00
|
||||
; 3. ===> 010
|
||||
; 4. ===> 011
|
||||
;
|
||||
;Finally, engine will replace bit groups with these bits.
|
||||
;Gewd thing on this algorithm is that there aren't needed same bytes to have
|
||||
;good compression ratio, but only some bits.
|
||||
;So now u know whole secret of my compression algorithm. U also know, why
|
||||
;I said, it has "interesting compression ratio". Look at the table and u will
|
||||
;see, what type of files can we strongly compress. They r both of binaries
|
||||
;and texts, but not every binaries or texts can be compressed as well as otherz.
|
||||
;We can compress some binaries again with the same or better ratio. Why ?
|
||||
;Imagine, u have file with 1000x 0x0s. After compression we have 125x 0xFFs, that
|
||||
;can be compressed again. Some files can be after compression (negative even -
|
||||
;file is bigger) compressed again with positive compression (file is smaller).
|
||||
;Heh, crazy, isn't it ? X-DDD.
|
||||
;
|
||||
;
|
||||
;
|
||||
;How can I use BCE32 in my virus ?
|
||||
;==================================
|
||||
;
|
||||
;BCE32 is placed in two procedures called BCE32_Compress and BCE32_Decompress.
|
||||
;
|
||||
;
|
||||
;a) BCE32_Compress:
|
||||
;-------------------
|
||||
;Input state:
|
||||
; 1) ESI register - pointer to data, which will be compressed
|
||||
; 2) EDI register - pointer to memory, where will be placed compressed data
|
||||
; 3) ECX register - number of bytes to compress + 1 (do not forget "+ 1" !)
|
||||
; 4) EBX register - work memory (16 bytes)
|
||||
; 5) EDX register - work memory (16 bytes). MUST NOT be same as EBX !
|
||||
;
|
||||
; call BCE32_Compress
|
||||
;
|
||||
;Output state:
|
||||
; 1) EAX register - new size of compressed data
|
||||
; 2) CF set, if negative compression
|
||||
; 3) Other registers r preserved (except FLAGS)
|
||||
;
|
||||
;
|
||||
;b) BCE32_Decompress:
|
||||
;---------------------
|
||||
;Input state:
|
||||
; 1) ESI register - pointer to compressed data
|
||||
; 2) EDI register - pointer to memory, where will be placed decompressed data
|
||||
; 3) ECX register - number of bytes to decompress (EAX value returned by
|
||||
; BCE32_Compress) - 1 (do not forget "- 1" !)
|
||||
;
|
||||
; call BCE32_Decompress
|
||||
;
|
||||
;Output state:
|
||||
; 1) All registers r preserved
|
||||
;
|
||||
;
|
||||
;WARNING: Be sure, u have enought memory for case of negative compression.
|
||||
;NOTE: U can compress (in some special cases) already compressed data.
|
||||
; For this purpose exists output parameters EAX and CF.
|
||||
;
|
||||
;
|
||||
;
|
||||
;Do u like this (or my another work) ?
|
||||
;======================================
|
||||
;
|
||||
;Gimme know. If u have some notes or commentz for this, for another work,
|
||||
;or if u simply like it, mail me to benny@post.cz. Thanx.
|
||||
;
|
||||
;
|
||||
;
|
||||
;Don't u like it ?
|
||||
;==================
|
||||
;
|
||||
;Fuck u.
|
||||
;
|
||||
;
|
||||
;
|
||||
;(c) by Benny/29A May 1999.
|
||||
|
||||
|
||||
|
||||
|
||||
BCE32_Compress Proc ;compression procedure
|
||||
pushad ;save all regs
|
||||
|
||||
;stage 1
|
||||
pushad ;and again
|
||||
create_table:
|
||||
push ecx ;save for l8r usage
|
||||
push 4
|
||||
pop ecx ;ECX = 4
|
||||
lodsb ;load byte to AL
|
||||
l_table:push eax ;save it
|
||||
xor edx, edx ;EDX = 0
|
||||
and al, 3 ;this stuff will separate and test
|
||||
je st_end ;bit groups
|
||||
cmp al, 2
|
||||
je st2
|
||||
cmp al, 3
|
||||
je st3
|
||||
st1: inc edx ;01
|
||||
jmp st_end
|
||||
st2: inc edx ;10
|
||||
inc edx
|
||||
jmp st_end
|
||||
st3: mov dl, 3 ;11
|
||||
st_end: inc dword ptr [ebx+4*edx] ;increment count in table
|
||||
pop eax
|
||||
ror al, 2 ;next bit group
|
||||
loop l_table
|
||||
pop ecx ;restore number of bytes
|
||||
loop create_table ;next byte
|
||||
|
||||
push 4 ;this will check for same numbers
|
||||
pop ecx ;ECX = 4
|
||||
re_t: cdq ;EDX = 0
|
||||
t_loop: mov eax, [ebx+4*edx] ;load DWORD
|
||||
inc dword ptr [ebx+4*edx] ;increment it
|
||||
cmp eax, [ebx] ;test for same numbers
|
||||
je _inc_ ;...
|
||||
cmp eax, [ebx+4] ;...
|
||||
je _inc_ ;...
|
||||
cmp eax, [ebx+8] ;...
|
||||
je _inc_ ;...
|
||||
cmp eax, [ebx+12] ;...
|
||||
jne ninc_ ;...
|
||||
_inc_: inc dword ptr [ebx+4*edx] ;same, increment it
|
||||
inc ecx ;increment counter (check it in next turn)
|
||||
ninc_: cmp dl, 3 ;table overflow ?
|
||||
je re_t ;yeah, once again
|
||||
inc edx ;increment offset to table
|
||||
loop t_loop ;loop
|
||||
popad ;restore regs
|
||||
|
||||
;stage 2
|
||||
pushad ;save all regs
|
||||
mov esi, ebx ;get pointer to table
|
||||
push 3
|
||||
pop ebx ;EBX = 3
|
||||
mov ecx, ebx ;ECX = 3
|
||||
rep_sort: ;bubble sort = the biggest value will
|
||||
;always "bubble up", so we know number
|
||||
;steps
|
||||
push ecx ;save it
|
||||
mov ecx, ebx ;set pointerz
|
||||
mov edi, edx ;...
|
||||
push edx ;save it
|
||||
lodsd ;load DWORD (count)
|
||||
mov edx, eax ;save it
|
||||
sort: lodsd ;load next
|
||||
cmp eax, edx ;is it bigger
|
||||
jb noswap ;no, store it
|
||||
xchg eax, edx ;yeah, swap DWORDs
|
||||
noswap: stosd ;store it
|
||||
loop sort ;next DWORD
|
||||
mov eax, edx ;biggest in EDX, swap it
|
||||
stosd ;and store
|
||||
lea esi, [edi-16] ;get back pointer
|
||||
pop edx ;restore regs
|
||||
pop ecx
|
||||
loop rep_sort ;and try next DWORD
|
||||
popad
|
||||
|
||||
;stage 3
|
||||
pushad ;save all regs
|
||||
xor eax, eax ;EAX = 0
|
||||
push eax ;save it
|
||||
push 4
|
||||
pop ecx ;ECX = 4
|
||||
n_search:
|
||||
push edx ;save regs
|
||||
push ecx
|
||||
lea esi, [ebx+4*eax] ;get pointer to table
|
||||
push eax ;store reg
|
||||
lodsd ;load DWORD to EAX
|
||||
push 3
|
||||
pop ecx ;ECX = 3
|
||||
mov edi, ecx ;set pointerz
|
||||
search: mov esi, edx
|
||||
push eax ;save it
|
||||
lodsd ;load next
|
||||
mov ebp, eax
|
||||
pop eax
|
||||
cmp eax, ebp ;end ?
|
||||
je end_search
|
||||
dec edi ;next search
|
||||
add edx, 4
|
||||
loop search
|
||||
end_search:
|
||||
pop eax ;and next step
|
||||
inc eax
|
||||
pop ecx
|
||||
pop edx
|
||||
add [esp], edi
|
||||
rol byte ptr [esp], 2
|
||||
loop n_search
|
||||
pop [esp.Pushad_ebx] ;restore all
|
||||
popad ;...
|
||||
|
||||
;stage 4
|
||||
xor ebp, ebp ;EBP = 0
|
||||
xor edx, edx ;EDX = 0
|
||||
mov [edi], bl ;store decryption key
|
||||
inc edi ;increment pointer
|
||||
next_byte:
|
||||
xor eax, eax ;EAX = 0
|
||||
push ecx
|
||||
lodsb ;load next byte
|
||||
push 4
|
||||
pop ecx ;ECX = 4
|
||||
next_bits:
|
||||
push ecx ;store regs
|
||||
push eax
|
||||
and al, 3 ;separate bit group
|
||||
|
||||
push ebx ;compare with next group
|
||||
and bl, 3
|
||||
cmp al, bl
|
||||
pop ebx
|
||||
je cb0
|
||||
|
||||
push ebx ;compare with next group
|
||||
ror bl, 2
|
||||
and bl, 3
|
||||
cmp al, bl
|
||||
pop ebx
|
||||
je cb1
|
||||
|
||||
push ebx ;compare with next group
|
||||
ror bl, 4
|
||||
and bl, 3
|
||||
cmp al, bl
|
||||
pop ebx
|
||||
je cb2
|
||||
|
||||
push 0 ;store bit 0
|
||||
call copy_bit
|
||||
push 1 ;store bit 1
|
||||
call copy_bit
|
||||
cb0: push 1 ;store bit 1
|
||||
end_cb1:call copy_bit
|
||||
pop eax
|
||||
pop ecx
|
||||
ror al, 2
|
||||
loop next_bits ;next bit
|
||||
pop ecx
|
||||
loop next_byte ;next byte
|
||||
mov eax, edi ;save new size
|
||||
sub eax, [esp.Pushad_edi] ;...
|
||||
mov [esp.Pushad_eax], eax ;...
|
||||
popad ;restore all regs
|
||||
cmp eax, ecx ;test for negative compression
|
||||
jb c_ok ;positive compression
|
||||
stc ;clear flag
|
||||
ret ;and quit
|
||||
c_ok: clc ;negative compression, set flag
|
||||
ret ;and quit
|
||||
cb1: push 0 ;store bit 0
|
||||
end_cb2:call copy_bit
|
||||
push 0 ;store bit 0
|
||||
jmp end_cb1
|
||||
cb2: push 0 ;store bit 0
|
||||
call copy_bit
|
||||
push 1 ;store bit 1
|
||||
jmp end_cb2
|
||||
copy_bit:
|
||||
mov eax, ebp ;get byte from EBP
|
||||
shl al, 1 ;make space for next bit
|
||||
or al, [esp+4] ;set bit
|
||||
cbit: inc edx ;increment counter
|
||||
cmp dl, 8 ;byte full ?
|
||||
jne n_byte ;no, continue
|
||||
stosb ;yeah, store byte
|
||||
xor eax, eax ;and prepare next one
|
||||
cdq ;...
|
||||
n_byte: mov ebp, eax ;save back byte
|
||||
ret Pshd ;quit from procedure with one parameter on stack
|
||||
db '[BCE32]', 0 ;little signature
|
||||
BCE32_Compress EndP ;end of compression procedure
|
||||
|
||||
|
||||
|
||||
BCE32_Decompress Proc ;decompression procedure
|
||||
pushad ;save all regs
|
||||
xor eax, eax ;EAX = 0
|
||||
xor ebp, ebp ;EBP = 0
|
||||
cdq ;EDX = 0
|
||||
|
||||
lodsb ;load decryption key
|
||||
push eax ;store it
|
||||
lodsb ;load first byte
|
||||
push 8 ;store 8
|
||||
push edx ;store 0
|
||||
d_bits: push ecx ;store ECX
|
||||
|
||||
test al, 80h ;test for 1
|
||||
jne db0
|
||||
test al, 0c0h ;test for 00
|
||||
je db1
|
||||
test al, 0a0h ;test for 010
|
||||
je db2
|
||||
mov cl, 6 ;its 011
|
||||
jmp tb2
|
||||
|
||||
testb: test bl, 1 ;is it 1 ?
|
||||
jne p1
|
||||
push 0 ;no, store 0
|
||||
_tb_: mov eax, ebp ;load byte to EAX
|
||||
or al, [esp] ;set bit
|
||||
ror al, 1 ;and make space for next one
|
||||
call cbit ;end of procedure
|
||||
ret ;...
|
||||
p1: push 1 ;store 1
|
||||
jmp _tb_ ;and continue
|
||||
|
||||
db0: xor cl, cl ;CL = 0
|
||||
mov byte ptr [esp+4], 1 ;store 1
|
||||
testbits:
|
||||
push eax ;store it
|
||||
push ebx ;...
|
||||
mov ebx, [esp+20] ;load parameter
|
||||
ror bl, cl ;shift to next bit group
|
||||
call testb ;test bit
|
||||
ror bl, 1 ;next bit
|
||||
call testb ;test it
|
||||
pop ebx ;restore regs
|
||||
pop eax
|
||||
|
||||
mov ecx, [esp+4] ;load parameter
|
||||
bcopy: cmp byte ptr [esp+8], 8 ;8. bit ?
|
||||
jne dnlb ;nope, continue
|
||||
mov ebx, eax ;load next byte
|
||||
lodsb
|
||||
xchg eax, ebx
|
||||
mov byte ptr [esp+8], 0 ;and nulify parameter
|
||||
dec dword ptr [esp] ;decrement parameter
|
||||
dnlb: shl al, 1 ;next bit
|
||||
test bl, 80h ;is it 1 ?
|
||||
je nb ;no, continue
|
||||
or al, 1 ;yeah, set bit
|
||||
nb: rol bl, 1 ;next bit
|
||||
inc byte ptr [esp+8] ;increment parameter
|
||||
loop bcopy ;and align next bits
|
||||
pop ecx ;restore ECX
|
||||
inc ecx ;test flags
|
||||
dec ecx ;...
|
||||
jns d_bits ;if not sign, jump
|
||||
|
||||
pop eax ;delete pushed parameters
|
||||
pop eax ;...
|
||||
pop eax ;...
|
||||
popad ;restore all regs
|
||||
ret ;and quit
|
||||
|
||||
db1: mov cl, 2 ;2. bit in decryption key
|
||||
mov [esp+4], cl ;2 bit wide
|
||||
jmp testbits ;test bits
|
||||
db2: mov cl, 4 ;4. bit
|
||||
tb2: mov byte ptr [esp+4], 3 ;3 bit wide
|
||||
jmp testbits ;test bits
|
||||
BCE32_Decompress EndP ;end of decompression procedure
|
||||
Binary file not shown.
@@ -0,0 +1,198 @@
|
||||
|
||||
; BNCE - BlueOwls Nibble Compression Engine
|
||||
; *****************************************
|
||||
;
|
||||
; Introduction
|
||||
; ************
|
||||
;
|
||||
; I made this engine for virusses which want to use some algorithm to make
|
||||
; themselves or something else smaller (obviously), but i wanted the
|
||||
; algorithm to be small too, because if it isn't it would have little use
|
||||
; for virusses. In this case, I tried to make the decompressor as small as
|
||||
; possible, and let the compressor do most of the work.
|
||||
;
|
||||
; How it works
|
||||
; ************
|
||||
;
|
||||
; Every byte has 4 nibbles and these can be compressed. The compression is
|
||||
; done by counting the number of nibbles in the entire data and change
|
||||
; the nibble sizes accordingly. The most common of the four possible
|
||||
; nibbles will be compressed, #2 will stay the same size and #3 & #4 will
|
||||
; be expanded. This means that as long as the number #1s > the numbers
|
||||
; #3+#4 compression occurs, otherwise the data will be expanded. The
|
||||
; maximum reducement is 50%, and the maximum enlargement is 112,5%.
|
||||
;
|
||||
; Notes
|
||||
; *****
|
||||
;
|
||||
; - The bnce_compress and bnce_decompress are not in any way dependent on
|
||||
; each other, and both do not use any (external) data, you can run them
|
||||
; without the write flag set.
|
||||
; - A small optimization is possible for the decryptor if you like to
|
||||
; decrypt only one thing with a static size with it; remove the (*)
|
||||
; lines in the compressor and change the (@) lines in mov ecx, size;
|
||||
; or push size, pop ecx. It will save one or three bytes in the
|
||||
; decompressor, wow! :P
|
||||
; - I have not encounterd any bugs, and the only errors could arrise from
|
||||
; a faulty parameters; too small output buffers or corrupted compressed
|
||||
; data fed to the decompressor. All which are not very likely.
|
||||
; - In some extreme cases, already compressed data can be compressed again
|
||||
; but this is only possible when the are a lot of same nibble repeaten-
|
||||
; cies; for example: 1111b becomes 00b; and 00b becomes 0b. But it does
|
||||
; not occur very often.
|
||||
; - As the maximum enlargement is 112,5% I would at least allocate an
|
||||
; output buffer of size *12 /10 if the data is not static.
|
||||
;
|
||||
; Last words
|
||||
; **********
|
||||
;
|
||||
; I made this engine for fun and I had fun with it, I hope you like it and
|
||||
; can use it in someway. Feel free to modify it to your needs. See Notes
|
||||
; for more details. Anyway, I hope you like it and if you like to let
|
||||
; me know something please do and send mail to xblueowl@hotmail.com.
|
||||
|
||||
; I compiled this stuff with FASM, but you should be able to assemble this
|
||||
; with any popular assembler (MASM/TASM/FASM/NASM?) :).
|
||||
|
||||
; compress
|
||||
; in: esi = ptr to data to compress
|
||||
; ecx = size of data to compress
|
||||
; edi = ptr to output buffer
|
||||
; out: edi = end of data put in output buffer
|
||||
; size: 165 bytes
|
||||
|
||||
bnce_compress: push 03020100h ; push table
|
||||
push esi
|
||||
push ecx
|
||||
sub eax, eax ; eax = 0
|
||||
cdq ; edx = 0
|
||||
push eax ; 4 counters for the 4 existing nibbles
|
||||
push eax
|
||||
push eax
|
||||
push eax
|
||||
count_bytes: push ecx ; save no. of bytes
|
||||
push 4
|
||||
pop ecx ; ecx = 4
|
||||
lodsb
|
||||
count_bits: sub ah, ah
|
||||
shl eax, 2 ; ah = first 2 bits
|
||||
mov dl, ah ; dl = 2 bits
|
||||
inc dword [esp+4+edx*4] ; count it
|
||||
loop count_bits
|
||||
pop ecx
|
||||
loop count_bytes ; now the 4 counters are filled with the correct values
|
||||
|
||||
sort_again: sub ecx, ecx ; ecx = 0
|
||||
mov esi, esp ; esi = ptr to first counter
|
||||
lodsd ; esi = ptr to next counter
|
||||
no_bubble: inc ecx
|
||||
cmp ecx, 4
|
||||
jz sort_done ; if no changes were made 4 times bubbling is done
|
||||
lodsd ; eax = this counter; esi = next counter
|
||||
cmp [esi-8], eax ; compare to previous counter
|
||||
jae no_bubble ; if previous counter is bigger or equal make no change
|
||||
xchg [esi-8], eax ; swap counters
|
||||
mov [esi-4], eax
|
||||
mov al, [esp+23+ecx]; swap nibbles
|
||||
xchg al, [esp+24+ecx]
|
||||
mov [esp+23+ecx], al
|
||||
jmp sort_again ; start over
|
||||
sort_done: add esp, 16 ; delete counters (only nibbles remaining)
|
||||
|
||||
pop ecx ; ecx = size of data
|
||||
pop esi ; esi = start of data
|
||||
|
||||
pop eax ; eax = nibble table
|
||||
push eax
|
||||
shl eax, 6 ; move up table
|
||||
stosd ; save table
|
||||
|
||||
mov eax, ecx ; eax = ecx = size of data (*)
|
||||
stosd ; save it (*)
|
||||
|
||||
sub edx, edx ; edx = 0 (bits stored counter)
|
||||
compress_loop: push ecx
|
||||
push 4
|
||||
pop ecx ; ecx = 4
|
||||
lodsb
|
||||
compress_bits: sub ebx, ebx ; ebx = 0
|
||||
sub ah, ah ; ah = 0
|
||||
shl eax, 2 ; ah = xxb
|
||||
inc ebx ; 1 bit large; output is: 0b
|
||||
cmp ah, [esp+0+4] ; is it main compress byte?
|
||||
jz move_bits
|
||||
mov bh, 10000000b ; output is: 10b
|
||||
inc ebx ; 2 bit large
|
||||
cmp ah, [esp+1+4]
|
||||
jz move_bits
|
||||
mov bh, 11000000b
|
||||
inc ebx ; 3 bit large; output is: 110b
|
||||
cmp ah, [esp+2+4]
|
||||
jz move_bits
|
||||
mov bh, 11100000b ; output is: 111b
|
||||
move_bits: shl dh, 1 ; get a free bit in dh
|
||||
shl bh, 1 ; carry on/of
|
||||
adc dh, 0 ; add it to dh
|
||||
inc edx
|
||||
mov [edi], dh
|
||||
cmp dl, 8
|
||||
jnz no_store_bits
|
||||
inc edi
|
||||
sub edx, edx
|
||||
no_store_bits: dec bl
|
||||
jnz move_bits
|
||||
loop compress_bits
|
||||
pop ecx
|
||||
loop compress_loop
|
||||
|
||||
mov cl, 8
|
||||
sub cl, dl
|
||||
rol dh, cl ; make sure last byte's bits are placed correctly
|
||||
mov [edi], dh
|
||||
inc edi
|
||||
|
||||
pop eax ; table not needed anymore
|
||||
ret
|
||||
|
||||
; decompress
|
||||
;
|
||||
; in: esi = pointer to data to be decompressed
|
||||
; edi = pointer to output buffer
|
||||
; out: edi = pointer to end of output buffer
|
||||
; size: 54 bytes
|
||||
|
||||
bnce_decompress:lodsd
|
||||
push eax ; push decoder table
|
||||
lodsd ; (@)
|
||||
xchg eax, ecx ; ecx = size when uncompressed (@)
|
||||
mov dl, 8 ; indicate new byte needed
|
||||
decompress_next:push ecx
|
||||
push 4 ; start byte reconstruction (4 nibbles remaining)
|
||||
pop ecx
|
||||
decompress_loop:sub ebx, ebx ; type = 0
|
||||
push ecx
|
||||
push 3 ; repeat 3 times if necessary
|
||||
pop ecx
|
||||
find_type: cmp dl, 8 ; next byte needed?
|
||||
jnz dont_fill
|
||||
sub edx, edx ; clear bit-counter
|
||||
lodsb ; load new byte
|
||||
dont_fill: inc edx ; 1 bit is used from byte
|
||||
shl al, 1 ; get the bit
|
||||
jnc dmove_bits ; if it is off, type is found
|
||||
inc ebx ; type ++
|
||||
loop find_type ; repeat
|
||||
dmove_bits: pop ecx ; restore ecx (stored bit counter)
|
||||
mov dh, al ; save al
|
||||
mov al, [esp+4+ebx] ; get appropiate bits
|
||||
shl eax, 2 ; add bits to ah
|
||||
mov al, dh ; restore al
|
||||
loop decompress_loop ; if byte is not ready to be put, go on
|
||||
mov [edi], ah ; save byte
|
||||
inc edi ; move up ptr
|
||||
pop ecx
|
||||
loop decompress_next ; go on decompressing
|
||||
pop eax
|
||||
ret
|
||||
|
||||
; BlueOwl 23 august, 2004
|
||||
Reference in New Issue
Block a user