【问题标题】:convert raw bytes to hexadecimal in c++ or assembly(FASM)在 C++ 或程序集(FASM)中将原始字节转换为十六进制
【发布时间】:2014-07-14 00:21:06
【问题描述】:

我知道这听起来像是一个非常愚蠢的问题,但我正在尝试构建一个简单的十六进制编辑器,但我无法从文件中读取字节。我使用 readfile api 读取 8kb 缓冲区,然后我打算将 8kb 转换为十六进制,但它有时只给我 4 个字节以相反的顺序或有时 0 我不确定我做错了什么。我怎样才能得到它,它将给我完整的 8kb 十六进制表示。如果他们是将整个文件转换为十六进制的更好方法,请告诉我。我只是在寻找读取整个文件并以十六进制表示形式在屏幕上显示的最快方法。谢谢

FASM 语法,但也很容易成为 c++

invoke ReadFile, [hFile],filebuffer,8192, BytesWritten, 0 
cinvoke wsprintfA,buffer1,"%X",[filebuffer]
invoke MessageBoxA,NULL,buffer1,title,MB_ICONINFORMATION+MB_OK 

所有数据都是dd?

更新 我将第二个答案标记为答案,因为我发现 masm 语法程序集看起来像这样,而且速度非常快,但我继续使用 CryptBinaryToString api http://msdn.microsoft.com/en-us/library/windows/desktop/aa379887

这里是 fasm 语法汇编代码,但又很容易变成 c++

invoke ReadFile, [hFile],filebuffer,500, BytesWritten, 0
        push    dwBuffLen
        push    pszHexBuffer
        push    0x0000000b  ; CRYPT_STRING_HEXASCIIADDR
        push    500
        push    filebuffer
        call    [CryptBinaryToStringA]
;pszHexBuffer contains the data

data sections
filebuffer rb 500
BUF_LEN       = 4000
        pszHexBuffer  db BUF_LEN   dup(0)  ; will contain converted bytes in hex. Twice the size of the original buffer at least (Read documentation about the last _In_Out parameter)
        dwBuffLen     dd BUF_LEN

【问题讨论】:

  • 这和我见过的任何 C++ 都不一样。它隐约类似于 1970 年代后期 PDP-11 中所谓的“线程宏”程序集。
  • 我知道它是汇编,但它也可以很容易地成为 c++,因为它只是 api 调用
  • @DarrinWoolit 你可以放弃printf 的意识形态并使用查找表转储nibbles。无论如何,这可能更接近你想要的。它需要一个包含 16 个字符的表(字符 '0''F')和一个迭代转储,将每个八位字节分成两个 4 位半字节,然后使用每个半字节作为表中的索引来知道要转储哪个字符.无论如何,我过去就是这样做的。无需使用像 printf 这样的大锤来拍打苍蝇(尽管它显然更容易实现)。请注意,这假定 8 位 char 类型可以正常工作。

标签: c++ assembly io hex fasm


【解决方案1】:

sprintf("%X") 只会为您转换一个整数,甚至会根据小端(因此反转)并且没有前导零(因此有时输出较短)来完成。您将需要一个循环并使用%02x 格式打印每个字节。

【讨论】:

  • 他们无法同时转换所有 8192 字节?我只是在寻找最快的方法来辐射整个文件并以十六进制表示形式在屏幕上显示它
【解决方案2】:

更多的是自己做的风格,但这应该可以解决问题。

inline char nibble_decode(char nibble)
{
    const char byte_map[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    return byte_map[nibble];
}

char *hex_string(char *buffer, unsigned char *bytes, int length)
{
    for(int i = 0; i < length; i++){
        buffer[i*3] = nibble_decode(bytes[i] >> 4);
        buffer[i*3+1] = nibble_decode(bytes[i] & 0x0f);
        buffer[i*3+2] = ' ';
    }
    buffer[length*3] = '\0';
    return buffer;
}

因为我现在正在公路旅行,所以我用手机输入了这个,所以我无法测试这个 sn-p。希望它传达了这个概念。

总而言之,它循环遍历长度字节数,并对高位使用位移位,对低位使用 and 操作。我还添加了一个空格,但如果你不想要它应该很容易删除。
注意:您必须预先分配 3*length+1 个字节到缓冲区。

【讨论】:

  • const char byte_map[16] = "0123456789abcdef";char *byte_map = "0123456789abcdef" 要短得多
  • 是的。它甚至可以被内联完整并直接索引。不知道为什么我费心把它打出来。一定是特别无聊。
猜你喜欢
  • 1970-01-01
  • 2018-05-21
  • 2017-03-05
  • 2015-09-04
  • 2017-07-19
  • 1970-01-01
  • 1970-01-01
  • 2013-09-12
  • 1970-01-01
相关资源
最近更新 更多