1. 查壳
没壳,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
,可以合理猜测转移指令前的call
为strcmp
。
单步运行,发现EAX
内容被改变,基本证实该call
为int strcmp()
或类似函数。
至此,便可以合理推测序列码即为"Hello Dude!"
。清理重新运行后,证实该猜测正确,[Serial] crack成功。
3. [Serial + Name] Crack
老规矩,Check It 之后参考字符串走一波。
两个引用,怪起来了,翻翻上下,有两处相似代码段,合理推测,有两处信息框提示,并且注册名、注册码格式有一定限制。
老样子,先强改转移指令,先让他congratulate我(((
jnz short 0042FB1F ;改为 je short 0042FB1F
无脑()
好好分析,在0042F998
处的push ebp
下断点,单步执行至第一个查找到的参考字符串附近。
注意到这里转移指令前的cmp
操作和EAX
内的值,以及输入Name
的长度,不难推测出该段代码限制了Name
的长度需大于等于0x4
(jge
条件)
继续向下单步执行,注意到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; }