【问题标题】:Output 64 bit integer with hexdump使用 hexdump 输出 64 位整数
【发布时间】:2015-09-13 21:17:08
【问题描述】:

我目前正在处理一些二进制数据。 为了检查和调试以前由我的应用程序生成的数据,我使用 hexdump,面对 hexdump 似乎无法提取 64 位整数字段的障碍。 给定以下最小示例:

#include <iostream>
#include <fstream>
#include <cstdint>

int main(int argc, char** argv){
    std::ofstream os("tmp.bin", std::ios::out | std::ios::binary);
    uint64_t x = 7;
    os.write((char*)&x,sizeof(uint64_t));
    os.close();
    return 0;
}

我在我的系统上执行了一个简单的 hexdump:

hexdump tmp.bin

> 0000000: 0007 0000 0000 0000
> 0000008:

现在尝试提取 64 位宽度的无符号整数:

hexdump -e '/8 "%u"' tmp.bin

> hexdump: bad byte count for conversion character u

根据写得好的hexdump-manual by David Mair应该是可以做到的,但是我没有成功。

我错过了什么?

【问题讨论】:

  • 不幸的是,这只会修改输出的缩进宽度。
  • 在手册页中说 x 和 u 最多只支持 4 个字节。无论如何,经过一番抨击后,我发现了这个解决方法: hexdump -e '2/4 "%08X" "\n"' FILE | awk '{system("echo \"ibase=16; "$1"\"|bc")}' 它基本上打印两个 4 字节十六进制对,然后使用 bc 将其转换为十进制。我不知道2个十六进制对的顺序是否需要交换正确的值,但你可以试一试。
  • 好吧,我刚试了一下。这些值确实必须交换。它是这样工作的: hexdump -e '2/4 "%08X " "\n"' HEX | awk 'BEGIN{printf "ibase=16; "}{print $2 $1}' | bc 谢谢。
  • 好的,现在我点击签名号码。因为我不知道它们是否使用符号位、一个补码、二进制补码、偏移二进制或负基本表示来表示,所以对于快速转储来说太多了。所以我们的解决方案只适用于无符号 64 位整数。
  • 最终你想出了答案 ;)

标签: c++ binary 64-bit reverse-engineering hexdump


【解决方案1】:

我们的最终解决方法如下:

x=`hexdump -n 8 -e '2/4 "%08X " "\n"' {FILENAME} | awk 'BEGIN{printf "0x"}{print $2$1}'`
echo $(($x))

各部分说明:

  • 从文件 {FILENAME} 中提取 64 位整数值的八个字节 作为两个四字节块打印为十六进制编码值。

    hexdump -n 8 -e '2/4 "%08X " "\n"' {FILENAME}
    
  • 反转两个块的字节顺序并将其打印为一个表示二进制值的八字节块。为后续处理添加 0x

    awk 'BEGIN{printf "0x"}{print $2$1}
    
  • 将十六进制表示保存到 x 以供 bash 评估。

    x=`....`
    
  • 让 bourne shell 解释并输出 64 位整数变量的十六进制编码值(这里需要之前添加的 0x)。

    echo $(($x))
    

【讨论】:

  • 这让我明白了很多。我很感激。
  • 我能够扩展它,这非常有用。
【解决方案2】:

也可以使用 sed。以下匹配 8 个字节的十六进制整数并交换它们。同样,这只适用于无符号整数。

hexdump ... | sed 's/0x\([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]\)/0x\2\1/'

AFAICT 应该能够写得更清楚

hexdump ... | sed 's/0x\([0-9a-f]{8,8}\)\([0-9a-f]{8,8}\)/0x\2\1/'

通常使用一些命令行选项(例如 -E)来启用扩展正则表达式,但至少在 Mac OS X 10.10 上这不起作用。

【讨论】:

    【解决方案3】:

    我不明白为什么这不能开箱即用,但我在打印 64 位整数时遇到了同样的问题,最终从util-linux 编译了一个更好的版本:https://github.com/karelzak/util-linux .起初我尝试在 Ubuntu 中安装该软件包,但它没有更新 hexdump,所以我决定尝试“手动”安装。

    这有点工作,但还不错。只需使用git 获取源代码,运行autogen.sh 脚本,然后./configure 后跟make hexdump 即可编译该程序。在我的笔记本电脑上编译只用了 4 秒。

    【讨论】:

      【解决方案4】:

      改用“od”命令。 od -xL 输出长整数

      【讨论】:

        猜你喜欢
        • 2019-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-29
        • 2018-11-23
        • 2011-03-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多