目录
本文讲解枚举法和特值法
1.下面代码中if判断是什么含义,请分析
来自某修改器的逆向出的代码的一部分:
//num为unsigned int类型
if (num <= 12)
{
if (((num - 8) & 0xFFFFFFFB) != 0)
{
// do_something
}
}
方法:枚举num的所有可能,看看判断的真假
枚举num的所有可能:循环
判断的真假的模版:
if ()
{
printf("true");
}
else
{
printf("false");
}
代码
因为num为unsigned int类型,因此从0枚举到12,打印每一种情况的真假
#include <stdio.h>
int main()
{
for (unsigned int num=0;num<=12;num++)
if (((num - 8) & 0xFFFFFFFB) != 0)
{
printf("%d:true\n",num);
}
else
{
printf("%d:false\n", num);
}
}
运行结果:
由运行结果可以看出:if判断等价为:
if (num != 8 && num != 12)
{
//do_something
}
如果unsigned int类型的num没有规定范围,可以对所有值判断,代码如下
int main()
{
for (unsigned int num = 0; num < UINT_MAX; num++)
if (((num - 8) & 0xFFFFFFFB) != 0)
{
// printf("%d:true\n", num);
}
else
{
printf("%d:false\n", num);
}
}
运行结果
下面to_int32函数的作用是什么,请分析
源代码片段来自https://github.com/pod32g/MD5/blob/master/md5.c
摘自MD5算法的源文件的一部分:
uint32_t to_int32(const uint8_t* bytes)
{
return (uint32_t)bytes[0]
| ((uint32_t)bytes[1] << 8)
| ((uint32_t)bytes[2] << 16)
| ((uint32_t)bytes[3] << 24);
}
方法:尝试一些数字去打印函数的返回值
例如使用存有特定值的类型为uint8_t数组
代码
int main()
{
uint8_t bytes[] = { 1, 2, 3, 4 };
printf("%u",to_int32(bytes));
}
{ 1, 2, 3, 4 }与打印的结果67305985貌似没有什么关系,可能需要调整printf打印的格式,uint32_t既可以%u(十进制)打印,也可以以%x(十六进制)打印,尝试按%x打印
int main()
{
uint8_t bytes[] = { 1, 2, 3, 4 };
printf("%x",to_int32(bytes));
}
运行结果:
好像看出规律了,如下图所示:
可以推出to_int32函数的的等价写法如下,但没有原来的写法快
uint32_t to_int32(const uint8_t* bytes)
{
return (uint32_t)bytes[0]
+ ((uint32_t)bytes[1] * pow(2,8)//或运算在这里等价为+运算
+ ((uint32_t)bytes[2] * pow(2, 16))
+ ((uint32_t)bytes[3] * pow(2, 24)));
}
因此to_int32函数的作用:将一个类型为uint8_t的数组的四个元素转换为一个32位整数