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 24576
- %define OBUF_SIZE 32768
- SECTION .bss
- input_buffer resb IBUF_SIZE ; Buffer for input (24 KB)
- output_buffer resb OBUF_SIZE ; Buffer for output (32 KB)
- SECTION .text
- global main
- main:
- mov rbp, rsp
- call base64_encode
- xor rax, rax ; clear off rax
- mov rax, 0xa ; move the new line character to rax
- mov [rsp+8], rax ; put this on the stack
- mov rdi, STDOUT ; file descriptor = stdout
- lea rsi, [rsp+8] ; buffer = address to write to console
- mov rdx, 0x1 ; number of bytes to write
- mov rax, SYS_WRITE ; SYSCALL number for writing to STDOUT
- syscall ; make the syscall
- 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
- jmp read_buffer ; on first loop, we have nothing to write
- write_buffer:
- 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 r9
- read_buffer:
- lea rsi, input_buffer ; load address
- mov rdi, STDIN ; file descriptor = stdin
- mov rdx, IBUF_SIZE ; max number of bytes to read
- mov rax, SYS_READ ; SYSCALL number for reading from STDIN
- syscall
- mov r8, rax ; store read byte count in r8, as rax will be used
- lea rsi, input_buffer
- cmp r8, IBUF_SIZE
- base64_encode_loop:
- cmp r8, 0x3 ; if number of bystes < 3, jump to handle_remainder
- jl check_end
- jmp encoding_start
- check_end:
- lea rax, [input_buffer + IBUF_SIZE]
- cmp rax, rsi
- jne write_buffer_end
- jmp write_buffer
- encoding_start:
- mov eax, [rsi] ; read memory into eax
- sub r8, 3
- add rsi, 3
- ; this block shifts aex from
- ; ???????? ABCDEFGH IJKLMNOP QRSTUVWX
- ; to
- ; 00CDEFGH 00MNOPAB 00WXIJKL 00QRSTUV
- mov ebx, eax
- shl eax, 8
- mov ecx, ebx
- shr ecx, 6
- and ecx, 0x00030000
- and eax, 0x3F00FFFF
- or eax, ecx
- mov ecx, ebx
- shl ecx, 10
- and ecx, 0x003C0000
- or eax, ecx
- mov ecx, ebx
- shl ax, 4
- and ax, 0x3000
- shr cx, 2
- and ecx, 0x00003C3F
- shr ch, 2
- or eax, ecx
- ; encodes each byte of eax to ecx
- xor ebx, ebx
- xor ecx, ecx
- mov bl, al
- mov cl, [base64_map + ebx]
- mov bl, ah
- mov ch, [base64_map + ebx]
- shr eax, 16
- mov bl, al
- mov dl, [base64_map + ebx]
- mov bl, ah
- mov dh, [base64_map + ebx]
- shl edx, 16
- or ecx, edx
- 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
- two_bytes:
- and eax, 0x0000FFFF
- ; i was to lazy to adapt the routine to 2 and 1 bytes
- ; this only gets executed once so it doesn't have a huge performance impact
- mov ebx, eax
- shl eax, 8
- mov ecx, ebx
- shr ecx, 6
- and ecx, 0x00030000
- and eax, 0x3F00FFFF
- or eax, ecx
- mov ecx, ebx
- shl ecx, 10
- and ecx, 0x003C0000
- or eax, ecx
- mov ecx, ebx
- shl ax, 4
- and ax, 0x3000
- shr cx, 2
- and ecx, 0x00003C3F
- shr ch, 2
- or eax, ecx
- xor ebx, ebx
- xor ecx, ecx
- mov bl, al
- mov cl, [base64_map + ebx]
- mov bl, ah
- mov ch, [base64_map + ebx]
- shr eax, 16
- cmp r8, 2
- je encode_2_bytes ; if 2 bytes were written, jump
- encode_1_byte:
- ; encodes each byte of eax to ecx
- mov dl, EQUALS
- mov dh, EQUALS
- shl edx, 16
- or ecx, edx
- jmp write_end
- encode_2_bytes:
- ; encodes each byte of eax to ecx
- mov bl, al
- mov dl, [base64_map + ebx]
- mov dh, EQUALS
- shl edx, 16
- or ecx, edx
- write_end:
- ; 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
- mov [rsi], ecx ; write data to stack
- 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