160个Crackme023

查壳

在这里插入图片描述

目标程序是一个用汇编写的带图形界面的程序,没有壳

分析程序

直接查找错误的字符串,来到错误的提示处,可以看到这个cmp就是关键比较了

在这里插入图片描述

这里会比较eax是否等于0x10,而eax来自于0x403166,所以必须让0x这个地址的值为0x10才能注册成功

直接右键->查找所有常量

在这里插入图片描述

在这里插入图片描述

这里有四个地址分别对0x403166进行了+4的操作,只要同时满足四个条件,就能注册成功了

分析条件一

首先来分析第一个地址的401093处的代码

在这里插入图片描述

这里首先获取用户名,然后判断用户名长度是否为零,不为零则对0x403166这个地址执行+4操作,所以这个地方一定会断下来

分析条件三

为什么先看条件三,因为我之前已经分析完了,这四个位置有一个先后顺序的问题,按照顺序再来到00401493这个地址

在这里插入图片描述

这里会获取输入的序列号,然后将序列号保存到0x403188这个地址,这个地址很重要,这个地址也是一定会断下来的

分析条件二

再来看条件二,这里就是这个程序校验的算法了,校验过程如下

在这里插入图片描述

  1. 获取用户名
  2. 设置循环次数,初始值i=0
  3. 用户名右移i位
  4. i++
  5. Serial++
  6. Serial和username[i]进行异或(username[i])指的是用户名左移i位后前四个字母的ASCII值)
  7. 保存结果到403188处
  8. 循环0x10次

分析条件四

在这里插入图片描述

这里首先会取出0x403188的结果,然后加上0x9112478,接着比较eax是否为零,为零则403166这个位置加上4,从这里可以得出条件三的算法结果必须为0-0x9112478=0xf6eedb88

写出注册机

根据条件三的结果,我们可以直接逆推出注册机

int CalcKey()
{
	char* name;
	unsigned long serial = 0xF6EEDB88;
	unsigned long *p;
	name = new char[20]{0};

	cout << "请输入用户名:";
	gets_s(name, strlen(name) - 1);
	for (int i= 0x10 - 1; i >= 0; i--)
	{
		p = (unsigned long *)&name[i];
		serial ^= *p;
		serial--;
	}
	cout <<serial << endl;
	return 0;
}

输入用户名和计算的序列号,注册成功,破解完成

在这里插入图片描述

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鬼手56

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值