;*********************************************************************** ;* * ;* Nigr0 Compression Engine * ;* * ;*********************************************************************** ; ; Engine Size (Compression and Descompression) = 01C0h Bytes ; ; Estadisticias: ; ; File WINWORD.EXE: ; Section size New size NCE Ratio ; ------- ------ -------- --------- ; Header 0400h 024Ah 57,2% ; Code 0357000h 03319E9h 97,4% ; Data 04000h 028BFh 63,6% ; Rsrc 0E000h 08B07h 62,0% ; Reloc 027000h 0192CFh 64,5% ; ; File NETSCAPE.EXE: ; Section size New size NCE Ratio (JQEnc) New Size ; ------- ------ -------- --------- ---------------- ; Header 0400h 0229h 54,0% 0184h ; Code 030E000h 02FC3C4h 97,7% 0245002h ; Data 056200h 043F18h 78,8% 031C0Ah ; Rsrc 03E00h 02E78h 74,9% 027F6h ; ; ; This engine is very usufull when the data to compress has ; a lot of repetitions or when the data variate only a little. ; 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 4 4 4 4 1 1 1 1 1 1 1 1 ; This secuence will have a good ratio because it has a lot of ; words repeated. ; 10 11 10 10 12 11 10 11 12 10 12 10 11 ; This secuence will olso have a good ratio because the ; differences between 10, 11 and 12 is very low. ; ; The engine will get 2 bytes from input buffer and compress ; it in the output buffer, the output format will be; ; (Seg) 1 bit-> Segurity bit (if 1 not compression posible and 16 bits ; follow it there are the data without any compression) ; (C) 1 bit -> Complement (0 no complement /1 complement) ; (O) 1 bit -> SUB or not SUB ( 0 Sub/ 1 not Sub) ; (S) 3 bits -> The size of the new encoding data ; (N) last bits -> The data compressed ; ; ÉÍÍÍÍÍÍËÍÍÍÍÍÍËÍÍÍÍÍÍËÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍ» ; º (Seg)º (C) º (O) º (S) º (N) º ; º 1bit º 1bit º 1bit º 3bits º Nbits º ; ÈÍÍÍÍÍÍÊÍÍÍÍÍÍÊÍÍÍÍÍÍÊÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍͼ ; ; In this way, if there are repeatition of words in the text to compress ; the second word will need only 6bits ,because N will be 0. ; With operation of SUB and Complement will be able to optain N=0, and ; will only need to code the compression data bits (Seg,C,O and S bits). .386p locals jumps .model flat,STDCALL extrn ExitProcess:PROC extrn CreateFileA:PROC extrn ReadFile:PROC extrn CloseHandle:PROC extrn WriteFile:PROC extrn SetFilePointer:PROC GENERIC_READ EQU 80000000H ;abre archivo para lectura GENERIC_WRITE EQU 40000000H ;abre el archivo para escritura OPEN_EXISTING EQU 3 ;usado por CreateFile para abrir archivo existente size EQU 03E00h dir equ 03C2E00h .data dumm7y db 0 ;de esta secci¢n paso text db 'Ejemplo de Compression Ejecutado',0 .code start: xor ebp,ebp lea esi,ebp+host ;Abro el archivo xor eax,eax push eax push eax push large OPEN_EXISTING push eax push eax push large GENERIC_READ or GENERIC_WRITE mov eax,esi push eax call CreateFileA ;abro el archivo a comprimir mov dword ptr [ebp+ahand],eax push LARGE 0 ;en edx: el offset del archivo push LARGE 0 push LARGE dir push dword ptr [ebp + ahand] call SetFilePointer ;me voy al principio mov ecx,size lea edx,[ebp+end] push large 0 ;En ecx: Numero de bytes a leer lea eax,[ebp +IOBYTES] ;En edx: el offset del buffer push eax push ecx push edx push dword ptr [ebp + ahand] call ReadFile push dword ptr [ebp + ahand] call CloseHandle ;cierro el archivo int 03h mov ebp,end_c_engine-start_c_engine xor ebp,ebp lea esi,[ebp+end] lea edi,[ebp+end] add edi,size mov ecx,size call nce_comp int 03h lea edi,[ebp+end] mov esi,edi add esi,size mov ecx,size call nce_decomp salir: Push LARGE -1 call ExitProcess IOBYTES: dd 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h dd 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h dd 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h dd 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h dd 0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h,0h ahand dd 0h ;el handle abierto host db 'prueba.exe',0 compr db 'prueba.cmp',0 ;************************************************************************ ;***************** Comienzo de la rutina de compresion ****************** ;************************************************************************ start_c_engine: nce_comp: pushad inc ecx shr ecx,1 ;divido entre 2 xor ebx,ebx ;ebx sera el contador de bits xor ebp,ebp ;en ebp se almacena la palabra anterior otrapalabra: push ecx xor eax,eax lodsw ;leo 2 bytes push eax push esi push eax @otravez: call pone0 ;bit de seguridad xor esi,esi push eax push eax pop edx pop ecx sub dx,bp xor cx,0ffffh mov si,cx sub si,bp shl eax,2 shl edx,2 shl ecx,2 shl esi,2 add edx,0002h add ecx,0001h add esi,0003h reord: cmp eax,edx jle @a xchg eax,edx jmp reord @a: cmp edx,ecx jle @b xchg edx,ecx jmp reord @b: cmp ecx,esi jle @c xchg ecx,esi jmp reord @c: push eax xchg eax,edx mov ecx,02h ;meto 2 bits con la codificacion de complemento call mbit ;y operacion pop eax shr eax,2 xor edx,edx dec edx db 066h,0fh,0bdh,0d0h ;bsr dx,ax ;calculo el tama¤o que tendr  inc edx cmp dx,7 jle @fuera sub ebx,3 call pone1 pop edx pop esi mov ecx,16 ;mete la palabra sin comprimir call mbit jmp @4 @fuera: add esp,4 pop esi and edx,0ffffh push edx mov ecx,03h ;codifico la longitud en 3 bits call mbit pop ecx jecxz @4 dec ecx ;El bit mas significativo ser  1 no hace falta ;codificarlo jecxz @4 xchg eax,edx call mbit ;y ahora mete la nueva codificacion @4: pop ebp ;en ebp la palabra anterior pop ecx dec ecx jne otrapalabra shr ebx,03h inc ebx ;en ebx los bytes que ocupara encriptado mov ebp,esp mov dword ptr [ebp+24],ebx popad ret ;****** Rutina que se encarga de poner un 1 o un 0 en el bit ebx ******* ;****** a partir de la direccion edi *********************************** pone1: bts [edi],ebx ;pone un 1 jmp @s pone0: btr [edi],ebx ;pone un 0 @s: inc ebx ret ;***** Rutina que copia tantos bit como indique ecx ***** ;***** desde el registro dx al buffer ********************** mbit: rcr dx,1 jc meteun1 call pone0 jmp sale meteun1: call pone1 sale: loop mbit ret ;************************************************************************ ;************* Comienzo de la rutina de decompresion ******************** ;************************************************************************ nce_decomp: pushad inc ecx shr ecx,01h ;lo paso a (16 bits) xor ebx,ebx xor ebp,ebp descomprimeotro: push ecx push edi xor edi,edi call leobit jnc estacomprimido mov ecx,016d formoword: bt [esi],ebx rcr ax,1 ;voy formando el bit inc ebx loop formoword jmp @p3 estacomprimido: call leobit jc cmpl push LARGE 0 jmp nocmpl cmpl: push LARGE -1 nocmpl: call leobit jnc @prosigue inc edi @prosigue: mov ecx,3 xor edx,edx otroc: bt [esi],ebx rcr dl,1 ;leo los 4 bits siguientes en dl inc ebx loop otroc shr dl,5 xchg ecx,edx ;en ecx el tama¤o xor eax,eax jecxz @5 dec ecx jecxz @6 push ecx metebit: bt [esi],ebx rcr ax,1 ;voy formando el bit inc ebx loop metebit pop ecx @6: inc ecx stc rcr ax,1 mov edx,16 sub edx,ecx xchg ecx,edx shr ax,cl ;desplazo lo que queda ;en ax tengo la palabra leida @5: pop ecx or ecx,ecx jz nocmp xor ax,0ffffh nocmp: or edi,edi jz @p3 add ax,bp @p3: mov ebp,eax ;en bp el nuevo valor para obtener las relocations pop edi stosw pop ecx dec ecx jnz descomprimeotro popad ret leobit: bt [esi],ebx inc ebx ret end_c_engine: end: buffer db 030f000h*2 dup(0) memoria db 010h dup(0) ;buffer para el algoritmo de jackqy tempbuf db 066000h dup(0) ;buffe temporal para el algo de jackqery end start