0,0 → 1,896 |
; @RCHER parser and filter routines |
; Written in pure assembler by Ivushkin Andrey aka Willow |
|
fhs_local equ 0x04034b50 |
fhs_central equ 0x02014b50 |
fhs_end equ 0x06054b50 |
fhs_enc equ 0x08074b50 |
|
SkipASCIIZ: |
xor eax,eax |
mov ecx,255 |
mov edi,esi |
repne scasb |
mov esi,edi |
ret |
|
PrintFilename: |
pusha |
mov esi,edx |
mov edi,os_work |
mov edx,edi |
rep movsb |
mov dword[edi],0x00a0d |
call DebugPrint |
; mcall 10 |
; mcall 2 |
popa |
ret |
|
|
; Parse routines: |
; out: edx= 0 if all ok, 1 - central dir, 2-EOD |
; 50 - encrypted |
; 51 - not deflated |
; 52 - invalid format |
; 53 - dir skipped |
; 1 - encrypted |
|
; **************************************************** |
ZipParse: |
|
call ResetFile |
.nxt: |
call ZipCrawl |
|
cmp edx,3 |
je .ex |
cmp edx,1 |
je .skipinc |
if IGNORE_DIRS eq 1 |
cmp edx,53 |
jne .skipinc |
end if |
inc [file_count] |
.skipinc: |
cmp edx,52 |
je .er1 |
cmp edx,50 |
jne .seek |
.er1: |
Msg edx |
ret |
.seek: |
add eax,ecx |
mov ebx,1 |
call FileSeek |
jmp .nxt |
.ex: |
Msg 2 |
mov eax,[file_count] |
if ~ SYS eq win |
dpd eax |
else |
pusha |
call int2str |
mov edx,os_work |
call DebugPrint |
popa |
end if |
Newline |
ret |
|
ZipFindN: |
; ecx - file # |
Msg 33 |
cmp ecx,[file_count] |
jae .err |
push ecx |
call ResetFile |
.nxt: |
call ZipCrawl |
cmp edx,51 |
je .ok2 |
.noenc: |
test edx,edx |
jnz .err |
.ok2: |
add eax,ecx |
cmp dword[esp],0 |
jz .ok |
dec dword[esp] |
mov ebx,1 |
call FileSeek |
jmp .nxt |
.err: |
mov edx,4 |
jmp .ex |
.ok: |
pop ecx |
sub eax,[esi+18] |
add esi,eax |
mov edx,5 |
.ex: |
push edx |
Msg edx |
pop edx |
ret |
|
ZipCrawl: |
mov edx,52 |
cmp dword[esi],fhs_central |
jne .noc |
mov eax,46 |
movzx ecx,word[esi+28] |
add eax,ecx |
movzx ecx,word[esi+30] |
add eax,ecx |
movzx ecx,word[esi+32] |
mov edx,1 |
ret |
.noc: |
cmp dword[esi],fhs_end |
jne .noe |
.edx3: |
Msg 3 |
mov edx,3 |
ret |
.noe: |
cmp dword[esi],fhs_local |
je .loc |
cmp dword[esi],fhs_enc |
jne .err |
mov eax,16 |
xor ecx,ecx |
mov edx,1 |
ret |
.loc: |
push word[esi+6] |
pop [gpbf] |
push dword[esi+14] |
pop [CRC_check] |
push dword[esi+22] |
pop [unp_size] |
movzx ecx,word[esi+26] |
mov eax,30 |
lea edx,[esi+eax] |
add eax,ecx |
if IGNORE_DIRS eq 1 |
cmp byte[edx+ecx-1],'/' |
je .skipdp |
end if |
call PrintFilename |
.skipdp: |
movzx ecx,word[esi+28] |
add eax,[esi+18] |
test [gpbf],1 |
jz .no_enc |
or [Flags],DECRYPT_MODE ; encrypted |
mov edx,51 |
jmp .err |
.no_enc: |
test word[esi+8],7 |
rep_err z,50 |
.ok: |
xor edx,edx |
.err: |
ret |
|
; *********************************************** |
GzipParse: |
ID1ID2 equ 0x8b1f |
FTEXT equ 1b |
FHCRC equ 10b |
FEXTRA equ 100b |
FNAME equ 1000b |
FCOMMENT equ 10000b |
mov eax,7 |
mov ebx,2 |
call FileSeek |
push dword[esi] |
pop [CRC_check] |
push dword[esi+4] |
pop [unp_size] |
call ResetFile |
xor edx,edx |
cmp word[esi],ID1ID2 |
rep_err e, 52, 15 |
cmp byte[esi+2],8 |
rep_err e, 52, 50 |
mov bl,[esi+3] ; bl - FLG |
add esi,10 ; esi->extra |
test bl,FEXTRA |
jz .noextr |
movzx eax,word[esi] |
lea esi,[esi+eax+2] ; esi->FNAME |
.noextr: |
test bl,FNAME |
jz .nofname |
mov edx,esi |
call DebugPrint |
call SkipASCIIZ |
cmp dword[esi-5],'.tar' |
jne .nofname |
or [Flags],TAR_MODE |
.nofname: ; esi->FCOMMENT |
test bl,FCOMMENT |
jz .nocomm |
call SkipASCIIZ |
.nocomm: ; esi->HCRC |
test bl,FHCRC |
jz .noCRC16 |
add esi,2 |
.noCRC16: |
cmp [unp_size],OUTBUF |
jb .sizeok2 |
Msg 16 |
mov edx,15 |
ret |
.sizeok2: |
xor edx,edx |
.err: |
ret |
|
PngParse: |
ID1 equ 0x474e5089 |
ID2 equ 0x0a1a0a0d |
FDICT equ 100000b |
InitIDAT equ 2 |
mov [IDATcount],InitIDAT |
call ResetFile |
cmp dword[esi],ID1 |
rep_err e, 52, 18 |
cmp dword[esi+4],ID2 |
rep_err e, 52, 18 |
add esi,8 |
cmp dword[esi+4],'IHDR' |
rep_err e,52, 18 |
or [Flags],PNG_MODE |
memcpy_esi PNG_info,13,8 |
mov eax,[PNG_info.Width] |
bswap eax |
mov [PNG_info.Width],eax |
mov eax,[PNG_info.Height] |
bswap eax |
mov [PNG_info.Height],eax |
add esi,25 |
cmp byte[esi-5],0 |
rep_err e,52,29 |
.nxt_sec: |
lodsd |
bswap eax ; eax - section size |
push eax |
lodsd |
mov edi,Png_ch |
mov ecx,(E_ch-Png_ch) / 4 |
repne scasd |
pop eax |
mov ebx,[esi-4] |
mov edx,os_work |
mov [edx],ebx |
mov dword[edx+4],0x0a0d |
.dp: |
sub edi,Png_ch |
shr edi,2 ; edi- chunk # |
if SHOW_PNG_SEC eq 1 |
call DebugPrint |
end if |
cmp edi,1 |
jne .noend |
mov edx,21 |
jmp .err |
.noend: |
cmp edi,2 |
jne .noplte |
memcpy_esi PNG_info.Palette,eax |
jmp .noidat |
.noplte: |
cmp edi,3 |
jne .noidat |
mov [IDATsize],eax |
cmp [IDATcount],InitIDAT |
jne .ex |
mov [bits],8 |
if RBLOCK eq 4 |
lodsd |
else |
lodsb |
end if |
call setcurb |
rbits 0,16 |
test ah,FDICT |
jz .ex |
rbits 0,32 |
add [IDATcount],4 |
jmp .ex |
.noidat: |
add eax,4 |
mov ebx,1 |
call FileSeek |
jmp .nxt_sec |
.ex: |
xor edx,edx |
.err: |
ret |
|
Png_ch: |
dd 'IEND','PLTE','IDAT','????' |
E_ch: |
|
ZipDecrypt: |
push edi |
mov ecx,3 |
mov edi,Dheader |
rep movsd |
pop edi |
call QueryPwd |
jecxz .ex |
push esi |
mov [DKeys], 305419896 |
mov [DKeys+4],591751049 |
mov [DKeys+8],878082192 |
xor eax,eax |
mov esi,Dpassword |
.enc_init: |
lodsb |
call UKeys |
loop .enc_init |
mov ecx,12 |
mov esi,Dheader |
.dec_header: |
call decrypt_byte |
xor al,[esi] |
call UKeys |
mov [esi],al |
inc esi |
loop .dec_header |
mov eax,[CRC_check] |
pop esi |
.ex: |
ret |
|
QueryPwd: |
; out: ecx - passwd len |
if SYS eq win |
Msg 32 |
invoke ReadConsole,[cons_in],Dpassword,PASSW_LEN,cparam1,NULL |
test eax,eax |
jnz .inp_ok |
xor ecx,ecx |
jmp .ex |
.inp_ok: |
mov ecx,[cparam1] |
cmp ecx,PASSW_LEN |
je .ex |
sub ecx,2 |
else |
end if |
.ex: |
ret |
|
UKeys: |
; in: al - char |
pusha |
mov edi,134775813 |
mov ebx,DKeys |
mov esi,os_work |
mov byte[esi],al |
mov ecx,1 |
push dword[ebx] |
pop [CRC32] |
call UCRC |
push [CRC32] |
pop dword[ebx] |
mov eax,[ebx] |
and eax,0xff |
add eax,[ebx+4] |
mul edi |
inc eax |
mov [ebx+4],eax |
shr eax,24 |
mov byte[esi],al |
push dword[ebx+8] |
pop [CRC32] |
call UCRC |
push [CRC32] |
pop dword[ebx+8] |
popa |
ret |
|
decrypt_byte: |
; out: al |
push ebx edx |
movzx ebx,word[DKeys+8] |
or ebx,2 |
mov eax,ebx |
xor eax,1 |
mul ebx |
shr eax,8 |
pop edx ebx |
ret |
|
setcurb: |
; in: eax |
test [Flags],DECRYPT_MODE |
jz .noenc |
push eax |
call decrypt_byte |
xor al,byte[esp] |
add esp,4 |
call UKeys |
.noenc: |
mov [cur_byte],eax |
ret |
|
TarParse: |
call ResetFile |
.nxt: |
call TarCrawl |
; wait |
cmp edx,3 |
je ZipParse.ex |
if IGNORE_DIRS eq 1 |
cmp edx,53 |
jne .skipinc |
end if |
inc [file_count] |
.skipinc: |
add eax,ecx |
mov ebx,1 |
call FileSeek |
jmp .nxt |
|
TarFindN: |
; in: ecx - file number |
; ecx - file # |
Msg 33 |
cmp ecx,[file_count] |
jae .err |
push ecx |
call ResetFile |
.nxt: |
call TarCrawl |
if IGNORE_DIRS eq 1 |
cmp edx,53 |
je .seek |
end if |
test edx,edx |
jnz .err |
cmp dword[esp],0 |
jz .ok |
dec dword[esp] |
.seek: |
add eax,ecx |
mov ebx,1 |
call FileSeek |
jmp .nxt |
.err: |
mov edx,4 |
jmp .ex |
.ok: |
pop ecx |
add esi,eax |
mov edx,5 |
.ex: |
Msg edx |
ret |
|
TarCrawl: |
cmp byte[esi],0 |
jz ZipCrawl.edx3 |
push esi |
mov ecx,11 |
add esi,0x7c |
call Octal_str |
mov esi,[esp] |
mov [outfile.size],eax |
call SkipASCIIZ |
if IGNORE_DIRS eq 1 |
cmp byte[esi-2],'/' |
je .skipdp |
end if |
mov edx,[esp] |
lea ecx,[esi-1] |
sub ecx,edx |
call PrintFilename |
.skipdp: |
mov ecx,[outfile.size] |
jecxz .zerolen |
shr ecx,9 |
inc ecx |
shl ecx,9 |
.zerolen: |
mov eax,512 |
pop esi |
jmp ZipCrawl.ok |
|
Octal_str: |
; in: esi - ASCIIZ octal string |
; ecx - its length |
; out: eax - value |
push esi ebx ecx |
xor ebx,ebx |
xor eax,eax |
.jec: |
jecxz .zero |
cmp byte[esi+ecx-1],' ' |
jne .lp |
dec ecx |
jmp .jec |
.lp: |
lodsb |
shl ebx,3 |
cmp eax,' ' |
je .space |
lea ebx,[ebx+eax-'0'] |
.space: |
loop .lp |
mov eax,ebx |
.zero: |
pop ecx ebx esi |
ret |
|
TRAILING_BUF equ 2048 |
SfxParse: |
call ResetFile |
cmp word[esi],'MZ' |
rep_err e, 34 |
mov eax,TRAILING_BUF |
mov ecx,eax |
mov ebx,2 |
call FileSeek |
mov edi,esi |
mov al,'P' |
.lp: |
repne scasb |
cmp dword[edi-1],fhs_end |
je .end_found |
jecxz .err |
jmp .lp |
.end_found: |
dec edi |
mov esi,edi |
mov eax,[edi+12] |
neg eax |
mov ebx,1 |
call FileSeek |
push dword[esi+42] |
pop [arc_base] |
.err: |
ret |
|
; Created: May 31, 2005 |
FiltCall: |
dd PngFilter.nofilt,Filt_sub,Filt_up,Filt_av,Filt_paeth,PngFilter.nofilt |
PngFilter: |
; esi - filtered uncompressed image data |
; edi - destination |
mov cl,[PNG_info.Color_type] |
mov eax,1 |
cmp cl,3 |
je .palette |
test cl,2 |
jz .notriple |
add eax,2 |
.notriple: |
test cl,4 |
jz .calc_bpp |
inc eax |
.calc_bpp: |
mul [PNG_info.Bit_depth] |
.palette: |
mov ecx,eax ; in bits |
shr eax,3 ; in bytes |
test eax,eax |
jnz .noz |
inc eax |
.noz: |
mov [png_bpp],eax |
mov eax,[PNG_info.Width] |
mov ebp,eax |
imul ecx |
shr eax,3 |
test eax,eax |
jnz .noz2 |
inc eax |
.noz2: |
mov [sline_len],eax ; scanline length |
push edi |
and [Flags],not 1 |
mov ecx,[PNG_info.Height] |
.scanline: |
; Msg 9,1 |
push ecx |
lodsb |
movzx eax,al |
cmp eax,5 |
jb .f_ok |
mov eax,5 |
.f_ok: |
inc dword[filters+eax*4] |
jmp dword[FiltCall+eax*4] |
.nofilt: |
mov dl,[PNG_info.Color_type] |
cmp dl,3 |
jne .nopalette |
lodsb |
mov [cur_byte],eax |
mov [bits],8 |
mov ecx,ebp |
.pixel: |
push ecx |
movzx ecx,[PNG_info.Bit_depth] |
call rb_png |
push esi |
lea esi,[eax+eax*2] |
add esi,PNG_info.Palette |
call PngStore |
pop esi |
pop ecx |
loop .pixel |
cmp [bits],8 |
jne .lp |
dec esi |
.lp: |
pop ecx |
loop .sl |
jmp .sl2 |
.sl: |
;// |
MV equ 1 |
; mov eax,ecx |
; and eax,1 shl MOVE_SLINE_LEV-1 |
; jnz .scanline |
;stop |
if MV eq 0 |
push ecx |
mov ecx,edi |
sub ecx,esi |
sub [outp],esi |
mov edi,output |
add [outp],edi |
rep movsb |
mov esi,output |
pop ecx |
pop eax |
push [outp] |
end if |
;;// |
jmp .scanline |
.sl2: |
;// |
; call MoveScanline |
sub edi,[outp] |
;// |
; sub edi,[esp] |
pop eax |
ret |
|
.nopalette: |
test dl,2 |
jz .notriple1 |
.__: |
mov ecx,[PNG_info.Width] |
.RGBcp: |
call PngStore |
add esi,[png_bpp] |
loop .RGBcp |
jmp .lp |
.notriple1: |
test dl,dl |
jz .gray |
cmp dl,4 |
jne .__ |
; Msg 31 |
; ud2 |
.gray: |
; stop |
push ecx |
mov ecx,[PNG_info.Width] |
mov [bits],8 |
lodsb |
mov [cur_byte],eax |
.gray2: |
push ecx |
movzx ecx,[PNG_info.Bit_depth] |
push ecx |
call rb_png |
pop ecx |
cmp ecx,8 |
jbe .lo |
add esi,2 |
shr eax,8 |
jmp .stsb |
.lo: |
neg ecx |
add ecx,8 |
shl eax,cl |
.stsb: |
mov ecx,3 |
rep stosb |
pop ecx |
loop .gray2 |
dec esi |
pop ecx |
jmp .lp |
|
Filt_sub: |
; dps '-' |
mov ecx,[sline_len] |
sub ecx,[png_bpp] |
push esi edi |
mov edi,esi |
add edi,[png_bpp] |
.scan: ; esi - previous, edi - current |
lodsb |
add [edi],al |
inc edi |
loop .scan |
|
pop edi esi |
; dps '-' |
jmp PngFilter.nofilt |
|
Filt_up: |
cmp ecx,[PNG_info.Height] |
je PngFilter.nofilt |
push esi edi |
mov ecx,[sline_len] |
mov edi,esi |
sub esi,ecx |
dec esi |
jmp Filt_sub.scan |
|
Filt_av: |
pusha |
mov ecx,[sline_len] |
mov ebp,[PNG_info.Height] |
mov edx,[png_bpp] ; edx-raw |
neg edx |
mov ebx,ecx |
sub ebx,[png_bpp] |
mov edi,esi |
sub esi,ecx |
dec esi ; esi-prior |
.lpavg: |
xor eax,eax |
cmp [esp+24h],ebp |
je .1stl |
movzx eax,byte[esi] |
.1stl: |
cmp ecx,ebx |
ja .leftbad |
push ecx |
movzx ecx,byte[edi+edx] |
add eax,ecx |
pop ecx |
.leftbad: |
shr eax,1 |
add [edi],al |
inc esi |
inc edi |
loop .lpavg |
popa |
jmp PngFilter.nofilt |
|
Filt_paeth: |
pusha |
mov ecx,[sline_len] |
mov edx,[png_bpp] |
neg edx |
lea ebp,[ecx+edx] ; left edge |
mov edi,esi |
sub esi,ecx |
dec esi |
.lpaeth: |
push ecx |
movzx eax,byte[edi+edx] |
movzx ebx,byte[esi] |
movzx ecx,byte[esi+edx] |
push eax |
mov eax,[esp+28h] |
cmp eax,[PNG_info.Height] ; 1st line |
jne .no1stlineok |
xor ebx,ebx |
xor ecx,ecx |
.no1stlineok: |
pop eax |
cmp [esp],ebp ; ecx |
jbe .leftok ; x-bpp>=0 |
xor eax,eax |
xor ecx,ecx |
.leftok: |
pusha ; eax-28, ebx-16, ecx-24 |
lea edx,[eax+ebx] |
sub edx,ecx ; p=edx |
sub eax,edx ; pa := abs(p - a) |
jge .eaxp |
neg eax |
.eaxp: |
sub ebx,edx ; pb := abs(p - b) |
jge .ebxp |
neg ebx |
.ebxp: |
sub ecx,edx ; pc := abs(p - c) |
jge .ecxp |
neg ecx |
.ecxp: |
cmp eax,ebx |
ja .noa |
cmp eax,ecx |
jbe .ex ; pa-min |
.noa: |
cmp ebx,ecx |
ja .nob |
mov eax,[esp+16] |
jmp .ex2 |
.nob: |
mov eax,[esp+24] |
.ex2: |
mov [esp+28],eax |
.ex: |
popa |
add [edi],al |
inc esi |
inc edi |
pop ecx |
loop .lpaeth |
popa |
jmp PngFilter.nofilt |
|
rb_png: ; eax-dest; ecx-count |
push ecx |
xor eax,eax |
.shift: |
rol byte[cur_byte],1 |
rcl eax,1 |
.dec: |
dec [bits] |
jnz .loop1 |
.push: |
push dword[esi] |
pop [cur_byte] |
mov [bits],8 |
inc esi |
.loop1: |
loop .shift |
pop ecx |
ret |
|
PngStore: |
push esi |
cmp [PNG_info.Bit_depth],8 |
jbe .lo |
add esi,3 |
.lo: |
if ~ SYS eq win |
mov esi,[esi] |
bswap esi |
shr esi,8 |
mov [edi],esi |
add edi,3 |
else |
movsw |
movsb |
end if |
pop esi |
ret |
|
FiltStats: |
pusha |
xor ebx,ebx |
mov edx,23 |
mov ecx,6 |
.lp: |
push ecx edx |
Msg edx |
mov eax,[filters+ebx*4] |
DebugPrintDec |
pop edx ecx |
inc edx |
inc ebx |
loop .lp |
Newline |
popa |
ret |
|
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |