Start
0x01 信息收集
没有点击ok的按钮,只有输入数字或者其他的按钮,总共13个
VB Decompiler看看,可以看到总共有13个Button的回调函数,分别对应上面的按钮,剩下4个定时器,所以可以确定Status的状态是通过Timer定时器定时读取Serial中的值进行判断的
看到Timer1的回调函数,发现REGISTRIERT字眼,说明这个回调函数就是用来定时监视Serial的值是否正确的:
0x02 流程分析+算法破解
拖进OD,搜索字符串,发现一大堆相同格式的字符串,这里只是混淆,唯一的字符串只有一个,
观察所有加密结果,可以发现,只有这个字符串是0-F范围的,猜测这个应该是正确的加密结果:
输入123456789
rtcLeftCharVar(res, var_44, 0x02)取从左边开始数两个字符,也就是12:
将前两个字符转成数字,存入ebp-0xCC中,这里是调用的fstp进行压栈,所以压入的值是体现为浮点10进制:
相当于int("12", 10)
fstp => pop
fild => push
fadd => add,不写src的位置,默认是往ST(0)将,结果存到ST(0),也就是十进制:49+12 = 61 => 十六进制:3D,最终得到的61通过fstp存入ebp-0x7C:
拼接到0018FA8C,随后调用vbaVarMove将数据结果放到ebp-34
直接完成循环,观察ebp-34指向的地址,最终得到:03D3E3F404142434445
整理注册码生成算法:
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
Comments NOTHING