【问题标题】:Nasm Linux x64-86 | Add bits at the end of file for correct base 64 encodingNasm Linux x64-86 |在文件末尾添加位以进行正确的 base 64 编码
【发布时间】:2018-05-26 13:37:57
【问题描述】:

我的程序应该将二进制文件编码为 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 中,对吗?我怎样才能做到这一点?

【问题讨论】:

  • 不清楚您的问题是什么。您确定不是在寻找mov [Bytes+1], '=' 之类的吗?
  • 不,我真的不知道怎么解释,我的英语不太好。
  • 这是 32 位还是 64 位?
  • 它在 Linux 64 位上!
  • 您的代码使用 32 位 int 0x80,因此如果您继续将其构建为 64b 二进制文件,您可能(并且很可能将)遇到问题:@987654321 @(例如,您的二进制文件肯定不能在 Windows10 linux“子系统”中运行,打包的 Ubuntu 仅支持 64b,不支持int 0x80,而使用控制台 stdin/stdout 的正确 64b 二进制文件可以)跨度>

标签: linux assembly x86 64-bit nasm


【解决方案1】:

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

即对于单个输入字节0x44,Bytes 需要设置为44 00 00(第一个44 由sys_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 有一个=。

【讨论】:

  • 是的,添加 '=' 的数量是正确的。谢谢!
猜你喜欢
  • 2016-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-25
  • 2019-06-19
  • 1970-01-01
  • 1970-01-01
  • 2011-11-19
相关资源
最近更新 更多