解码masm中的十六进制(空字节问题)

发布于 2024-11-26 11:59:06 字数 4529 浏览 1 评论 0原文

我正在尝试解码 masm 中的十六进制二进制字符串,一开始我尝试了 htodw 但解码不正确,所以我尝试了 hex2bin,这个似乎解码得很好,但我遇到了空字节问题。十六进制编码的字符串将在第一个空字节 (0x00) 处终止。

这是我的代码示例:

.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

如何解码任何类型的十六进制编码字符串,无论它包含什么类型的字符?

I am trying to decode an hexed binary string in masm, at first I tried htodw but that wasn't decoding it right, so I tried hex2bin and this one seems to decode fine but I have a problem with null bytes. The hex encoded string will be terminated at the first null byte (0x00).

Here's my code example:

.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

How could I decode any type of hex encoded string no matter what type of characters it contains?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嘿看小鸭子会跑 2024-12-03 11:59:06

无需使用多个查找表!

因此,仅使用一张 256 字节的带返回码的表:

<前><代码>; 0..0x0F = 字符到 bin 值
; 0x80 = 不可接受的字符
; 0x81 = 忽略字符(空格、减号和 CRLF)
; 0x82 = 注释字符 (;)

那应该可以解决你的问题!

编辑:添加代码

更改表为:

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

There is no need to use more than one lookup table!

So use only one tabe of 256 bytes with return codes:

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

That should solve your problem!

EDIT:added code

change table to:

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

Now you can get value and character attribute at once:

        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
凉风有信 2024-12-03 11:59:06

我前段时间这样做了:

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

我做了一些修改,就像你的测试代码一样。

I did this some time ago:

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

I did some modification to be like your test code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文