在文件中存储十六进制地址
Storing hexadecimal addresses in a file
我有一个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)
则给出了指针的字节大小。我们可以通过得出上述字节
- 将指针转换为整数表示形式(即
0x0026234b
) - 将字节四处移动以选择我们想要的字节
- 把它粘在某个地方
在代码中:
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
);
}
一些注意事项:
- 这将在最后一次循环迭代中执行
>> 0
。我怀疑这可能是未定义的行为,您需要一个if案例来处理它 - 这将写出平台大小的指针,并要求它们可以合理地转换为整数。(我认为如果不是这样的话,
uintptr_t
就不存在了。)它在64位平台上不会做同样的事情,就像在32位平台上一样,因为它们有不同的指针大小。(或者你遇到的任何其他指针大小的平台。) - 一旦程序失效,程序的指针就无效,甚至可能在程序仍在运行时仍然无效。(如果指针指向程序决定释放的内存,则指针无效。)
很可能有一个库可以帮你做这件事。(在Python中,struct
就是这样做的。)
上面是一个大端编码器。或者,你也可以写出little-endian——维基百科的文章详细介绍了其中的区别。
最后,您可以将一个指针强制转换为指向unsigned char *
的指针,然后编写它。(也就是说,将指针的实际内存转储到一个文件。)不过,这更依赖于平台。
如果你需要更多的空间,我会通过gzip
运行它。
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 指向存储在字符串 c++ 中的十六进制
- 为什么C++总是显示十六进制内存地址,而不仅仅是整数?
- 是否可以在C++中获取 CHAR 的有效十六进制地址?
- 如何使用 setfill 和 setw 在字符串变量中存储十六进制值
- 是否可以将存储在dword中的十六进制与getasynckeystate一起使用
- 将字符串存储为十六进制而不进行转换
- 将十六进制字符数组存储在字节数组中,而无需更改为 ASCII 或其他任何东西
- 如何从存储在 QByteArray 中的十六进制值计算校验和
- 将字符串中以十六进制形式存储的负长整型值转换为 C++ 中的长整型变量
- C++/CPP 读取添加的十六进制地址
- 将十六进制值存储到 std::vector<无符号字符中>
- C++为什么字符串的地址尽管是十六进制格式,但不能存储在 long int 变量中?
- 在文件中存储十六进制地址
- 为什么十六进制地址是14个字符
- c++seekg似乎返回了一个十六进制地址,而不是.txt文件中的实际字符
- 将十六进制值存储为字符串(Arduino项目)
- 指针地址给出的是1,而不是十六进制地址
- 转换十六进制并存储为字节
- 添加十六进制地址到DLL地址的c++