CrackMe-011

发布于 2023-04-14  98 次阅读


Start

0x01 信息收集

没有点击ok的按钮,只有输入数字或者其他的按钮,总共13个

image.png

VB Decompiler看看,可以看到总共有13个Button的回调函数,分别对应上面的按钮,剩下4个定时器,所以可以确定Status的状态是通过Timer定时器定时读取Serial中的值进行判断的

image.png

看到Timer1的回调函数,发现REGISTRIERT字眼,说明这个回调函数就是用来定时监视Serial的值是否正确的:

image.png

0x02 流程分析+算法破解

拖进OD,搜索字符串,发现一大堆相同格式的字符串,这里只是混淆,唯一的字符串只有一个,

image.png

观察所有加密结果,可以发现,只有这个字符串是0-F范围的,猜测这个应该是正确的加密结果:

image.png

输入123456789

rtcLeftCharVar(res, var_44, 0x02)取从左边开始数两个字符,也就是12:

image.png

将前两个字符转成数字,存入ebp-0xCC中,这里是调用的fstp进行压栈,所以压入的值是体现为浮点10进制:

相当于int("12", 10)

image.png
image.png

fstp => pop

fild => push

fadd => add,不写src的位置,默认是往ST(0)将,结果存到ST(0),也就是十进制:49+12 = 61 => 十六进制:3D,最终得到的61通过fstp存入ebp-0x7C:

image.png
image.png

拼接到0018FA8C,随后调用vbaVarMove将数据结果放到ebp-34

image.png
image.png
image.png

直接完成循环,观察ebp-34指向的地址,最终得到:03D3E3F404142434445

image.png

整理注册码生成算法:

rtcLeftCharVar取前两个字符,转成数字: key = int(Serial[:2], 10)

结果为encrypt = '0'

循环每次取Serial的一个字符,从最左边开始取,取其ASCII码加上key,转成hex字符串,加到encrypt上:

Serial = '123456789'
encrypt = '0'
key = int(Serial[:2], 10)

for i in Serial:
   encrypt += str(hex(ord(i) + key)[2:]).upper()

print(encrypt)

# 03D3E3F404142434445

0x03 注册码

由于输入是数字和两个特殊字符,在开头的两个必定是数字,否则无法正常执行fstp指令:

那么开头的情况就是10^2一百种情况,直接遍历就可以得到最终结果:

numlist = '1234567890'
encrypt_serial = '0817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C'

def get_key():  
   for i in numlist:
       for j in numlist:
           key = int(i+j, 10)
           tmp = int(encrypt_serial[1:3], 16) - key
           if tmp == ord(i): # 与第一个字符进行比较,这里已经是有唯一解了,不往下继续作比较
               return key
 
key = get_key()
print(key)
Serial = ''
def decrypt():
   encrypt_serial = encrypt_serial[1:]
   i = 0
   while i < len(encrypt_serial):
       Serial += chr(int(encrypt_serial[i:i+2], 16) - key)
       i += 2

print(Serial)

# 74*3032589#**0541238#7412
image.png

End