; 18-01-98 23:40:15 1.00 begin to write program, file io procs alredy created ; 19-01-98 02:37:30 IT WORKS !!! (unpacking) - avp9708.avc unpacked ; 19-01-98 08:32:39 unpacking .AV5 files ; 19-01-98 22:00:29 adding checksum ; 21-01-98 16:47:03 1.01 .AV5->.L16,32, AV6->OBJ - skipped 1st 8 bytes ; =========================================================================== ; max size of packed/unpacked datablock in addon MAX_PACKED equ 2097152 ; 2 MB MAX_UNPACKED equ 2097152 ; 2 MB ; =========================================================================== ; .avc file format: ; ; 00h DBx64 kami_copyriht ; 40H DBx64 author_copyright ; 80H DBx46H avc_header ; xxx ??x36 datablock headers *** aka SUX *** ; yyy ?? (compressed) datablocks ; ; =========================================================================== avc_header_size equ 46h avc_header_struc struc avc_id dd ? ; EK.8 00 01 02 03 avc_ver dw ? ; 3 04 05 avc_bits db ? ; 06 ; bit0 = 0: made in kami, compressed ; bit0 = 1: warning(not in kami), not compressed avc_unk1 db 5 dup (?) ; ? 07 08 09 0A 0B avc_filesize dd ? ; 0C 0D 0E 0F avc_sux_offs dd ? ; 10 11 12 13 avc_sux_count dw ? ; 14 15 avc_unk2 dw ? ; ? =0 16 17 avc_unk3 db 32 dup (?); ? 18 ... 37 avc_unk4 db 6 dup (?) ; ? 38 ... 3d avc_author_cs dd ? ; 3E 3F 40 41 avc_header_cs dd ? ; 42 43 44 45 ends sux_size equ 36 sux_struc struc sux_id dw ? ; 0/1/2 / 100H 00 01 sux_id2 dw ? ; sub-id 02 03 sux_dataoffs dd ? ; 04 05 06 07 sux_datasize dd ? ; compressed data size 08 09 0a 0b sux_realsize dd ? ; real data size 0c 0d 0e 0f sux_unk2 dw ? ; ? =1 10 11 sux_recsize dw ? ; record size (or 0) 12 13 sux_recnum dd ? ; records(stamms) 14 15 16 17 ; or lines(names) ; or files(objects) sux_data_cs dd ? ; 18 19 1A 1B sux_unused db 8 dup (?) ; ? 1C ... 23 ends ; =========================================================================== .386 .model flat locals @@ jumps ; =========================================================================== extrn ExitProcess:PROC extrn MessageBoxA:PROC extrn GetCommandLineA:PROC extrn CreateFileA:PROC extrn SetFilePointer:PROC extrn ReadFile:PROC extrn WriteFile:PROC extrn CloseHandle:PROC ; =========================================================================== .data msgbox_title db 'Information',0 initmsg db 'AVPX AVP eXtender 1.01 (c) 1998 Z0MBiE z0mbie@chat.ru',0 syntaxmsg db 'Error in cmdline: See AVPX.DOC for help',0 badcmd_msg db 'Unknown command',0 cmd_unpavc db 6,'unpavc',0 cmd_unplib db 6,'unplib',0 cmd_packavc db 7,'packavc',0 cmd_packlib db 7,'packlib',0 cmd dd cmd_unpavc, unp_avc dd cmd_unplib, unp_lib dd cmd_packavc, pack_avc dd cmd_packlib, pack_lib cmd_end: unpackedavc_msg db '.AVC database unpacked',0 ;packedavc_msg db '.AVC database created',0 packedavc_msg db 'THIS FUNCTION IS NOT IMPLEMENTED IN 1.1',0 unpackedlib_msg db '.LIB file unpacked',0 ;packedlib_msg db '.LIB file created',0 packedlib_msg db 'THIS FUNCTION IS NOT IMPLEMENTED IN 1.1',0 error1msg db 'Too big compressed datablock size [increase "max_packed"]',0 error3msg db 'Too big real datablock size [increase "max_unpacked"]',0 error2msg db 'Error unpacking database [please report to Z0MBiE]',0 error4msg db 'Too big object size in .AV5 [increase "max_(un)packed" OR internal error [please report to Z0MBiE]]',0 __cprkami db '_kami.hdr',0 __cprauthor db '_author.hdr',0 __hdr db '_header.hdr',0 suxN equ 7 suxnum equ byte ptr $+4 sux_hdr db '_sux????.hdr',0 sux_unk db '_unk????.unk',0 sux_l16 db '_lib????.l16',0 sux_l32 db '_lib????.l32',0 sux_obj db '_obj????.obj',0 sux_nam db '_nam????.nam',0 sux_sta db '_sta????.sta',0 sux_iii db '_iii????.iii',0 ; id id2 suxxxx dd sux_iii, 0000h,0000h ; indexs? dd sux_sta, 0000h, -1 ; STAmms dd sux_l16, 0001h, -1 ; 16-bit lib dd sux_l32, 0002h, -1 ; 32-bit lib dd sux_nam, 0100h, -1 ; NAMes suxxxx_num equ ($-suxxxx)/8 bytesread dd ? byteswritten dd ? command equ paramstr1 avcbase equ paramstr2 paramcount dd ? paramstr0 db 128 dup (?) paramstr1 db 128 dup (?) paramstr2 db 128 dup (?) count dw ? TEMPDWORD dd ? TEMPDWORD2 dd ? cpr_kami db 80 dup (?) cpr_author db 80 dup (?) h avc_header_struc ? sux sux_struc ? ; --------------------------------------------------------------------------- bits dw ? len db ? next_byte_ptr dd ? ; --------------------------------------------------------------------------- UNPACKED_SIZE dd ? PACKED_SIZE dd ? UNPACKED db MAX_UNPACKED dup (?) PACKED db MAX_PACKED dup (?) ; =========================================================================== .code start: lea edx, initmsg call msg call parsecmdline cmp paramcount, 2 jne showsyntax lea ebx, cmd @@2: lea esi, command mov edi, [ebx] movzx ecx, byte ptr [edi] inc edi rep cmpsb jne @@1 jmp dword ptr [ebx + 4] @@1: add ebx, 8 cmp ebx, offset cmd_end jb @@2 badcmd: lea edx, badcmd_msg error: call msg call ExitProcess ; =========================================================================== showsyntax: lea edx, syntaxmsg jmp error error_1: lea edx, error1msg jmp error error_2: lea edx, error2msg jmp error error_3: lea edx, error3msg jmp error error_4: lea edx, error4msg jmp error ; ===================== cmdline ============================================= parsecmdline: call getcommandlinea mov esi, eax lea edi, paramstr0 call getparam mov paramcount, 0 lea edi, paramstr1 call getparam lea edi, paramstr2 call getparam ret ; parameters: ; <"some text"> getparam: mov ecx, -1 @@1: lodsb or al, al jz @@4 cmp al, 32 je @@1 dec esi @@3: lodsb stosb or al, al jz @@5 cmp al, '"' jne @@2 not ecx jmp @@3 @@2: jecxz @@3 cmp al, 32 jne @@3 sub [edi-1], al @@5: inc paramcount @@4: ret ; ===================== msg ================================================= ; input: EDX=msg msg: push 0 ; MB_OK push offset msgbox_title push edx push 0 call MessageBoxA ret ; ===================== hi-level file io ==================================== ; input: EDX=file name ; EBX=file pos ; EDI=buf ; ECX=bytes to read ; output:bytesread load: pushad push edi push ecx push ebx call fopen pop edx call fseek pop ecx pop edx call fread call fclose popad ret ; input: EDX=file name ; EBX=file pos/__create/__eof ; EDI=buf ; ECX=bytes to write ; output:byteswritten __create equ -1 __eof equ -2 save: pushad push edi push ecx cmp ebx, __create je @@1 push ebx call fopen pop edx cmp edx, __eof je @@3 call fseek jmp @@2 @@3: call fseekeof jmp @@2 @@1: call fcreate @@2: pop ecx pop edx call fwrite call fclose popad ret ; ===================== file io ============================================= ; input: EDX=file ; output: EBX=handle fopen: push 0 push 0 ; attr push 3 ; OPEN_EXISTING push 0 push 0 push 80000000h + 40000000h ; GENERIC_READ + GENERIC_WRITE push edx call CreateFileA xchg ebx, eax ret ; input: EDX=file ; output: EBX=handle fcreate: push 0 push 0 ; 0 push 1 ; CREATE push 0 push 0 push 80000000h + 40000000h ; GENERIC_READ + GENERIC_WRITE push edx call CreateFileA xchg ebx, eax ret ; input: EDX=position ; EBX=handle fseek: push 0 push 0 push edx push ebx call SetFilePointer ret ; input: EBX=handle fseekeof: push 2 push 0 push 0 push ebx call SetFilePointer ret ; input: EBX=handle fclose: push ebx call CloseHandle ret ; input: ECX=bytes to read ; EDX=buf ; EBX=handle ; output:EAX=bytes read fread: push 0 push offset bytesread push ecx push edx push ebx call ReadFile ret ; input: ECX=bytes to read ; EDX=buf ; EBX=handle ; output:bytes written fwrite: push 0 push offset byteswritten push ecx push edx push ebx call WriteFile ret ; ===================== unpack avc ========================================== unp_avc: lea edx, avcbase ; read kami cpr mov ebx, 0 lea edi, cpr_kami mov ecx, 64 call load lea edx, __cprkami ; write kami cpr mov ebx, __create lea edi, cpr_kami mov ecx, 64 call save lea edx, avcbase ; read author cpr mov ebx, 64 lea edi, cpr_author mov ecx, 64 call load lea edx, __cprauthor ; write author cpr mov ebx, __create lea edi, cpr_author mov ecx, 64 call save lea edx, avcbase ; read avc header mov ebx, 128 lea edi, h mov ecx, avc_header_size call load lea edx, __hdr ; write avc header mov ebx, __create lea edi, h mov ecx, avc_header_size call save mov count, 0 process_sux: movzx ecx, count ; generate file names call gen_sux_names ; calculate offset of sux header mov ebx, ecx imul ebx, sux_size add ebx, h.avc_sux_offs ; load sux header lea edx, avcbase lea edi, sux mov ecx, sux_size call load ; write suxheader lea edx, sux_hdr mov ebx, __create lea edi, sux mov ecx, sux_size call save mov eax, sux.sux_realsize cmp eax, max_unpacked ja error_3 ; read sux data lea edx, avcbase mov ebx, sux.sux_dataoffs mov ecx, sux.sux_datasize cmp ecx, MAX_PACKED ja error_1 lea edi, PACKED mov PACKED_SIZE, ecx call load ; unpack sux data call UNPACK_SUX mov ecx, UNPACKED_SIZE cmp ecx, sux.sux_realsize jne error_2 ; save sux data lea esi, suxxxx mov ecx, suxxxx_num @@2: lodsd xchg edx, eax lodsd xchg ebx, eax lodsd cmp bx, sux.sux_id jne @@3 cmp ax, -1 je @@1 cmp ax, sux.sux_id2 je @@1 @@3: loop @@2 lea edx, sux_unk @@1: mov ebx, __create lea edi, UNPACKED mov ecx, sux.sux_realsize call save inc count mov ax, count cmp ax, h.avc_sux_count jb process_sux ;; lea edx, unpackedavc_msg call msg call ExitProcess ; ===================== subprograms ========================================= ; gen_sux_names = ; input: ECX=number ; output: filenames hexchar db '0123456789ABCDEF' gen_sux_names: pushad lea edi, suxnum mov dl, 4 @@1: rol cx, 4 mov eax, ecx and eax, 15 mov al, hexchar[eax] stosb i = 1 rept suxN-1 mov byte ptr [edi-1 + 13*i], al i = i + 1 endm dec dl jnz @@1 popad ret ; --------------------- UNPACK_SUX ------------------------------------------ ; PACKED --> UNPACKED UNPACK_SUX: ; 1st pass -- UNXOR lea esi, PACKED mov ecx, PACKED_SIZE xor eax, eax unxor: xor [esi], al inc esi inc eax loop unxor ; 2nd pass -- UNPACK (optional) test h.avc_bits, 1 ; check bit 0 jnz exit_unpack_sux ; --------------------- unpacking ------------------------------------------- inbuf equ PACKED outbuf equ UNPACKED mov next_byte_ptr, offset inbuf lea edi, outbuf call avp_unpack sub edi, offset outbuf mov UNPACKED_SIZE, EDI ; --------------------- end of unpacking ------------------------------------ exit_unpack_sux: ret avp_unpack: call getbyte push eax ; CODE XREF: 0000:0CE3j call getbyte pop ebx ; CODE XREF: 0000:0D02j mov ah, bl xchg ah, al mov bits, ax mov len, 16 loc_0_D20: call get_bit ; CODE XREF: 0000:0D4Cj 0000:0D51j 0000:0E15j 0000:0E37j or ax, ax jz loc_0_D53 call getbyte mov [edi], al ; CODE XREF: 0000:0D36j inc edi cmp edi, offset outbuf + MAX_unpacked jne loc_0_d20 jmp exit loc_0_D53: call get_bit ; CODE XREF: 0000:0D25j or ax, ax jnz loc_0_D8F call get_bit shl ax, 1 mov si, ax call get_bit or si, ax add si, 2 call getbyte or ax, 0FF00h ; CODE XREF: 0000:0D78j mov dx, ax jmp loc_0_E19 loc_0_D8F: call getbyte loc_0_DAD: mov ah, 0 ; CODE XREF: 0000:0D9Ej mov dx, ax call getbyte mov ah, 0 ; CODE XREF: 0000:0DC0j mov si, ax and ax, 0FFF8h mov cl, 5 shl ax, cl or ax, 0E000h or dx, ax and si, 7 add si, 2 cmp si, 2 jnz loc_0_E19 call getbyte loc_0_E08: mov ah, 0 ; CODE XREF: 0000:0DF9j mov si, ax or si, si jz exit cmp si, 1 jnz loc_0_E18 jmp loc_0_D20 loc_0_E18: inc si ; CODE XREF: 0000:0E13j loc_0_E19: ; CODE XREF: 0000:0D8Cj 0000:0DE8j MOVsX EDX, DX add edx, edi jmp loc_0_E33 loc_0_E21: mov ebx, edx ; CODE XREF: 0000:0E35j mov al, [ebx] mov [edi], al inc edi dec si inc edx cmp edi, offset outbuf + MAX_unpacked ja exit loc_0_E33: or si, si ; CODE XREF: 0000:0E1Fj 0000:0E2Ej jg loc_0_E21 jmp loc_0_D20 exit: ret getbyte: push ebx mov ebx, next_byte_ptr; CODE XREF: 0000:0C8Cj mov al, [ebx] ; CODE XREF: 0000:0CDEj pop ebx inc next_byte_ptr ret get_bit: mov dx, bits; CODE XREF: 0000:0D20p 0000:0D53p 0000:0D5Ap 0000:0D61p and dx, 1 mov al, len add al, -1 mov len, al jnz shr_XXX call getbyte push ax ; CODE XREF: 0000:0E66j call getbyte pop bx ; CODE XREF: 0000:0E85j mov ah, bl xchg ah, al mov bits, ax mov len, 16 jmp c1 shr_XXX: shr bits, 1 ; CODE XREF: 0000:0E55j c1: mov ax, dx ; CODE XREF: 0000:0EA3j ret ; ===================== pack avc ============================================ pack_avc: ;; not implemented lea edx, packedavc_msg call msg call ExitProcess ; ===================== unpack lib ========================================= unp_lib: xor ebp, ebp mov count, 0 @@1: lea edx, avcbase ; .av5 lea edi, TEMPDWORD mov ecx, 8 mov ebx, ebp call load cmp bytesread, 0 je @@exit add ebp, 8 sub TEMPDWORD, 8 lea edx, avcbase lea edi, PACKED mov ecx, TEMPDWORD cmp ecx, MAX_PACKED+MAX_UNPACKED ja error_4 mov ebx, ebp call load inc count movzx ecx, word ptr count call gen_sux_names lea edx, sux_obj lea edi, PACKED mov ecx, TEMPDWORD mov ebx, __create call save add ebp, TEMPDWORD jmp @@1 @@exit: lea edx, unpackedlib_msg call msg call ExitProcess ; ===================== pack lib ========================================= pack_lib: ; not implemented lea edx, packedlib_msg call msg call ExitProcess end start