Skip to content

Instantly share code, notes, and snippets.

@odzhan
Last active November 18, 2021 18:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save odzhan/5f60b1104ecaac6cf4c11a2a7fe19a00 to your computer and use it in GitHub Desktop.
Save odzhan/5f60b1104ecaac6cf4c11a2a7fe19a00 to your computer and use it in GitHub Desktop.
LZCE32 Compression Engine
;
; LZCE32 by Sexy Dufus released in ca. 2000
;
; disassembly by odzhan
; 12-07-2019
;
; Compression ratio is typically ~36% for 1MB EXE
bits 32
%ifndef BIN
global lz_compress
global _lz_compress
global lz_decompress
global _lz_decompress
%endif
; ############################################## COMPRESSION ##########################################
; workspace should be buffer of 0x5000 bytes
; uint32_t lz_compress(const void *inbuf, void *outbuf, uint32_t inlen, void *workspace);
lz_compress:
_lz_compress:
sub eax, eax
push eax
push eax
push eax
push eax
push eax
mov ebp, esp
call sub_91
sub eax, eax
inc ah
call sub_B4
call sub_DD
loc_1C:
sub ah, ah
loc_1E:
mov [ebp+0], ax
call sub_DD
jb loc_74
mov [ebp+8], al
movzx ebx, word [ebp+0]
call sub_F2
jnb loc_1E
call sub_128
push ebx
movzx eax, word [ebp+0]
call sub_B4
pop ebx
mov al, [ebp+8]
cmp bx, [ebp+4]
jl loc_1C
cmp word [ebp+6], 0Ch
jl loc_6A
sub eax, eax
inc ah
call sub_B4
call sub_91
mov al, [ebp+8]
jmp loc_1C
loc_6A:
inc word [ebp+6]
shl word [ebp+4], 1
jmp loc_1C
loc_74:
movzx eax, word [ebp+0]
call sub_B4
mov eax, 101h
call sub_B4
xchg eax, edi
sub eax, [ebp+1Ch]
add esp, 14h
retn 10h
sub_91:
pusha
mov word [ebp+6], 9
mov word [ebp+4], 200h
sub eax, eax
dec eax
mov ecx, 280h
mov edi, [ebp+24h]
rep stosw
mov word [ebp+2], 102h
popa
retn
sub_B4:
push eax
mov eax, [ebp+0Ch]
movzx ecx, word [ebp+6]
add [ebp+0Ch], ecx
push 8
pop ecx
sub edx, edx
div ecx
add eax, [ebp+1Ch]
xchg eax, edi
pop eax
mov ecx, edx
sub edx, edx
jcxz loc_D6
shl eax, cl
or al, [edi]
loc_D6:
stosw
shr eax, 10h
stosb
retn
sub_DD:
mov esi, [ebp+18h]
mov edi, [ebp+10h]
cmp edi, [ebp+20h]
jnb loc_F0
mov al, [esi+edi]
inc dword [ebp+10h]
clc
retn
loc_F0:
stc
retn
sub_F2:
call sub_121
sub edi, edi
cmp word [esi], 0FFFFh
jz loc_11F
inc edi
movzx ebx, word [esi]
loc_103:
call sub_121
cmp [esi+4], al
jnz loc_112
clc
movzx eax, bx
retn
loc_112:
cmp word [esi+2], 0FFFFh
jz loc_11F
movzx ebx, word [esi+2]
jmp loc_103
loc_11F:
stc
retn
sub_121:
lea esi, [ebx+ebx*4]
add esi, [ebp+24h]
retn
sub_128:
movzx ebx, word [ebp+2]
or edi, edi
jz loc_136
mov [esi+2], bx
jmp loc_139
loc_136:
mov [esi], bx
loc_139:
cmp bx, 1000h
jz locret_157
call sub_121
mov word [esi], 0FFFFh
mov word [esi+2], 0FFFFh
mov [esi+4], al
inc word [ebp+2]
locret_157:
retn
; ####################################### DECOMPRESSION ###############################
; workspace should be buffer of 0x3000 bytes
; uint32_t lz_decompress(const void *inbuf, void *outbuf, uint32_t inlen, void *workspace);
lz_decompress:
_lz_decompress:
sub eax, eax
push eax
push eax
push 9
push 2000000h
push 1020000h
push eax
push 0FFF07FFh
push 3FF01FFh
mov ebp, esp
loc_1D:
call sub_F8
cmp ax, 101h
jz loc_E7
cmp ax, 100h
jnz loc_51
call sub_130
call sub_F8
mov [ebp+8], ax
mov [ebp+0Ah], ax
mov [ebp+17h], al
mov [ebp+16h], al
call sub_143
jmp loc_1D
loc_51:
mov [ebp+8], ax
mov [ebp+0Ch], ax
cmp ax, [ebp+0Eh]
jl loc_70
movzx eax, word [ebp+0Ah]
mov [ebp+8], ax
movzx eax, byte [ebp+16h]
push eax
inc word [ebp+10h]
loc_70:
cmp word [ebp+8], 0FFh
jle loc_92
movzx ebx, word [ebp+8]
call sub_F1
mov al, [ebx+2]
push eax
inc word [ebp+10h]
movzx eax, word [ebx]
mov [ebp+8], ax
jmp loc_70
loc_92:
movzx eax, word [ebp+8]
mov [ebp+16h], al
mov [ebp+17h], al
push eax
inc word [ebp+10h]
movzx ecx, word [ebp+10h]
jcxz loc_B0
loc_A8:
pop eax
call sub_143
loop loc_A8
loc_B0:
mov [ebp+10h], cx
call sub_14E
movzx eax, word [ebp+0Ch]
mov [ebp+0Ah], ax
movzx ebx, word [ebp+0Eh]
cmp bx, [ebp+12h]
jl loc_1D
cmp word [ebp+14h], 0Ch
jz loc_1D
inc word [ebp+14h]
shl word [ebp+12h], 1
jmp loc_1D
loc_E7:
xchg eax, edi
sub eax, [ebp+28h]
add esp, 20h
retn 10h
sub_F1:
lea ebx, [ebx+ebx*2]
add ebx, [ebp+30h]
retn
sub_F8:
movzx eax, word [ebp+14h]
add eax, [ebp+18h]
xchg eax, [ebp+18h]
push 8
pop ecx
sub edx, edx
div ecx
add eax, [ebp+24h]
xchg eax, esi
lodsw
movzx ebx, ax
lodsb
movzx ecx, dx
jcxz loc_120
loc_119:
shr al, 1
rcr bx, 1
loop loc_119
loc_120:
movzx eax, bx
movzx ebx, word [ebp+14h]
sub ebx, 9
and ax, [ebp+ebx*2+0]
retn
sub_130:
mov word [ebp+14h], 9
mov word [ebp+12h], 200h
mov word [ebp+0Eh], 102h
retn
sub_143:
mov edi, [ebp+1Ch]
add edi, [ebp+28h]
stosb
inc dword [ebp+1Ch]
retn
sub_14E:
movzx ebx, word [ebp+0Eh]
call sub_F1
movzx eax, byte [ebp+17h]
mov [ebx+2], al
movzx eax, word [ebp+0Ah]
mov [ebx], ax
inc word [ebp+0Eh]
retn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment