160 个newCrackMe 下载链接
百度网盘
链接:https://pan.baidu.com/s/1BaROP5e9UbJMSN1sgOOKbA
提取码:z2i6
这个平时没事可以玩玩,可能有人之前做过吾爱的 160 个CrackMe,那个排序是按照首字母来排序的
所以有些较难题可能排在前面,但是并不是那么好做,难度不是逐渐上升的,这个newCrackMe是对吾爱的重新排序
适合像我这样的新手去练习和玩耍,有空我也会记录一下我的解题过程,
比较 eax,如果等于0 就不会跳转,往下执行 Error,不等于 0就跳转到 Well Done
爆破的话可以直接 je改成 jne 或 jmp 就行
追踪分析的话也不难发现只需要把 cmp eax,0x0改成 cmp eax,0x1 使其跳转
往上找,好像是要先创建个 CRACKME3.KEY 文件,然后读文件,一步一步验证后通过
所以创个 CRACKME3.KEY 文件,内容不知道就猜了
直接可以F8一步步往下看,在CreateFile 之后一个和 -1 的比较,也就是判断有没有这个文件,不等就是有,就跳转
跳转过来把 eax赋值给内存,可以跟随地址看见下面一大串字符串
然后就是读文件,可以看见读出了部分的ASCII,0x12 也就是 18个,key的长度 18
读到下面的异或时 F7 跟进去,F8 继续跟,先是拿到key给esi,然后取 a 与 0x41 异或,也就是 a 和A异或,结果又放回 esi
异或之后 al 变成 20,然后又被放回,al 清空,b1 和 0x4f 比较,也就是 79,所以就是循环了 79-65 = 14 次
14 次循环结束以后,key只剩下 4 位,返回
异或出来以后,又是ds 和 eax 的比较,ds那段是上面异或时 和 0x12345678 的结果,eax的值7271706f,也就是key的后四位倒序,rqpo
那么那段ds 在和 0x12345678 异或之前值是多少,重新运行跟到那里F7进入,其实就是14 次都在往 ds上加 eax,0x20(32),0x01c0(448),32*14=448
重新理一下思路
key 是18位,前14位 逐个与从0x41 开始递增异或,异或后得值放回字符串,14次异或得到的值累加,然后返回
返回以后 累加值再与 0x12345678 做异或,异或后的值再与 key 的后四位倒序做比较
知道了流程,编写注册用的 key
我们知道异或累加后的值是 0x123457b8,然后倒序,所以补充上去就可以破解注册了
尝试写个注册机
import binascii
key = "paidaxing0@163"
ds = 0
bl = 65
for al in key:
xor = chr(ord(al) ^ bl)
ds += ord(al) ^ bl
bl += 1
print("累加后ds :{:0>4}".format(hex(ds)[2:]))
xor = str(hex(ds ^ int("0x12345678", 16)))
print("异或后的:",xor)
result = ""
for i in range(2,len(xor),2):
s = xor[i:i+2]
result += chr(int(s,16))
key += result[::-1]
print("最终的key:",key)
with open(r"C:\Users\Administrator\Downloads\key",'wb')as f:
f.write(key.encode("utf-8"))
UPX的壳,需要简单的脱个壳
直接运行,会跳转到 jmp,F8跟进,这里就是程序的入口点OEP
下面的一堆东西可以右键分析,模块中删除分析,代码就取出来了
正常以后右键选 od脱壳调试进程,直接脱壳得到正常的文件
正常文件拖进od 分析,在成功的前面有一个跳转,我们只要让他不跳就可以进到 success
最简单的方法就是爆破了,jnz改 jz ,或者就是 NOP填充
另一种方法,还是要分析一下他这个怎么判断的
可以看到我随便输入的一个123456给到了EAX,然后EDX被赋值了一个特别的字符串,F7跟进call 看看做了什么比较让jnz跳的
比较这两个字符串是否相等,这个时候再试试输入这个特别的字符串,成功
这个比较简单了,成功上面有一个跳转,还是一样,可以爆破让他不跳进到下面 success
跳过来正好就是输入错误的情况
还是简单分析一下判断的流程,到这读入输入的12345,然后是一个 vb的字符串比较
call出来以后 eax变成 -1,然后给了edi,一直到后面 di 和 si比较,两个都是 0,所以 je就跳了
所以这里如果 vb字符串的比较相同是不是就不跳了,试一下这个时候 call出来 eax是 0,di 和 si 的比较是 -1 和 0,这次 je就不跳了
直接爆破的话很简单,直接修改成功前面的跳转即可,
还是研究一下算法
检查输入的用户名,然后跳转到结束
所以要满足jmp不跳转条件,长度为5的用户名
eax是用户名,ebx是序列号,ecx是用户名长度
取eax减cl,与ebx比较,不等就退出
src = "paidx0"
l = len(src)
flag = ''
for i in src:
flag += chr(ord(i) - l)
print(flag)
l -= 1
运行软件生成一个 dll文件,内容就是我们输入的东西
中间有几个检查,直接跳到了最后面返回,在他们前面的call下断点看看做了什么
先是判断是否存在 reg.dll 这个文件,然后从这个文件中读取用户名和序列号
F7 进入到这个函数,又两个比较, eax 和 0x10(16)比较,不满足跳转,向下执行会发现eax是序列号长度,所以这里要求序列号长度16
然后进一个循环,0x11(17),也就是把所有的序列号都取出来检查了一遍
继续往下,猜测这个应该就是日期,然后进下一个call,返回一个16位的字符串,猜测是真序列号
进入到一个复杂的计算算法中,返回了几个长度较长的字符串
应该是检查序列号的,然后修改bl,后面ebx给eax然后退出函数,如果 al是1时,ZF是0,je此时就不跳转
用上面拿到的真序列号测试一下