Assembly imul指令的第三个操作数是内存地址,它的原始值是多少?
我目前正在从游戏中反转哈希函数,遇到以下情况:Assembly imul指令的第三个操作数是内存地址,它的原始值是多少?,assembly,reverse-engineering,Assembly,Reverse Engineering,我目前正在从游戏中反转哈希函数,遇到以下情况: Game.exe+1F745D - 69 C0 93 01 00 01 - imul eax,eax,Game.exe+C00193 指令本身并不是问题所在,它的有符号多个操作数有三个:目标、源1和源2。Source1和Source2相乘,结果存储在目标操作数中 当我试图对此进行反向工程时,我想知道此操作码在源代码中的外观如何? 我怀疑开发人员是否在代码中加入了基本地址+C00193? (该游戏的基址是0x00400000 btw,如果有必要,地
Game.exe+1F745D - 69 C0 93 01 00 01 - imul eax,eax,Game.exe+C00193
指令本身并不是问题所在,它的有符号多个操作数有三个:目标、源1和源2。Source1和Source2相乘,结果存储在目标操作数中
当我试图对此进行反向工程时,我想知道此操作码在源代码中的外观如何?我怀疑开发人员是否在代码中加入了基本地址+C00193?
(该游戏的基址是0x00400000 btw,如果有必要,地址是静态的) 游戏将哈希函数的结果与硬编码值进行比较。所以我认为游戏开发者不太可能想要一个不可预测的结果 假设第三个操作数是一个立即数,如果我没有弄错的话,这意味着它会按“原样”处理第三个操作数。因此,第三个操作数的值不是该内存地址的值(即0),而是基址+C00193的和 所以当我在代码中这样做时:
hash*=0x00400000+0xc00193代码>它确实有效,但原始源代码中的值是多少?
我已经完成了该函数的一个完整的工作实现,如果需要的话,我可以发布。我的猜测是,反汇编程序试图在这里变得聪明,并假设常量是内存地址,但实际上可能不是。从技术上讲,内存地址也只是一个数字。如果它们“看起来像一个”,反汇编程序将尝试将它们显示为内存地址。(在许多情况下,这些启发式方法非常有用,但有时可能会产生误导。)根据您发布的字节(93 01 00 01
),它实际上是0x10000193
)
所以原始代码可能是:
hash*=0x1000193
这表明它是一个32位函数,如下所示:
uint32\u t fnv32hash(const std::string&str){
uint32_t hash=0x811c9dc5;
常量uint32_t原始=0x10000193;
对于(int i=0;i
这看起来几乎和我的反向函数一模一样!我认为你完全正确。多谢各位!如果你遇到任何奇怪的常数,用谷歌搜索它们通常是非常有用的,因为大部分时间都是某种加密算法的一部分,或者是著名的编译器优化(例如,为了优化5的除法,用0xcccd
乘法)。