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

String 在masm中解码十六进制(空字节问题),string,assembly,hex,masm,masm32,String,Assembly,Hex,Masm,Masm32,我正在尝试在masm中解码一个经过十六进制处理的二进制字符串,起初我尝试了htodw,但没有正确解码,所以我尝试了hex2bin,这一个似乎解码得很好,但我遇到了空字节的问题。十六进制编码字符串将在第一个空字节(0x00)处终止 下面是我的代码示例: .486 .model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\include\masm32.inc inc

我正在尝试在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
.486
.平板模型,标准球
选项案例图:无
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
.数据
; 此字符串为“test(NULL BYTE)test”,但messagebox仅显示“test”
var_hex db“7465737400746573774”,0
多任务\
db 0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
分贝2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0
db 1,1,1,1,1,1,1,1,1,1,1,0,3,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=不可接受的字符
; 1=可接受的字符(0到9,A到F,A到F)
; 2=忽略的字符(空格、减号和CRLF)
; 3=注释字符(;)
; 第一偏移表
分贝00h、10h、20h、30h、40h、50h、60h、70h、80h、90h、0,0,0,0;63
分贝00h,0A0h,0B0h,0D0h,0E0h,0F0h,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
; 第二偏移表
分贝00h,01h,02h,03h,04h,05h,06h,07h,08h,09h,0,0,0,0;63
分贝00h,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh,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
; 为允许的字符表添加256
; 第1偏移表中的sub 48
; 第二个字节加7
.数据?
var dd?
.代码
主要内容:
调用hex2bin,addr var_hex,addr var
调用MessageBoxA,0,地址变量,0,0
调用ExitProcess,0
; 合二宾
对齐4
hex2bin proc src:DWORD,dst:DWORD
评论*---------------------------------
EAX和EBX是未使用的循环代码
--------------------------------- *
推ebx
推动esi
推式电子数据交换
推ebp
动画片
mov edi,dst
异或ebp,ebp
jmp-h2b;只有一次预测失误
对齐4
评论:
添加esi,1
cmp字节PTR[esi],10
jb zerofound;<10 = 0
jne评论;如果不是10,则循环
对齐4
之前:
添加esi,1
对齐4
h2b:
movzx ebp,字节PTR[esi];零将第1字节扩展到EBP
cmp字节PTR[ebp+多任务],2;第一次比较忽略字符上的短路
日本脑炎前期;反向预测
movzx-edx,字节PTR[esi+1];零将第2字节扩展到EDX
评论;反向预测
mov cl,[ebp+多表+208];将第二个表中的第一个字符加载到CL中
添加cl,[edx+多表+263];添加第三个表中第二个字符的值
cmp字节PTR[ebp+多任务],0;错误或为零时退出
je错误1;只有一次预测失误
mov[edi],cl;将字节写入输出缓冲区
添加esi,2
添加edi,1
cmp字节PTR[edx+多任务],1;测试第二个字节是否为允许字符
日本脑炎h2b;反向预测
错误2:
mov-ecx,2;错误2=非法字符
jmp exitproc
错误1:
测试ebp,ebp;测试字节是否为终止符
jzzerofound
mov-ecx,1;错误1=不匹配的十六进制字符对
jmp exitproc
zerofound:
异或ecx,ecx;无错误0
出口程序:
pop-ebp;在使用堆栈参数之前恢复EBP
电子数据交换小组
电子数据交换
流行电子数据交换
波普esi
流行电子束
ret
hex2bin endp
端干管

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

无需使用多个查找表

因此,只需使用一个256字节的表和返回码:

那应该能解决你的问题

编辑:添加代码

将表更改为:

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

我不久前就这样做了:

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

我做了一些修改,使之像您的测试代码一样。

我需要保留每个字节,因为原始字节不只是将空值转换为空格,编码字符串是二进制字符串,我需要在不修改原始值的情况下对其进行解码。只需删除“if”即可。但它不会显示在MessageBox中,因为它是以null结尾的字符串。现在它不会交换字符。我尝试了您的函数,但它在mov字节ptr ds:[ebx+ecx],dl处崩溃。我尝试过调试,但无法找出错误。@riviraz:您是否在outstring中传递了一个具有写权限的地址?@GJ:我不明白您在说什么,ode的表部分是我从MASM libs源代码复制的,所以我不完全理解。你能给我一个更清楚的例子吗?@riviraz:好的,我添加了一部分未测试的代码来帮助你……:)
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