Crackme026 的逆向分析
1.程序观察
如果序列号错误,name的输入框会闪一下,但没有弹窗提示。
2.简单查壳
3.程序分析
可以看到,有两个点击事件,程序也有两个功能按钮。
使用 OD 载入程序,转到地址 402B10 处。下断点,点击 check 按钮,程序断在了 402B10。所以该段代码应该就是验证的代码。
继续向下看代码
1.
程序求得输入name的长度,如果小于5个字符,就会出现上面出现的提示弹窗。
2.
程序建立循环,循环次数为用户名的长度。
程序获取用户名第 i 位的 ASCII值。
i 为循环次数,如果是第一次循环,就获取用户名第1位的 ASCII值,也就是 name[0] 的 ASCII值。
程序将字符串 432.4 转化为浮点数,再将 ASCII(name[i-1])转化为浮点数,两数相乘,再乘以浮点数 17.79。
也就是 432.5 * ASCII(name[i-1]) * 17.79
程序将上面的结果除以 15,也就是 (432.5 * ASCII(name[i-1]) * 17.79) /15
然后再将结果转化为字符串。
至此,一个循环结束。
3.
将最后一次循环的结果转化为浮点数,去除小数点后部分,然后再转化为字符串。
4.
程序取 name 首字符的 ASCII值,转化为浮点数;再将 3. 的结果转化为浮点数,两者相加。
5.
取name首字符的 ASCII值,乘以 0x19。
再将 3. 的结果转化为浮点数,减去上一步骤的结果,再转化为十六进制值。
6.
将 3. 的结果转化为十六进制。
7.
取 name[0] 的 ASCII 值,乘以 name 的长度,再减去 0x1B。
8.
将 4. 的结果和 5. 的结果拼接在一起。
将上面拼接的结果和 6. 的结果拼接在一起。
将上面拼接的结果和 7. 的结果拼接在一起。
将 name 的长度转化为字符串,和上面拼接的结果拼接在一起。
将上面拼接的结果和 "-CM" 拼接在一起。
最后进行比较
4.注册机
1 #include <stdio.h> 2 #include <string.h> 3 #include <Windows.h> 4 5 6 int Keygen() 7 { 8 char szName[20] = { 0 }; 9 char szSerial[100] = { 0 }; 10 char szSerial1[20] = { 0 }; 11 int NameLen = 0; 12 __int64 Result = 0; 13 __int64 Result1 = 0; 14 15 16 printf("请输入用户名:"); 17 scanf_s("%s", szName, 20); 18 NameLen = strlen(szName); 19 20 Result = (szName[NameLen - 1] * 432.4 * 17.79) / 15; 21 22 Result1 = szName[0] + Result; 23 sprintf(szSerial1, "%I64d", Result1); 24 strcat(szSerial, szSerial1); 25 26 Result1 = Result - szName[0] * 0x19; 27 sprintf(szSerial1, "%I64X", Result1); 28 strcat(szSerial, szSerial1); 29 30 sprintf(szSerial1, "%I64X", Result); 31 strcat(szSerial, szSerial1); 32 33 Result1 = szName[0] * 0x5 - 0x1B; 34 sprintf(szSerial1, "%I64d", Result1); 35 strcat(szSerial, szSerial1); 36 37 Result1 = NameLen; 38 sprintf(szSerial1, "%I64d", Result1); 39 strcat(szSerial, szSerial1); 40 41 strcat(szSerial, "-CM"); 42 43 printf("%s ", szSerial); 44 45 return 0; 46 } 47 48 int main(int argc, char* argv[]) 49 { 50 Keygen(); 51 system("pause"); 52 return 0; 53 }