Guest User

Base64Encoder

a guest
Mar 1st, 2025
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ASM (NASM) 6.52 KB | Source Code | 0 0
  1. SECTION .data
  2. base64_map db "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  3.  
  4. %define SYS_EXIT 60
  5. %define SYS_READ 0
  6. %define SYS_WRITE 1
  7. %define STDOUT 1
  8. %define STDIN 0
  9. %define EQUALS 0x3D
  10. %define IBUF_SIZE 24576
  11. %define OBUF_SIZE 32768
  12.  
  13. SECTION .bss
  14. input_buffer resb IBUF_SIZE   ; Buffer for input (24 KB)
  15. output_buffer resb OBUF_SIZE   ; Buffer for output (32 KB)
  16.  
  17. SECTION .text
  18.    
  19. global main
  20.  
  21. main:
  22.     mov rbp, rsp
  23.     call base64_encode
  24.  
  25.     xor rax, rax        ; clear off rax
  26.     mov rax, 0xa        ; move the new line character to rax
  27.     mov [rsp+8], rax    ; put this on the stack
  28.     mov rdi, STDOUT     ; file descriptor = stdout
  29.     lea rsi, [rsp+8]    ; buffer = address to write to console
  30.     mov rdx, 0x1        ; number of bytes to write
  31.     mov rax, SYS_WRITE  ; SYSCALL number for writing to STDOUT
  32.     syscall             ; make the syscall
  33.  
  34.     mov rdi, 0          ; set exit status = 0
  35.     mov rax, SYS_EXIT   ; SYSCALL number for EXIT
  36.     syscall             ; make the syscall
  37.  
  38.  
  39. base64_encode:
  40.     push rax
  41.     push rbx
  42.     push rcx
  43.     push rdx
  44.     push rsi
  45.     push rdi
  46.     push r8
  47.     push r9
  48.    
  49.     xor r9, r9                              ; store number of bytes in output_buffer in r9, used to calculate offset
  50.     jmp read_buffer                         ; on first loop, we have nothing to write
  51.    
  52.     write_buffer:
  53.         mov rdi, STDOUT                     ; file descriptor = stout
  54.         mov rdx, r9                         ; number of bytes to write
  55.         mov rax, SYS_WRITE                  ; SYSCALL number to write to STDOUT
  56.         lea rsi, output_buffer              
  57.         syscall                             ; make the syscall
  58.         xor r9, r9                          ; reset r9
  59.    
  60.     read_buffer:
  61.         lea rsi, input_buffer               ; load address
  62.         mov rdi, STDIN                      ; file descriptor = stdin
  63.         mov rdx, IBUF_SIZE                  ; max number of bytes to read
  64.         mov rax, SYS_READ                   ; SYSCALL number for reading from STDIN
  65.         syscall
  66.         mov r8, rax                         ; store read byte count in r8, as rax will be used
  67.         lea rsi, input_buffer
  68.         cmp r8, IBUF_SIZE
  69.  
  70.     base64_encode_loop:
  71.         cmp r8, 0x3                         ; if number of bystes < 3, jump to handle_remainder
  72.         jl  check_end
  73.         jmp encoding_start
  74.        
  75.     check_end:
  76.         lea rax, [input_buffer + IBUF_SIZE]
  77.         cmp rax, rsi
  78.         jne write_buffer_end
  79.         jmp write_buffer
  80.        
  81.     encoding_start:
  82.         mov eax, [rsi]                      ; read memory into eax
  83.         sub r8, 3
  84.         add rsi, 3
  85.        
  86.         ; this block shifts aex from
  87.         ; ???????? ABCDEFGH IJKLMNOP QRSTUVWX
  88.         ; to
  89.         ; 00CDEFGH 00MNOPAB 00WXIJKL 00QRSTUV
  90.         mov ebx, eax
  91.         shl eax, 8
  92.         mov ecx, ebx
  93.         shr ecx, 6
  94.         and ecx, 0x00030000
  95.         and eax, 0x3F00FFFF
  96.         or eax, ecx
  97.         mov ecx, ebx
  98.         shl ecx, 10
  99.         and ecx, 0x003C0000
  100.         or eax, ecx
  101.         mov ecx, ebx
  102.         shl ax, 4
  103.         and ax, 0x3000
  104.         shr cx, 2
  105.         and ecx, 0x00003C3F
  106.         shr ch, 2
  107.         or eax, ecx
  108.        
  109.         ; encodes each byte of eax to ecx
  110.         xor ebx, ebx        
  111.         xor ecx, ecx
  112.         mov bl, al
  113.         mov cl, [base64_map + ebx]
  114.         mov bl, ah
  115.         mov ch, [base64_map + ebx]
  116.         shr eax, 16
  117.         mov bl, al
  118.         mov dl, [base64_map + ebx]
  119.         mov bl, ah
  120.         mov dh, [base64_map + ebx]
  121.         shl edx, 16
  122.         or ecx, edx
  123.        
  124.         lea rax, [output_buffer + r9]    ; load offset address in output_buffer
  125.         mov [rax], ecx                   ; write to output_buffer
  126.         add r9, 4                        ; increase number of bytes written
  127.        
  128.         ; jump back to the start of the loop
  129.         jmp base64_encode_loop
  130.        
  131.     write_buffer_end:
  132.         mov rbx, rsi                        ; store rsi, it will be needed
  133.         mov rdi, STDOUT                     ; file descriptor = stout
  134.         mov rdx, r9                         ; number of bytes to write
  135.         mov rax, SYS_WRITE                  ; SYSCALL number to write to STDOUT
  136.         lea rsi, output_buffer              
  137.         syscall                             ; make the syscall
  138.         mov rsi, rbx
  139.  
  140.  
  141.     handle_remainder:
  142.         mov eax, [rsi]                      ; read memory into eax
  143.         cmp r8, 0
  144.         je routine_end                      ; if no bytes were read, jump to end
  145.         cmp r8, 2
  146.         je two_bytes
  147.         and eax, 0x000000FF
  148.     two_bytes:
  149.         and eax, 0x0000FFFF
  150.        
  151.         ; i was to lazy to adapt the routine to 2 and 1 bytes
  152.         ; this only gets executed once so it doesn't have a huge performance impact
  153.         mov ebx, eax
  154.         shl eax, 8
  155.         mov ecx, ebx
  156.         shr ecx, 6
  157.         and ecx, 0x00030000
  158.         and eax, 0x3F00FFFF
  159.         or eax, ecx
  160.         mov ecx, ebx
  161.         shl ecx, 10
  162.         and ecx, 0x003C0000
  163.         or eax, ecx
  164.         mov ecx, ebx
  165.         shl ax, 4
  166.         and ax, 0x3000
  167.         shr cx, 2
  168.         and ecx, 0x00003C3F
  169.         shr ch, 2
  170.         or eax, ecx
  171.        
  172.         xor ebx, ebx        
  173.         xor ecx, ecx
  174.         mov bl, al
  175.         mov cl, [base64_map + ebx]
  176.         mov bl, ah
  177.         mov ch, [base64_map + ebx]
  178.         shr eax, 16
  179.        
  180.         cmp r8, 2
  181.         je encode_2_bytes                          ; if 2 bytes were written, jump
  182.        
  183.     encode_1_byte:
  184.         ; encodes each byte of eax to ecx
  185.         mov dl, EQUALS
  186.         mov dh, EQUALS
  187.         shl edx, 16
  188.         or ecx, edx
  189.         jmp write_end
  190.     encode_2_bytes:
  191.         ; encodes each byte of eax to ecx
  192.         mov bl, al
  193.         mov dl, [base64_map + ebx]
  194.         mov dh, EQUALS
  195.         shl edx, 16
  196.         or ecx, edx
  197.        
  198.     write_end:
  199.         ; write remainder in ecx to stdout
  200.         mov rdi, STDOUT                     ; file descriptor = stout
  201.         mov rdx, 0x4                        ; number of bytes to write
  202.         mov rax, SYS_WRITE                  ; SYSCALL number to write to STDOUT
  203.         mov [rsi], ecx                      ; write data to stack
  204.         syscall                             ; make the syscall
  205.         jmp routine_end
  206.        
  207.     routine_end:
  208.         pop r8
  209.         pop r9
  210.         pop rdi
  211.         pop rsi
  212.         pop rdx
  213.         pop rcx
  214.         pop rbx
  215.         pop rax
Add Comment
Please, Sign In to add comment