在文件中存储十六进制地址

时间:2014-02-18 04:36:59

标签: c++ file-io hex

我有一个pintool应用程序,它将应用程序访问的内存地址存储在一个文件中。这些地址是十六进制形式。如果我以字符串的形式写这些地址,它将需要大量的存储空间(接近300GB)。编写这么大的文件也会花费大量的时间。所以我想到了另一种减少使用存储量的方法。

十六进制地址的每个字符代表4位,每个ASCII字符为8位。所以我想用一个ASCII字符表示两个十六进制字符。

例如: 如果我的十六进制地址是 0x26234B 那么相应的转换后的ASCII地址将是& #K (忽略0x,因为我知道所有地址都是十六进制的。)

我想知道有没有其他更有效的方法来实现这一点,这需要更少的存储空间。

注意:我正在使用c ++

2 个答案:

答案 0 :(得分:0)

这是一个好的开始。如果您真的想要更进一步,可以考虑使用zip库或霍夫曼编码来压缩数据。

答案 1 :(得分:0)

假设您的地址是64位指针,并且这种表示对您的平台是明智的,您可以将它们存储为64位整数。例如,您列出0x1234567890abcdef,它可以存储为四个字节:

12 34 56 78 90 ab cd ef
(your pointer, stored in 8 bytes.)

或相同,但向后,取决于您选择的endianness。具体来说,您应该阅读this

我们甚至可以在某种程度上独立于平台:uintptr_t是无符号整数类型,与指针的宽度相同(假设一个存在,它通常会这样做,但它不是一个确定的东西),和sizeof(our_pointer),它给出了指针的字节大小。我们可以通过以下方式得到上述字节:

  1. 将指针转换为整数表示(即0x0026234b
  2. 移动字节以挑出我们想要的字节。
  3. 把它贴在某处。
  4. 在代码中:

    unsigned char buffer[sizeof(YourPointerType)];
    for(unsigned int i = 0; i < sizeof(YourPointerType); ++i) {
        buffer[i] = (
            (reinterpret_cast<uintptr_t>(your_pointer) >> (sizeof(YourPointerType) - i - 1))
            & 0xff
        );
    }
    

    一些注意事项:

    1. 在最后一次循环迭代中执行>> 0。我怀疑这可能是未定义的行为,你需要一个if-case来处理它。
    2. 这将写出您的平台大小的指针,并要求它们可以合理地转换为整数。 (如果不是这样的话,我认为uintptr_t不会存在。)它不会像在32位平台上那样在64位上做同样的事情,因为它们有不同的指针大小。 (或者您遇到的任何其他指针大小的平台。)
    3. 一旦程序死亡,程序的指针就无效,并且在程序仍在运行时甚至可能无效。 (如果指针指向程序决定释放的内存,则指针无效。)
    4. 可能有一个图书馆会为你做这件事。 (struct,在Python中,这样做。)

      以上是一个大端编码器。或者,您可以写出小端 - 维基百科的文章详细说明了差异。

      最后,您可以将指针强制转换为指向unsigned char *的指针,并将其写入。 (即,将指针的实际内存转储到文件中。)但这更依赖于平台。

      如果您需要更多空间,请通过gzip运行。