当我想计算函数的地址时,我会执行以下操作:
HMODULE base = GetModuleHandle(L"program.exe"); // Module base addr
// Adding an offset to the base
std::cout << (base + 0x8F0A0) << std::endl; -> Wrong!
我不确定为什么结果是错的。我通过在线十六进制计算测试了它,并且还有调试器来检查这两个值。
可以认为是十进制,其他是十六进制,会产生错误的结果吗?
如何以十六进制获得结果?
答案 0 :(得分:1)
问题在于GetModuleHandle(L"program.exe")
返回值:00DE0000
。您需要使用C十六进制语法,因此您需要在“0x”上添加并加上十六进制数 00DE0000 。
因此,您的基数应该投放到数值:0x00DE0000
0x00DE0000 is equal to 00DE0000
尝试使用std::string to_string(int value);
将其转换为字符串,然后将十六进制值(base)转换为C十六进制语法(在十六进制值的开头添加“0x”)。要完成此操作,请将基础值转换回数值(例如,使用std::stoi)并使用std::hex执行添加。
试试此代码here。
#include <iostream>
int main () {
int hex1 = 0x8F0A0;
int hex2 = 0x00DE0000; // Using int values
std::cout << std::hex << hex1 + hex2 << std::endl;
}
答案 1 :(得分:1)
正如here所述,根据STRICT
是否已定义,HMODULE
基本上是void*
还是<unique type>*
,其目的是使每个句柄类型成为不同的C ++类型,这意味着混合和匹配时编译器错误。在前一种情况下,指针算法不会编译。在后一种情况下,它将进行编译,但是您不能依赖于发生的任何事情,因为指针算法会考虑类型的大小,并且因为如果指向对象/数组,指针算法是未定义的。
你应该把这个指针视为没有特别指向任何东西,因此不要做指针算术。您必须reinterpret_cast
将其设置为您确定足够大(std::uintptr_t
)的整数类型,然后对该整数值进行算术运算。
在我的本地标题中,这个唯一类型包含int
成员,因此添加1实际上会将指针向前移动4个字节(除了未定义的行为和所有内容之外)。碰巧0x00DE0000 + 4 * 0x8F0A0是你的0x0101C280值。
答案 2 :(得分:0)
正如克里斯所说,我有同样的情况,解决了这样的事情:
int offset = 0x8F0A0;
std::uintptr_t base = reinterpret_cast<uintptr_t>(GetModuleHandle(L"program.exe"));
// Here added 4 bytes to the offset.
std::cout << std::hex << (base + (offset + 4096)) << std::endl;