我有一个校验和,我正在尝试对其进行逆向工程,我已经知道在我知道最初用于创建校验和的原始初始值之后如何保持校验和生成。
到目前为止,我知道校验和是使用双数据类型数学方程生成的。
计算出的校验和的最终值是一个无符号整数,但在此之前它会从 double 转换为 unsigned long long aka (unsigned __int64)。
我要做的是将一个无符号整数恢复为双数据类型中的相同值,以进入撤消校验和以检索原始初始值的下一步。
当校验和在这里计算时,它以双精度数据类型生成的值。
3083570000.3115764
它创建了一个校验和0xB7CB8B50
我不认为这是一个有损的对话,所以即使它从 8 字节双倍转换回 4 字节整数校验和,也没有真正丢失。为什么?因为该double
值始终是通过乘以创建的4294967295.0
,我认为这只是为了消除尾随的 4 个字节,有点像移位。
因此,double
我要检索的值必须除以4294967295.0
才能将原始双精度值精确地恢复到最后一位。
问题是我不能正确划分它,因为它不是 100% 准确到最后一个小数点。我知道浮点数学不是 100% 准确的 IEEE 浮点废话,但我不在乎我只是试图以与最初创建相同的方式来扭转这一点。
输出
假设原始校验和双倍是0.71794958809146792
0.71794958809146792 * 4294967295.0 = 3083570000.3115761849416764
数据包中发送的答案是0xb7cb8b50
如果我手动将无符号整数0xb7cb8b50
转换为unsigned __int64
手动,它应该看起来像这样0x00000000b7cb8b50
在代码中生成的原始双精度应该如下所示,我在将其附加到数据包之前使用相同的密钥重新创建相同的条件以首先生成校验和,它应该看起来像这样
Real ANSWER = 3083570000.3115764
所以
0x00000000b7cb8b50 should equals = 3083570000.3115764 double
我的反向代码看起来像这样
unsigned int checksum = 0xb7cb8b50;
double test1 = (double)(unsigned __int64)checksum;
double test2 = double(checksum);
double test3 = static_cast<double>(checksum);
double test4 = *((double*)(void*)&checksum);
上面的代码有几个小数位是错误的。
test1 returns = 3083570000.0000000
test2 returns = 3083570000.0000000
test3 returns = 3083570000.0000000
test4 returns = 1.523486003547e-314#DEN
我如何获得额外的,.3115764
也是我的问题。