练习笔记之160Crackme-034
本帖最后由 xiaoyu2032 于 2022-9-8 11:30 编辑# 160CM-034
## 1. 爆破
程序打开以后,没有注册按钮和窗口,只有一个uncracked的提示。直接拖进OD中,从头往下看,可以很容易的看出程序流程:
① 判断CRACKME3.key文件是否存在;
② 读取文件内容并判断读取内容的字节数;
③ 将读取到的内容按两个校验算法进行计算,比较结果是否相同。
因此,要爆破就需要将上述三处判断的跳转都改到正确的流程上去,需要:
(1)401035处,将`jnz short 00401043`改为`jmp short 00401043`;
(2)40106D处,将`jnz short 00401037`改为`nop`;
(3)40109F处,将`je short 00401037`改为`nop`;
上述修改完成后,程序启动后的菜单栏提示已经变成了Cracked的字样,但是没有破解成功的提示框弹窗,还需要在40118A处,将`jnz short 004011A3`改为`nop`,这样就全部爆破就完成了。
## 2. 算法分析
先分析校验算法1,用IDA打开程序,找到算法子程序`401311`,按F5得到伪代码,如下图:
从伪代码中可以看出,算法依次将每个字节与变量v4(从65到79每次加1)进行异或计算,然后将结果累加,共执行14次。
然后累加结果再与`0x12345678`进行异或计算。
校验算法2很简单,将从文件中读取到的内容,取第15~18字节的内容,当成整型变量值。
然后比较算法1的异或结果和算法2得到的整型变量是否相等,相等则成功。
另外,由于注册成功后提示的字符串是异或后的结果,如果要显示希望的字符,则需要先进行异或处理后,将异或处理后的内容当做1~14字节的内容。
编写注册机算法程序如下:
```cpp
// 160CrackMe-034.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <math.h>
int _tmain(int argc, _TCHAR* argv[])
{
char input,String1;
int i, j,length;
int k,temp;
int code1;
printf("请输入用户名:");
scanf_s("%s", input, 50);
length = strlen(input);
k = 65;
//现将用户名异或处理得到长度为14字节的字符串
for (i = 0; i < 14; i++)
{
if (i<length)
{
String1 = input ^ k;
}
else
{
String1 = 0 ^ k;
}
k++;
}
j = 0;
k = 65;
code1 = 0;
do
{
temp = k ^ String1;
k++;
code1 = code1+temp;
if (!temp)
break;
j++;
} while (k != 79);
code1 = code1 ^ 0x12345678;
String1 = code1 & 0xFF;
String1 = (code1 & 0xFF00)>>8;
String1 = (code1 & 0xFF0000) >> 16;
String1 = (code1 & 0xFF000000) >> 24;
char * path = "z:\\CRACKME3.KEY";
FILE * pfile;
fopen_s(&pfile, path, "w");
fwrite(String1, sizeof(byte), 18, pfile);
fclose(pfile);
system("pause");
return 0;
}
```
输入用户名`helloworld`,生成key文件后,将文件复制到程序目录下,运行程序,验证成功。
## 3. 总结
这道题由于异或计算会得到非可见的ASCII码字符,因此注册机输出文本信息会有不可见的字符,需要直接二进制写入key文件。 谢谢大佬 谢谢大佬 谢你的坚持分享学习了 感谢分享,讲得很清楚 感谢破解 , 谢谢楼主分享 厉害了奥 感谢楼主分享