运行程序 查看界面
随便输入key点击Register
发现会弹出信息框 OD附加下断点:MessageBoxA
堆栈返回到0x4012e1
看到如下代码
此处可以看到成功和失败的文本都在这里 通过跳转控制成功失败 找到该函数头部 查看整个函数代码
直接在函数头部下断点 跟着跑一遍
得知如下结果
1.获取输入的key
0040120B . FF15 A8704000 call dword ptr ds:[<&USER32.GetDlgItemTe>; \GetDlgItemTextA
2.调用Sleep延迟500毫秒
00401211 . 68 F4010000 push 0x1F4 ; /Timeout = 500. ms
00401216 . FF15 00704000 call dword ptr ds:[<&KERNEL32.Sleep>] ; \Sleep
3.验证输入的是否符合
⒈获取输入的key的长度 判断输入的长度是否等于4位
⒉判断输入的4位中是否有数字0
⒊判读第一位是否等于数字1和第二位是否等于数字5
此处得知key只有4位 前两位为”15”且整个key中没有数字0
4.计算输入的key
代码还原如下:
float g_fValue = 16.0f;
float fResult =
(
(
(float)(Key[2] - dwValue) -
(
(float)(Key[0] - dwValue) / (float)(Key[1] - dwValue)
)
) * (float)(Key[3] - dwValue)
) * g_fValue;
5.比较key计算出的结果是否等于正确结果
float g_fResult = 384.0f;
if (fResult == g_fResult)
{
return true;
}
6.总结并测试
已知key计算结果为384为成功
已知key只有4位且前两位为”15”
下面直接手动输入key
先输入1598 计算结果为1126.4 数值太大 输入一个小一点的试试
输入1555 计算那结果为 384 程序弹出如下框
至此逆向完成! 整个判断和计算代码如下
float g_fValue = 16.0f;
float g_fResult = 384.0f;
bool CheckKey(char* Key)
{
//判断key是否是四位
if (strlen(Key) == 4)
{
DWORD dwValue = 0x30;
//判断key中是否有数字0
if (Key[0] != dwValue && Key[1] != dwValue && Key[2] != dwValue && Key[3] != dwValue && Key[0] == 0x31 && Key[1] == 0x35)
{
float fResult =
(
(
(float)(Key[2] - dwValue) -
(
(float)(Key[0] - dwValue) / (float)(Key[1] - dwValue)
)
) * (float)(Key[3] - dwValue)
) * g_fValue;
if (fResult == g_fResult)
{
return true;
}
}
}
return false;
}
int main()
{
bool bRet = CheckKey("1555");
printf("结果:%d\r\n", bRet);
return 0;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课