下面是网上的160个CrackMe的部分逆向笔记,包括逆向思路、注册机实现和逆向中常用的知识整理
注意:逆向前一定要先操作一下软件,熟悉软件的运行现象
CrackMe002和CrackMe003是同一个作者用VB写的小程序;CrackMe002难度是一颗星,很简单

1.现象
运行软件,需要破解的是用户名/序列号;破解前可以输入很少的字符看看是否有字符的限制,本程序没有

2.逆向思路
step 1.错误提示
输入一组序列号和用户名,点击验证发现出现错误对话框,最有用的是错误的字符串You Get Wrong

step 2.关键跳转
通过错误字符串You Get Wrong,在OD中引用的地方设置断点;重新输入用户名和序列号进行验证,直到找到正确的断点命中位置,回溯找到关键跳转(0x402588)

step 3.关键跳转所在函数
在关键跳转所在的函数起始位置设置断点,重新输入用户名和序列号进行验证;断点命中后,下面是计算序列号的主要逻辑
- 1.用户名计算序列号
计算用户名长度 –> 长度 * 0x17CFB,如果结果溢出则跳转 –> 结果加上用户名第一个字符的ASCII码,结果转成十进制
公式:strlen(用户名) * 0x17CFB + 用户名第一个字符ASCII码

- 2.结果拼接
计算结果直接与AKA进行拼接,最后得到序列号
提示:如果细心的话,会发现真正的序列号在某一个时刻会在函数的栈帧(本案例就在
ebp-20的地址处存储正确序列号AKA-682833)或寄存器上进行存储,会有这种现象是因为用正确序列号与用户输入的序列号进行比较,基本有2种情况:
- 使用类似于strcmp的函数:此时正确序列号被压入stack中,当做参数
- 使用类似于==的逻辑:此时存在eax等寄存器中

简单验证:使用用户名test123分析出来的序列号AKA-682833进行验证,发现逆向成功
step 4.注册机
下面是没有考虑边界条件的注册机的简单实现代码
#include "StdAfx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char user_name[100] = {0}; //用户名
printf("请输入用户名:");
scanf_s("%s", user_name, 100);
int user_serial = strlen(user_name) * 0x17CFB + user_name[0]; //关键计算
char serial[200] = {0};
char key[] = "AKA";
sprintf(serial, "%s-%d", key, user_serial); //拼接
printf("用户名:%s, 对应的序列号:%s\n", user_name, serial);
system("pause");
return 0;
}
注册机生成结果验证成功:

总结:本次逆向使用的还是关键字符串作为突破口,找到关键跳转和其所在函数,分析处理逻辑
900



被折叠的 条评论
为什么被折叠?



