2011-07-28 1 views
4

masm에서 16 진수 바이너리 문자열을 디코딩하려고합니다. 처음에는 htodw를 시도했지만 올바르게 디코딩하지 않았으므로 hex2bin을 시도해 보았습니다. null 바이트에 문제가 있습니다. 16 진수로 인코딩 된 문자열은 첫 번째 null 바이트 (0x00)에서 종료됩니다.masm (null 바이트 문제)에서 16 진수를 디코딩

여기 내 코드 예제입니다 :

.486 
.model flat, stdcall 
option casemap :none 

include \masm32\include\windows.inc 
include \masm32\include\masm32.inc 
include \masm32\include\user32.inc 
include \masm32\include\kernel32.inc 
includelib \masm32\lib\kernel32.lib 
includelib \masm32\lib\masm32.lib 
includelib \masm32\lib\user32.lib 

.data 
; this string is "test(NULL BYTE)test", but the messagebox only shows "test" 
var_hex db "746573740074657374",0 

multitable \ 
    db 0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
    db 2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0 
    db 1,1,1,1,1,1,1,1,1,1,0,3,0,0,0,0 
    db 0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
    db 0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 

    ; 0 = unacceptable character 
    ; 1 = acceptable characters (0 to 9, A to F, a to f) 
    ; 2 = ignored characters  (space, minus and CRLF) 
    ; 3 = comment character  (;) 

    ; 1st offset table 
    db 00h,10h,20h,30h,40h,50h,60h,70h,80h,90h,0,0,0,0,0,0  ; 63 
    db 00h,0A0h,0B0h,0C0h,0D0h,0E0h,0F0h,0,0,0,0,0,0,0,0,0  ; 79 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0       ; 95 
    db 00h,0A0h,0B0h,0C0h,0D0h,0E0h,0F0h 

    ; 2nd offset table 
    db 00h,01h,02h,03h,04h,05h,06h,07h,08h,09h,0,0,0,0,0,0  ; 63 
    db 00h,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh,0,0,0,0,0,0,0,0,0   ; 79 
    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0       ; 95 
    db 00h,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh 

    ; add 256 for allowable character table 
    ; sub 48 from 1st offset table 
    ; add 7 for the second BYTE 

.data? 
var dd ? 

.code 
main: 
    Invoke hex2bin, addr var_hex, addr var 

    Invoke MessageBoxA,0,addr var,0,0 

    invoke ExitProcess, 0 


    ; hex2bin 
    align 4 

    hex2bin proc src:DWORD,dst:DWORD 

    comment * --------------------------------- 
      EAX and EBX are unused in loop code 
      --------------------------------- * 

     push ebx 
     push esi 
     push edi 
     push ebp 

     mov esi, src 
     mov edi, dst 

     xor ebp, ebp 

     jmp h2b        ; mispredicted only once 

     align 4 
     stripcomment: 
     add esi, 1 
     cmp BYTE PTR [esi], 10 
     jb zerofound      ; < 10 = 0 
     jne stripcomment     ; loop if not 10 
     align 4 
     pre: 
     add esi, 1 
     align 4 
     h2b: 
     movzx ebp, BYTE PTR [esi]   ; zero extend 1st byte into EBP 
     cmp BYTE PTR [ebp+multitable], 2 ; 1st compare short circuit on ignored characters 
     je pre        ; predicted backwards 
     movzx edx, BYTE PTR [esi+1]   ; zero extend 2nd BYTE into EDX 
     ja stripcomment      ; predicted backwards 

     mov cl, [ebp+multitable+208]  ; load 1st character into CL from 2nd table 
     add cl, [edx+multitable+263]  ; add value of second character from 3rd table 
     cmp BYTE PTR [ebp+multitable], 0 ; exit on error or ZERO 
     je error1       ; mispredicted only once 

     mov [edi], cl      ; write BYTE to output buffer 
     add esi, 2 
     add edi, 1 
     cmp BYTE PTR [edx+multitable], 1 ; test if second byte is allowable character 
     je h2b        ; predicted backwards 

     error2: 
     mov ecx, 2       ; error 2 = illegal character 
     jmp exitproc 
     error1: 
     test ebp, ebp      ; test if byte is terminator 
     jz zerofound 
     mov ecx, 1       ; error 1 = non matching hex character pairs 
     jmp exitproc 
     zerofound: 
     xor ecx, ecx      ; no error 0 

     exitproc: 

     pop ebp        ; restore EBP before using stack parameter 
     sub edi, dst 
     mov eax, edi 

     pop edi 
     pop esi 
     pop ebx 

     ret 

    hex2bin endp 

