运行分析
- 用win7或win xp系统可以运行
- 输入Serial,点击Check无反应
PE分析
- ASM程序,32位,无壳
静态分析&动态调试
- ida找到关键字符串
- 在sub_401E6B处按x,返回上一步函数
- 来到关键函数,静态分析逻辑如下:
- 1、Serial长度为29
- 2、Serial第6/12/18/24位为’-’
- 3、有检测调试模式,需要patch调试判断(直接NOP)
- 4、通过func_1、func_2、func_3、func_4、func_5检测Serial是否满足要求
- 启动动态调试,在401CDB地址右键,点击Force jump强制跳转,绕过时间检测
- 动调func_1,返回值需要为0,Serial前5位需满足上图计算公式
- 分别对func_2~5进行分析,发现和func_1一样,分别判定了Serial每5位的条件
算法分析
Serial = [0] * 25
Serial[5] = '-'
Serial[11] = '-'
Serial[17] = '-'
Serial[23] = '-'def func_1(Serial):return (Serial[4] * ( Serial[4] + Serial[3] * (Serial[3] + Serial[2] * (Serial[2] + Serial[1] * (Serial[1] + Serial[0]))))) ^ 0x31CF15A9;def func_2(Serial):return Serial[4] *(Serial[4] + Serial[3] * (Serial[3] + Serial[2] * (Serial[2] + Serial[1] * (Serial[1] + Serial[0])))) - 680588896;def func_3(Serial):return Serial[4] *(Serial[4] + Serial[3] * (Serial[3] + Serial[2] * (Serial[2] + Serial[1] * (Serial[1] + Serial[0])))) - 742389200;def func_4(Serial):return Serial[4] * (Serial[4] + Serial[3]* (Serial[3] + Serial[2]* (Serial[2] + Serial[1] * (Serial[1] + Serial[0])))) - (((Serial[4] * (Serial[4]+ Serial[3] * ( Serial[3] + Serial[2] * (Serial[2] + Serial[1] * (Serial[1] + Serial[0]))))) >> 32 != 0) + 798775313);def func_5(Serial):return Serial[4] * (Serial[4] + Serial[3] * (Serial[3] + Serial[2] * (Serial[2] + Serial[1] * (Serial[1] + Serial[0])))) // 0x2D418AD4 - 1;k = '1234567890abcedfghijklmnopqrstuvwxyz'for i in range(0,5):n = 0for s_1 in k:for s_2 in k:for s_3 in k:for s_4 in k:for s_5 in k:s = [ord(s_1),ord(s_2),ord(s_3),ord(s_4),ord(s_5)]if i == 0:if func_1(s) == 0:print("".join([chr(i)for i in s]),end='')print('-', end='')n = 1if i == 1:if func_2(s) == 0:print("".join([chr(i)for i in s]),end='')print('-', end='')n = 1if i == 2:if func_3(s) == 0:print("".join([chr(i)for i in s]),end='')print('-', end='')n = 1if i == 3:if func_4(s) == 0:print("".join([chr(i)for i in s]),end='')print('-', end='')n = 1if i == 4:if func_5(s) == 0:print("".join([chr(i)for i in s]),end='')n = 1if n == 1:breakif n == 1:breakif n == 1:breakif n == 1:breakif n == 1:break
- 使用爆破的方法,每5位进行一次爆破,假设Serial的值为数字或小写字母
- 验证成功