2017-12-12 9 views
1

내 프로그램은 바이너리를 기본 64로 인코딩해야합니다. 모든 것이 EOF까지 작동합니다. 출력 문자열 끝에 '='을 추가하는 데 문제가 있습니다.Nasm Linux x64-86 | 올바른 기본 64 인코딩을 위해 파일 끝에 비트를 추가하십시오.

이것은 마지막 바이트가 읽혀질 때만 발생해야합니다. 빈 공간을 채워야합니다. 여기에 하나 또는 두 개의 '='를 추가해야 할 때마다 코드를 추출합니다. 내에서 그래서

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 기능, 난 지금 내 '='바이트를 추가해야합니까? 어떻게하면 될까요?

+0

문제가 무엇인지 분명하지 않습니다. 확실히 당신은'mov [Bytes + 1], '=''등을 찾고 있지 않습니까? – Jester

+0

아니, 설명하는 법을 모르겠다. 내 영어는 그렇게 좋지 않다. – Arkarr

+0

32 비트 또는 64 비트입니까? –

답변

3

내 대답은 .. 그 코드는 항상 3 바이트를 먹었고, 0으로 채워지고, 나중에 결과를 수정/패치하기로되어있었습니다!

e.e. 단일 입력 Y이트 0x44의 경우 Bytes44 00 00으로 설정해야합니다 (첫 x0 44sys_read으로 설정되고 다른 두 개는 코드로 지워야 함). 잘못된 변환 결과 RAAA이 발생하고 올바른 RA==으로 패치해야합니다.

e.e.

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 

다시 짧고 간단하게 작성하여 성능을 많이 신경 쓰지 않습니다.

지침을 간단하게 만드는 방법은 버퍼 끝에 충분한 패딩을 두는 것입니다. 따라서 버퍼를 넘어 메모리를 덮어 쓰는 것에 대해 걱정할 필요가 없습니다. 그러면 각 출력 후에 두 개의 '=='을 쓸 수 있으며 원하는대로 배치 할 수 있습니다 place (두 개의 마지막 문자를 덮어 쓰거나 마지막 문자 하나를 덮어 쓰거나 출력 밖으로 완전히 씁니다.).

if (length == 1/2/3) {...} else {...}이 많지 않으면 코드 작성이 어려워 메모리 쓰기를 지키고 출력 버퍼 만 덮어 씁니다.

그래서 내가 한 일과 작동 방식을 이해하고 버퍼에 충분한 채우기를 추가하십시오.

...! 면책 조항! : 실제로 많은 수의 =이 base64 출력 끝 부분에 있어야하고, 그 시점은 base64 정의를 연구하는 OP입니다. 나는 단지 3B -> 4B 변환의 잘못된 출력을 수정하는 방법을 보여줄뿐입니다.이 변환은 0으로 채워진 짧은 입력을 사용합니다. 흠, online BASE64 generator에 따르면 실제로는 내 코드로 작동합니다. (입력 % 3) => 0은 =이고, 1은 =이며 2는 =입니다.

+0

예, '='를 추가하는 것이 옳습니다. 고맙습니다 ! – Arkarr

관련 문제