1. 查壳

PEID

没壳,Delphi写的,直接拉到od里开跑

运行界面

2. [Serial] Crack

胡乱输入一个Serial进去,会弹出这个信息框:

随意测试

肉眼可见明显的字符串 "Failed!""Try Again!!" 。直接参考字符串查找,开扣!

找到的字符串
定位参考

找到参考,可以找到0042F470段分支处。大概浏览一遍,可以得知0042F4D5处为决定弹出信息框内容的关键性跳转。于是理所当然的进行如下改动:

jnz short 0042F4F1
;改为
je short 0042F4F1
强 制 跳 转

无脑跳转成了((( 但这样感觉好没排面,还是要找出一般解法的。

0042F470处的push ebp下硬件断点,单步执行至转移指令jnz前的call处,观察栈内内容和寄存器内容,可以明显地看出输入的序列码和疑似正确序列码 "Hello Dude!"。同时根据原转移条件jnz,可以合理猜测转移指令前的callstrcmp

寄存器内容
堆栈内容

单步运行,发现EAX内容被改变,基本证实该callint strcmp()或类似函数。

寄存器内容

至此,便可以合理推测序列码即为"Hello Dude!"。清理重新运行后,证实该猜测正确,[Serial] crack成功。

成功
主要代码

3. [Serial + Name] Crack

老规矩,Check It 之后参考字符串走一波。

两个引用,怪起来了,翻翻上下,有两处相似代码段,合理推测,有两处信息框提示,并且注册名、注册码格式有一定限制。

两个参考字符串
看起来像最终结果的代码段

老样子,先强改转移指令,先让他congratulate我(((

jnz short 0042FB1F
;改为
je short 0042FB1F
旧 活 新 整

无脑()

好好分析,在0042F998处的push ebp下断点,单步执行至第一个查找到的参考字符串附近。

Name限定

注意到这里转移指令前的cmp操作和EAX内的值,以及输入Name的长度,不难推测出该段代码限制了Name的长度需大于等于0x4jge条件)

寄存器内容

继续向下单步执行,注意到imul指令执行前EAX先取得了输入Name的偏移地址,之后又将该地址进行了byte ptr限定的movx操作,即将Name第一个字母的ASCII码放入了EAX中,接下来继续单步执行,可以发现下来的几步操作将ds:[0x431750]的值设为了Name[0] * 0x29 * 2 = 0x19A0

计算具体步骤

继续向下单步,具体细节同上,发现该段代码实现了将上一步算出的结果转换为十进制字符串,并将其合成为形如“CW-xxxx-CRACKED”的形式,并将其与输入的序列号进行比较,从而实现判断。

合成字符串并判断

运用以上算法(Name[0] * 0x29 * 2)进行计算,假设注册名为 “DT9025A”,’D’ 的ASCII码为 0x44 ,计算后得到中间的十进制数为 5576 。输入后验证结果正确。

成功

[Serial + Name] crack成功。至此,CrackMe01 – Acid burn.exe Crack完成。

主要代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main () {
	//CW-DEC(Name[0] * 0x29 * 2)-CRACKED
	char name[100];
	puts("Acid burn CrackMe KeyGen");
	printf("Input Name to be registered:");
	scanf("%s", name);
	printf("Your serial is: CW-%d-CRACKED\n", name[0] * 0x29 * 2);
	system("pause");
	return 0;
}
20/10/17