Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- SECTION .data
- base64_map db "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
- %define SYS_EXIT 60
- %define SYS_READ 0
- %define SYS_WRITE 1
- %define STDOUT 1
- %define STDIN 0
- %define EQUALS 0x3D
- %define IBUF_SIZE 49152
- %define OBUF_SIZE 65536
- SECTION .bss
- input_buffer resb IBUF_SIZE ; Buffer for input (48 KB)
- output_buffer resb OBUF_SIZE ; Buffer for output (64 KB)
- SECTION .text
- global main
- main:
- mov rbp, rsp
- call base64_encode
- mov rdi, 0 ; set exit status = 0
- mov rax, SYS_EXIT ; SYSCALL number for EXIT
- syscall ; make the syscall
- base64_encode:
- push rax
- push rbx
- push rcx
- push rdx
- push rsi
- push rdi
- push r8
- push r9
- xor r9, r9 ; store number of bytes in output_buffer in r9, used to calculate offset
- xor r8, r8 ; store bytes left in read buffer
- jmp read_buffer ; on first loop, we have nothing to write
- write_buffer:
- mov rbx, rsi ; store read address (required for remainder)
- mov rdi, STDOUT ; file descriptor = stout
- mov rdx, r9 ; number of bytes to write
- mov rax, SYS_WRITE ; SYSCALL number to write to STDOUT
- lea rsi, output_buffer
- syscall ; make the syscall
- xor r9, r9 ; reset write buffer count
- mov rsi, rbx ; load back read address
- read_buffer:
- mov ax, [rsi]
- mov [input_buffer], ax ; put remainder at the start of the buffer
- lea rsi, [input_buffer + r8] ; load address
- mov rdi, STDIN ; file descriptor = stdin
- mov rdx, IBUF_SIZE
- sub rax, r8 ; max number of bytes to read
- mov rax, SYS_READ ; SYSCALL number for reading from STDIN
- syscall
- add r8, rax ; store read byte count in r8, as rax will be used
- lea rsi, input_buffer
- cmp rax, 0
- je handle_remainder ; if no bytes were read, eof was reached --> encode remainder
- base64_encode_loop:
- cmp r8, 0x3 ; if number of bystes < 3, write output buffer (and read new input buffer)
- jl write_buffer
- encoding_start:
- mov eax, [rsi] ; read memory into eax
- sub r8, 3
- add rsi, 3
- ; initial state aex: ???????? ABCDEFGH IJKLMNOP QRSTUVWX
- ; encoding order: 00CDEFGH 00MNOPAB 00WXIJKL 00QRSTUV
- ; encode last byte
- mov ebx, eax
- shr ebx, 16 ; 00000000 00000000 ???????? ABCDEFGH
- and ebx, 0x0000003F ; 00000000 00000000 00000000 00CDEFGH
- mov ch, [base64_map + ebx] ; ???????? ???????? 33333333 ????????
- mov ebx, eax
- shr ebx, 16 ; 00000000 00000000 ???????? ABCDEFGH
- mov bh, ah ; 00000000 00000000 IJKLMNOP ABCDEFGH
- shr bx, 6 ; 00000000 00000000 000000IJ KLMNOPAB
- and ebx, 0x0000003F ; 00000000 00000000 00000000 00MNOPAB
- mov cl, [base64_map + ebx] ; ???????? ???????? 33333333 22222222
- shl ecx, 16 ; 33333333 22222222 00000000 00000000
- mov bh, al ; 00000000 00000000 QRSTUVWX 00MNOPAB
- mov bl, ah ; 00000000 00000000 QRSTUVWX IJKLMNOP
- shr bx, 4 ; 00000000 00000000 0000QRST UVWXIJKL
- and ebx, 0x0000003F ; 00000000 00000000 00000000 00WXIJKL
- mov ch, [base64_map + ebx] ; 33333333 22222222 11111111 00000000
- shr eax, 2 ; 00?????? ??ABCDEF GHIJKLMN OPQRSTUV
- and eax, 0x0000003F ; 00000000 00000000 00000000 00QRSTUV
- mov cl, [base64_map + eax] ; 33333333 22222222 11111111 00000000
- lea rax, [output_buffer + r9] ; load offset address in output_buffer
- mov [rax], ecx ; write to output_buffer
- add r9, 4 ; increase number of bytes written
- ; jump back to the start of the loop
- jmp base64_encode_loop
- write_buffer_end:
- mov rbx, rsi ; store rsi, it will be needed
- mov rdi, STDOUT ; file descriptor = stout
- mov rdx, r9 ; number of bytes to write
- mov rax, SYS_WRITE ; SYSCALL number to write to STDOUT
- lea rsi, output_buffer
- syscall ; make the syscall
- mov rsi, rbx
- handle_remainder:
- mov eax, [rsi] ; read memory into eax
- cmp r8, 0
- je routine_end ; if no bytes were read, jump to end
- cmp r8, 2
- je two_bytes
- and eax, 0x000000FF
- mov ch, EQUALS
- mov cl, EQUALS
- shl ecx, 16
- mov bh, al
- mov bl, ah
- shr bx, 4
- and ebx, 0x0000003F
- mov ch, [base64_map + ebx]
- shr eax, 2
- and eax, 0x0000003F
- mov cl, [base64_map + eax]
- jmp write_end
- two_bytes:
- and eax, 0x0000FFFF
- mov ch, EQUALS
- mov ebx, eax
- shr ebx, 16
- mov bh, ah
- shr bx, 6
- and ebx, 0x0000003F
- mov cl, [base64_map + ebx]
- shl ecx, 16
- mov bh, al
- mov bl, ah
- shr bx, 4
- and ebx, 0x0000003F
- mov ch, [base64_map + ebx]
- shr eax, 2
- and eax, 0x0000003F
- mov cl, [base64_map + eax]
- write_end:
- lea rsi, [output_buffer] ; load offset address in output_buffer
- mov [rsi], ecx ; write to output_buffer
- ; write remainder in ecx to stdout
- mov rdi, STDOUT ; file descriptor = stout
- mov rdx, 0x4 ; number of bytes to write
- mov rax, SYS_WRITE ; SYSCALL number to write to STDOUT
- syscall ; make the syscall
- jmp routine_end
- routine_end:
- pop r8
- pop r9
- pop rdi
- pop rsi
- pop rdx
- pop rcx
- pop rbx
- pop rax
Add Comment
Please, Sign In to add comment