end main 

내가 아무리 진수로 인코딩 된 문자열의 모든 종류를 디코딩 할 수 없었다 어떻게 포함 된 문자의 종류?

답변

0

둘 이상의 찾아보기 테이블을 사용할 필요가 없습니다!

그래서 리턴 코드와 256 바이트의 한 타베를 사용

; 0..0x0F = char to bin value 
; 0x80 = unacceptable character 
; 0x81 = ignored characters  (space, minus and CRLF) 
; 0x82 = comment character  (;) 

문제를 해결해야한다고!

편집 : 추가 코드

변경 테이블에 : 이제

multitable \ 
    db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x80,0x81,0x80,0x80 
    db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 
    db 0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x80 
    db 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x80,0x82,0x80,0x80,0x80,0x80 
    db 0x80,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 
    db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 
    db 0x80,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 
    db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 
    db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 
    db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 
    db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 
    db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 
    db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 
    db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 
    db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 
    db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 

에게 한 번에 값과 문자 속성을 얻을 수 있습니다 :

 movzx ebp, BYTE PTR [esi]   ; zero extend 1st byte into EBP 
     mov cl, [ebp+multitable]   ; convert char to value or attribute 
     cmp cl, 0x0F      ; if cl > 0xF then attribute 
     ja AttributeFind     ; resolve Attribute 
              ; in cl is converted char from 0..15 
     inc esi       ; covert next char 
     movzx ebp, BYTE PTR [esi]   ; zero extend second byte into EBP 
     mov ch, [ebp+multitable]   ; convert char to value or attribute 
     cmp ch, 0x0F      ; if ch > 0xF then attribute 
     ja AttributeFind     ; resolve Attribute 
              ; in ch is converted char from 0..15 
;put together both nibbles in cl and ch 
     shl ch, 4       ;shift ch left by 4 
     or cl, ch 
;store byte result 
     mov BYTE PTR [edi], cl 
+0

@GJ : 당신이 말하는 것을 이해하지 못합니다. ode의 테이블 부분을 MASM libs 소스 코드에서 복사 했으므로 완전히 이해하지 못했습니다. 좀 더 명확한 예를 들어 주시겠습니까? – riviraz

+0

@riviraz : ok 내가 도와 줄 테스트되지 않은 코드의 일부를 추가했습니다. :) –

0

을 나는 몇 시간 전에이했던 :

include \masm32\include\masm32rt.inc 

.data 
var_hex db "746573740074657374",0 

.data? 
out_hex db ? 

.code 
String2Hex proc offstring:DWORD, outstring:DWORD 
    mov eax, offstring 
    xor ecx, ecx 
    mov ebx, outstring 
    .repeat 
     mov dh, byte ptr ds:[eax] 
     mov dl, byte ptr ds:[eax+1] 
     .if dl > 39h 
      sub dl, 37h 
     .else 
      sub dl, 30h 
     .endif 
     .if dh > 39h 
      sub dh, 37h 
     .else 
      sub dh, 30h 
     .endif 
     shl dl, 4 
     shr dx, 4 
     mov byte ptr ds:[ebx+ecx], dl 
     inc ecx 
     add eax, 2 
    .until byte ptr ds:[eax-1]==0 
    mov eax, ecx 
    ret 
String2Hex endp 

main: 
    Invoke String2Hex, addr var_hex, addr out_hex 
    Invoke MessageBoxA,0,addr out_hex,0,0 
    invoke ExitProcess, 0 
End main 

테스트 코드처럼 수정되었습니다.

+0

원본으로 모든 바이트를 공백으로 변환하지 않고 인코딩 된 문자열을 이진 문자열로 유지해야합니다. 원래 값을 수정하지 않고 디코딩하십시오. – riviraz

+0

'if'를 삭제하면 효과가 있습니다. 그러나 null로 끝나는 문자열이기 때문에 MessageBox에 표시되지 않습니다. – Diego

+0

이제는 문자를 바꿀 수 없습니다 – Diego

관련 문제