Files
Elpisdev_unarchive/bar.asm
T
Eren 9742c47cb7 xd
xd
2024-11-14 23:30:43 +03:00

340 lines
6.7 KiB
NASM

section .data
FILENAME_SIZE equ 256
section .bss
bar_num_files resw 1
bar_file_size resd 1
bar_bytes_remaining resd 1
bar_filename_buffer resb FILENAME_SIZE
bar_temp_filename resb FILENAME_SIZE
bar_check1 resd 1
bar_check2 resd 1
bar_current_dir resb 260
section .text
extract_bar:
push ebp
mov ebp, esp
push 0
push bytes_read
push 10
push header_buffer
push dword [file_handle]
call _ReadFile@20
test eax, eax
jz cleanup
push 0
push bytes_read
push 2
push bar_num_files
push dword [file_handle]
call _ReadFile@20
test eax, eax
jz cleanup
bar_extract_loop:
movzx ecx, word [bar_num_files]
test ecx, ecx
jz cleanup
push 0
push bytes_read
push FILENAME_SIZE
push bar_filename_buffer
push dword [file_handle]
call _ReadFile@20
test eax, eax
jz cleanup
call bar_process_filename
push 0
push bytes_read
push 8
push bar_check1
push dword [file_handle]
call _ReadFile@20
call bar_read_file_size
test eax, eax
jz cleanup
call bar_create_output_path
call bar_extract_file_data
test eax, eax
jz cleanup
dec word [bar_num_files]
jmp bar_extract_loop
.invalid_format:
push 0
push bytes_written
push msg_invalid_bar_len
push msg_invalid_bar
push dword [stdout_handle]
call _WriteFile@20
jmp cleanup
bar_process_filename:
push ebp
mov ebp, esp
mov al, [bar_filename_buffer + FILENAME_SIZE - 1]
cmp al, 0xFE
je .fe_format
mov esi, bar_filename_buffer
mov edi, bar_temp_filename
mov ecx, FILENAME_SIZE - 4
rep movsb
mov byte [edi], 0
push FILE_CURRENT
push 0
push -4
push dword [file_handle]
call _SetFilePointer@16
cmp eax, 0xFFFFFFFF
je .error
jmp .clean_filename
.fe_format:
mov esi, bar_filename_buffer
mov edi, bar_temp_filename
.find_fe:
lodsb
cmp al, 0xFE
je .fe_found
stosb
cmp esi, bar_filename_buffer + FILENAME_SIZE
jb .find_fe
.fe_found:
mov byte [edi], 0
.clean_filename:
mov edi, bar_temp_filename
xor edx, edx
.trim_loop:
mov al, [edi]
test al, al
jz .trim_done
cmp al, ' '
je .next_trim
cmp al, '.'
je .next_trim
cmp al, 9
je .next_trim
cmp al, 13
je .next_trim
cmp al, 10
je .next_trim
mov edx, edi
.next_trim:
inc edi
cmp edi, bar_temp_filename + FILENAME_SIZE
jb .trim_loop
.trim_done:
mov edi, edx
inc edi
mov byte [edi], 0
mov edi, bar_temp_filename
.convert_slashes:
mov al, [edi]
test al, al
jz .done
cmp al, '\\'
jne .next_char
mov byte [edi], '/'
.next_char:
inc edi
jmp .convert_slashes
.done:
mov esp, ebp
pop ebp
ret
.error:
mov esp, ebp
pop ebp
ret
bar_read_file_size:
push ebp
mov ebp, esp
push 0
push bytes_read
push 4
push bar_file_size
push dword [file_handle]
call _ReadFile@20
test eax, eax
jz .error
push 0
push bytes_read
push 4
push bar_check1
push dword [file_handle]
call _ReadFile@20
mov esp, ebp
pop ebp
ret
.error:
mov esp, ebp
pop ebp
ret
bar_create_output_path:
push ebp
mov ebp, esp
mov esi, input_file
mov edi, output_path
.copy_path:
lodsb
stosb
test al, al
jnz .copy_path
dec edi
mov esi, extract_suffix
mov ecx, extract_suffix_len
rep movsb
mov byte [edi], '/'
inc edi
mov esi, bar_temp_filename
.copy_name:
lodsb
test al, al
jz .done
stosb
jmp .copy_name
.done:
mov byte [edi], 0
mov esi, output_path
mov edi, bar_current_dir
.create_dirs:
lodsb
stosb
test al, al
jz .dirs_done
cmp al, '/'
jne .create_dirs
mov byte [edi-1], 0
push eax
push 0
push bar_current_dir
call _CreateDirectoryA@8
pop eax
mov byte [edi-1], '/'
jmp .create_dirs
.dirs_done:
mov esp, ebp
pop ebp
ret
bar_extract_file_data:
push ebp
mov ebp, esp
push 0
push bytes_written
push msg_extract_len
push msg_extract
push dword [stdout_handle]
call _WriteFile@20
mov esi, output_path
call string_length
push 0
push bytes_written
push eax
push output_path
push dword [stdout_handle]
call _WriteFile@20
push 0
push bytes_written
push msg_newline_len
push msg_newline
push dword [stdout_handle]
call _WriteFile@20
push 0
push FILE_ATTRIBUTE_NORMAL
push CREATE_ALWAYS
push 0
push 0
push GENERIC_WRITE
push output_path
call _CreateFileA@28
cmp eax, INVALID_HANDLE_VALUE
je .error
mov ebx, eax
mov ecx, [bar_file_size]
mov [bar_bytes_remaining], ecx
.copy_loop:
mov eax, CHUNK_SIZE
cmp [bar_bytes_remaining], eax
jb .last_chunk
jmp .do_copy
.last_chunk:
mov eax, [bar_bytes_remaining]
.do_copy:
push 0
push bytes_read
push eax
push chunk_buffer
push dword [file_handle]
call _ReadFile@20
test eax, eax
jz .error
push 0
push bytes_written
push dword [bytes_read]
push chunk_buffer
push ebx
call _WriteFile@20
test eax, eax
jz .error
mov eax, [bytes_read]
sub [bar_bytes_remaining], eax
jnz .copy_loop
push ebx
call _CloseHandle@4
mov eax, 1
jmp .done
.error:
push ebx
call _CloseHandle@4
xor eax, eax
.done:
mov esp, ebp
pop ebp
ret