在nasm中解码base64

时间:2017-12-29 10:22:02

标签: linux assembly base64 nasm x86-64

[解码后输出的链接。 ] [1]代码开始很好然后变为bezerk然后恢复正常。它旨在将base64 nasm转换为其原始形式。我将收到的第一个字节(在rax寄存器中的ASCII中)转换为Base64以获得二进制等效值。为两位腾出空间,然后在rbx中取下一个字节并执行相同的操作。然后获取rbx中的前两位并添加到第一个字节以获取ASCII等效值并保存结果。由于此问题,我无法使用=处理文件末尾。 谢谢你的帮助。

 ;  Build using these commands:
 ;    nasm -f elf64 -g -F dwarf decode.asm
 ;    ld -o decode decode.o

%macro writeIt 0
          add al,bl                 ; add bl to al because upper rbx contains the rest
          mov byte[B64LIN+rcx-1],al ; move the equivalent into B64LIN
%endmacro
        ; ************************************************************************
        ;;; Note: This process does automatic conversion into ASCII ##############
        ; ************************************************************************

%macro clear 1
   xor %1,%1
%endmacro


SECTION .bss        ; Section containing uninitialized data

 BUFFLEN equ 4
 Buff: resb  BUFFLEN

SECTION .data           ; Section containing initialised data

  B64LIN:       db "000",0  ; used for output
  B64LEN:       EQU $-B64LIN ; only used to determine the size of the string treated

SECTION .text   ; Section containing code

           ;;; We convert ASCII to Base 64
Base64:
   .UpperCase:              ; remove 65 to convert match the B64Table
       sub rax,65
       ret

   .LowerCase:           ; remove 71 to convert match the B64Table
        sub rax,71
        ret

    .Numbers:                ; add 4 for numbers
        add rax,4
        ret

    .Addition:               ; remove 62 to convert match the B64Table
        sub rax,62
        ret

    .BackSlash:          ; remove 63 to convert match the B64Table
        sub rax,63
        ret



 ;------------------------------------------------------------------------
        ; Encode:       Enconde binary datas into Base 64
        ; UPDATED:      15/12/2017
        ; IN:           File
        ; RETURNS:      ASCII VERSION
        ; MODIFIES:     ASCII to Base 64

        ;;; Behaves like a switch statement
        ;;; Look for the equivalent Base64
        Convert:
            cmp rax,61h
            jge Base64.LowerCase

            cmp rax,41h
            jge Base64.UpperCase

            cmp rax,3Dh
            je .EOF1

            cmp rax,30h
            jge Base64.Numbers

            cmp rax, 2Bh
            je Base64.Addition

            cmp rax,2Fh
            je Base64.BackSlash

            cmp rax,rbx       ; comparing rbx to rax for zeros
            je Exit                 ; we're done if that happens


        ; *****************************************************************************
        ;;; Note: This process doesn't send any values back because it was added to the
        ;;;       file in the encoding process. ##############
        ; *****************************************************************************
          .EOF1:
            clear rax
            writeIt
            ret

            ;;; Register clean up
        Decode:
            ;;; Treating 1st Byte
          mov al,byte[Buff+rcx] ; takes in the first element in the input
          call Convert                  ; convert to get their Base64 value

        ;;; Treating 2nd Byte
          inc rcx                       ; increment to get the next element in the Buff
          mov bl,byte[Buff+rcx] ; moves second element into rbx
          xchg al,bl                ; xchg rax with rbx because Convert deals with rax
          call Convert          ; call Convert to get the base64 equiv.
          xchg bl,al                ; get the values back and exchange them
          rol rax,2                 ; make room for the first 2 bits in rbx
          ror rbx,4                 ; keep only the top four since first 2 bits are 00
          writeIt
          clear bl                  ; clear bl so we can role back
          rol rbx,8                 ; role 8 so we already make room when we moves rax

            ;;; Treating 3rd Byte
          inc rcx                     ; increment to get the next element
          mov al,byte[Buff+rcx] ; moves it directly into al since previous element is gone
          call Convert          ; Converts to Base64
          ror rax,2               ; roll right to get the top 4 bits only
          xchg rax,rbx          ; xchg so even the top bits are kept in the process
          writeIt

            ;;; Treating 4th Byte
          clear bl                ; clear lower 4 bits
              clear rax         ; clears everything since we have no use for it
          inc rcx                     ; increments to get next
          mov al,byte[Buff+rcx] ; moves next Byte into al
          call Convert          ; converts to Base64 equiv.
          rol rbx,8               ; make room for last 2 bits coming
          writeIt
          ret


            ;;; code keeps on running onto PrintLine to finish off

        ;-------------------------------------------------------------------------
        ; IN:           Nothing
        ; RETURNS:      The Original text
        ; MODIFIES:     Nothing
        ; CALLS:        Kernel sys_write

        PrintLine:
            push rax           ; Save all used registers
            push rbx           ; Save all used registers
            push rcx           ; Save all used registers
            push rdx           ; Save all used registers
            mov rax,4        ; Specify sys_write call
            mov rbx,1          ; Specify File Descriptor 1: Standard output
            mov rcx,B64LIN ; Pass offset of line string
            mov rdx,B64LEN ; Pass size of the line string
            int 80h          ; Make kernel call to display line string
            pop rdx          ; Restore all caller's registers
            pop rcx          ; dito
            pop rbx          ; dito
            pop rax          ; dito
            ret                ; Return to caller


        ;-------------------------------------------------------------------------


        LoadBuff:
            push rax        ; Save caller's EAX
            push rbx        ; Save caller's EBX
            push rdx        ; Save caller's EDX

            mov rax,3       ; Specify sys_read call
            mov rbx,0           ; Specify File Descriptor 0: Standard Input
            mov rcx,Buff    ; Pass offset of the buffer to read to
            mov rdx,BUFFLEN ; Pass number of bytes to read at one pass
            int 80h         ; Call sys_read to fill the buffer
            mov rbp, rax    ; Save # of bytes read from file for later
            xor rcx,rcx   ; Clear buffer pointer ECX to 0
            pop rdx         ; Restore caller's EDX
            pop rbx         ; Restore caller's EBX
            pop rax         ; Restore caller's EAX
            ret               ; And return to caller


        GLOBAL _start
        ; ------------------------------------------------------------------------
        ; MAIN PROGRAM BEGINS HERE
        ;-------------------------------------------------------------------------
        _start:
        ; We will stay into this loop until the buffer is empty
        Read:
            call LoadBuff    ; Read first buffer of data from stdin
            cmp rbp,0          ; If ebp=0, sys_read reached EOF on stdin
            jbe Exit           ; If ebp=0, we jumps to Exit
            call Decode    ; If there's still some data into the buffer, we call Encode to convert them
            call PrintLine ; Save the enconded data into stdout
            clear rbp        ; Clear ebp for the next LoadBuff
            jmp Read           ; Read one more time the data from stdi


        ; The programm did his job, we can exit
        Exit:
            xor rax, rax     ; Clear rax
            xor rbx, rbx     ; Clear rbx
            mov rax,1          ; Code for Exit Syscall
            mov rbx,0            ; Return a code of zero
            int 0x80             ; Make kernel call`


      [1]: https://i.stack.imgur.com/bHJnI.jpg

0 个答案:

没有答案