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

Storing hexadecimal addresses in a file

本文关键字:十六进制地址 存储 文件      更新时间:2023-10-16

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

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

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

我想知道,有没有其他更有效的方法可以做到这一点,减少存储量。

注意:我在c++中工作

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

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

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

或者相同,但向后,这取决于您选择的endianness。具体来说,你应该阅读这篇文章。

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

  1. 将指针转换为整数表示形式(即0x0026234b)
  2. 将字节四处移动以选择我们想要的字节
  3. 把它粘在某个地方

在代码中:

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案例来处理它
  2. 这将写出平台大小的指针,并要求它们可以合理地转换为整数。(我认为如果不是这样的话,uintptr_t就不存在了。)它在64位平台上不会做同样的事情,就像在32位平台上一样,因为它们有不同的指针大小。(或者你遇到的任何其他指针大小的平台。)
  3. 一旦程序失效,程序的指针就无效,甚至可能在程序仍在运行时仍然无效。(如果指针指向程序决定释放的内存,则指针无效。)

很可能有一个库可以帮你做这件事。(在Python中,struct就是这样做的。)

上面是一个大端编码器。或者,你也可以写出little-endian——维基百科的文章详细介绍了其中的区别。

最后,您可以将一个指针强制转换为指向unsigned char *的指针,然后编写它。(也就是说,将指针的实际内存转储到一个文件。)不过,这更依赖于平台。

如果你需要更多的空间,我会通过gzip运行它。