Nasm Linux x64-86 |在文件末尾添加位以进行正确的 base 64 编码

Nasm Linux x64-86 | Add bits at the end of file for correct base 64 encoding

我的程序应该将二进制文件编码为 base 64。 在 EOF 之前一切正常。我无法在输出字符串的末尾添加“=”。

只有在读取最后一个字节时才会发生这种情况。它应该填补空白 space。这是我的代码,每当我必须添加一个或两个'='时检测。

Read:
        mov eax,3               ; Specify sys_read call
        mov ebx,0               ; Specify File Descriptor 0: Standard Input
        mov ecx,Bytes           ; Pass offset of the buffer to read to
        mov edx,BYTESLEN        ; Pass number of bytes to read at one pass
        int 80h                 ; Call sys_read to fill the buffer
        mov ebp,eax             ; Save # of bytes read from file for later
        cmp rax,1               ; If EAX=0, sys_read reached EOF on stdin
        je MissingTwoByte   ; Jump If Equal (to 1, from compare)
        cmp rax,2               ; If EAX=0, sys_read reached EOF on stdin
        je MissingOneByte   ; Jump If Equal (to 2, from compare)
        cmp eax,0               ; If EAX=0, sys_read reached EOF on stdin
        je Done         ; Jump If Equal (to 0, from compare)

所以在我的 :MissingOneByte 和 :MissingTwoByte 函数中,我应该将我的 '=' 添加到 Bytes 中,对吗?我怎样才能做到这一点?

在我之前的回答中..该代码应该总是吃 3 个字节,用零填充,然后 fix/patch 结果!

即对于单个输入字节 0x44 需要将 Bytes 设置为 44 00 00 (第一个 44sys_read 设置,其他两个需要通过代码清除).你会得到错误的转换结果RAAA,然后你需要把它打补丁到正确的RA==.

SECTION .bss
BYTESLEN    equ     3           ; 3 bytes of real buffer are needed
Bytes:      resb    BYTESLEN + 5; real buffer +5 padding (total 8B)
B64output:  resb    4+4         ; 4 bytes are real output buffer
                                ; +4 bytes are padding (total 8B)

SECTION .text

        ;...
Read:
        mov     eax,3           ; Specify sys_read call
        xor     ebx,ebx         ; Specify File Descriptor 0: Standard Input
        mov     ecx,Bytes       ; Pass offset of the buffer to read to
        mov     edx,BYTESLEN    ; Pass number of bytes to read at one pass
        int     80h             ; Call sys_read to fill the buffer
        test    eax,eax
        jl      ReadingError    ; OS has problem, system "errno" is set
        mov     ebp,eax         ; Save # of bytes read from file for later
        jz      Done            ; 0 bytes read, no more input
        ; eax = 1, 2, 3
        mov     [ecx + eax],ebx ; clear padding bytes
            ; ^^ this is a bit nasty EBX reuse, works only for STDIN (0)
            ; for any file handle use fixed zero: mov word [ecx+eax],0
        call    ConvertBytesToB64Output     ; convert to Base64 output
        ; overwrite last two/one/none characters based on how many input
        ; bytes were read (B64output+3+1 = B64output+4 => beyond 4 chars)
        mov     word [B64output + ebp + 1], '=='
        ;TODO store B64output where you wish
        cmp     ebp,3
        je      Read            ; if 3 bytes were read, loop again
        ; 1 or 2 bytes will continue with "Done:"
Done:
        ; ...

ReadingError:
        ; ...

ConvertBytesToB64Output:
        ; ...
        ret

再次写得简短,不太关心性能。

使指令简单的诀窍是在缓冲区末尾有足够的填充,这样你就不用担心覆盖缓冲区以外的内存,然后你可以在每次输出后写两个'==',并且只需将其放置在所需位置(覆盖最后两个字符或最后一个字符,或将其完全写在输出之外,进入填充区域)。

如果没有它,可能很多 if (length == 1/2/3) {...} else {...} 会潜入代码,以保护内存写入,并且仅覆盖输出缓冲区,仅此而已。

所以请确保您了解我所做的及其工作原理,并为您自己的缓冲区添加足够的填充。

另外...!免责声明!:我实际上不知道有多少 = 应该在 base64 输出的末尾,以及什么时候...这取决于 OP 来研究 base64 定义。我只是展示如何修复 3B->4B 转换的错误输出,这需要用零填充的较短输入。嗯,根据 online BASE64 generator 它实际上是我的代码... (input%3) => 0 没有 =,1 有两个 =,2 有一个 [=20] =].