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

时间:2017-12-12 19:09:33

标签: linux assembly x86 64-bit nasm

我的程序应该将二进制文件编码为base 64。 一切正常,直到EOF。我有麻烦添加' ='在输出字符串的末尾。

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

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 my' =',对吧?我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:2)

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

即。对于单个输入字节0x44Bytes需要设置为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,它实际上可以作为我的代码...(输入%3)=> 0没有=,1有两个=,2有=