[TOC]



## 查壳



![1552908035334](assets/1552908035334.png)



跟008和009这两个crackme一样是同一个作者，还是用VB写的。



## 分析程序



这个程序的保护方式也很简单，只有一个序列号



![1552908107434](assets/1552908107434.png)



直接搜索字符串，



![1552908093068](assets/1552908093068.png)



根据错误提示来到关键代码处，接着一直往上找，



![1552908154855](assets/1552908154855.png)



![1552908200632](assets/1552908200632.png)



接着就看到了这个地方的跳转来自0x402053这个位置，跟过去看看



![1552908250849](assets/1552908250849.png)这里有一个关键的比较，根据ax的值来提示是否正确。

`kXy^rO|*yXo*m\kMuOn*+ `我一开始以为上面这个字符串就是序列号，结果发现我想多了，看来是有算法，没办法，单步跟吧。



## 分析算法



大致的校验过程如下



![1552909513614](assets/1552909513614.png)



首先获取到序列号的长度



![1552909531753](assets/1552909531753.png)



然后将序列号的长度作为循环的次数



![1552909568793](assets/1552909568793.png)



接着会取出序列号ASCII的每一位，然后将序列号的ASCII值+0xA之后，再将这个值转为字符串。



![1552909637587](assets/1552909637587.png)



然后又是国际惯例了，会通过一个函数将结果保存到[ebp-0x34]这个位置。(VB的程序每次都是这样，这不是给逆向人员开绿色通道吗？)那么这个循环我们只要跟了一次，然后直接看[ebp-0x34]的结果就可以了。



![1552909761726](assets/1552909761726.png)



循环结束之后，会把最后的结果跟硬编码的一个字符串作比较，根据比较的结果提示正确或者错误。那么我们很容易就能写出这个crackme的注册机了



## 写出注册机



```C++

int CalcKey()

{

	char result[MAX_PATH] = { 0 };

	char key[MAX_PATH] = { "kXy^rO|*yXo*m\\kMuOn*+" };

	int keyLen = strlen(key);



	for (int i = 0; i < keyLen; i++)

	{

		result[i] = key[i] - 0xA;

	}



	printf("%s\n", result);



	return 0;

}

```



## 验证结果



![1552910210228](assets/1552910210228.png)



把注册机的结果全部复制下来，显示正确，那么这个crackme就完成了



需要相关文件的可以到我的Github下载：https://github.com/TonyChen56/160-Crackme