新160个CrackMe026-KeygenMe、027-MexeliteCRK1、029-figugegl.1逆向分析
026
无壳
暴力破解
发现关键跳转,nop掉即可获得破解版
算法分析
向上可以找到函数头,顺着函数头分析发现有一部分汇编代码是与序列号检验算法无关的,接续向下找发现读取用户名和序列号的函数在这个关键点下断点
先取用户名的的第一个字符将其ASCII值求二次幂,存到esi里,再对字符ASCII码值算术右移0x1,再+0x3,*字符ASCII码值,得到的结果-字符ASCII码值,加到esi里面去,最后对esi求2倍,用户名长度-1,eax+1,一直循环到用户名为空,将其结果与之前读取的序列号进行对比,相等则判断成功,否则失败
可以生成keygen:
username=input(f"Input username:").strip() def arithmetic_right_shift(x: int, n: int, width: int = 32) -> int: n %= width if n == 0: return x mask = (1 << width) - 1 x &= mask sign_bit = (x >> (width - 1)) & 1 shifted = x >> n if sign_bit: high_mask = ((1 << n) - 1) << (width - n) shifted |= high_mask return shifted & mask sum=0 for ch in username: sum+=ord(ch)**2 index=arithmetic_right_shift(ord(ch),1)+3 sum+=(index*ord(ch))-ord(ch) sum=sum*2 print(f"Serial:{sum:08x}")但是生成的序列号有些是不可打印字符没办法验证,可以在x32dbg调试中观察是否生成的是正确的序列号
027
无壳
暴力破解
该程序只有一个关键跳转,给改成jmp即可获取破解版本
算法分析
深入分析函数发现该程序只是将用户名获取之后与固定字符串Benadryl进行对比,没有进行任何其他操作,将该字符串Benadryl输入未被破解的程序,并随便输入序列号进行测试发现成功,该程序只关心用户名是否为Benadryl
029
无壳
暴力破解
根据字符串追踪,初步判断这是一个获取输入之后循环判断是否相等的简单程序,只需要将两个跳转给nop掉。发现这两个跳转给nop掉也不会达到预期效果
发现是上面还有一个检验输入长度的跳转没有处理,现在将三个跳转都给nop掉即可发现获得破解版软件
算法分析
首先对输入的用户名和序列号的要求是用户名长度不得小于5,序列号存在
下面进行了一个循环,从下标0开始,每个用户名对应的的字符ASCII码值-下标的差将其与该下标对应的序列号的值进行判断,如果在用户名结束时全都相等则验证成功,可以生成keygen:
username=input(f"Input username:").strip() serial="" for i,ch in enumerate(username): serial+=chr(ord(ch)-i) print(f"Serial:{serial}")