054
无壳
暴力破解
字符串查找找到相关跳转,将该跳转给nop掉即可获取破解版本软件
算法分析
先是获取用户名和序列号,之后将这两个参数利用函数调用,根据返回结果,判断跳转成功或者跳转失败
步进函数继续分析先是判断用户名和序列号的第一位是否相等,之后再判断序列号第二位是不是“-”,之后经过循环将用户名的每一位ASCII码值累加,再将和+0x6064,求出a
之后构造字符串“用户名第一位-用户名最后一位大写字母-a的十进制整数”之后再构造了一个整数b,b=a+0x6064
之后将十进制的数b添加到之前生成的字符串,生成真正的序列号“用户名第一位-用户名最后一位大写字母-a的十进制整数-b的十进制整数”
将生成好的序列号与用户输入的序列号进行逐位对比,不相等就直接跳转到函数末尾
最后可以生成keygen:
username=input("Input username:").strip() sum=0 serial='' for ch in username: sum+=ord(ch) sum+=0x6064 print(f"sum:{sum}") serial=username[0:1]+'-'+username[len(username)-1:len(username)].upper()+'-'+str(sum) print(serial) sum+=0x6064 print(f"sum:{sum}") serial+='-'+str(sum) print(serial)055
ASPack壳
脱壳
暴力破解
X32dbg调用脱壳后的程序,可以发现他需要一个文件,还有一个神秘数字,在程序对应目录下创建文件之后在文件内填写神秘数字,继续运行分析程序
向下找到关键跳转,将该跳转给改成jmp即可获取破解版本软件
算法分析
验证存在文件,文件内容全为X,循环验证
056
无壳
暴力破解
根据字符串查找可以知道输入的字符串长度限制
关键跳转下断点可以发现,经过一个循环之后相等才跳转成功,直接将判断相等的跳转额判断序列号是否验证结束的跳转给改成jmp,判断序列号长度的前两个跳转给nop掉即可获取破解版本软件
算法分析
先是获取用户名判断长度是否在5-32之间,之后将前五个字符进行循环操作生成新的序列号,每个字符异或0x29再+(5-i),之后判断是否处在A-Z之间,如果不是就用0x52+(5-i)来作为新生成的序列号字符。这里的用例是admin,对应生成的前五个字符为MQGBH
之后再对前五个字符进行操作,先是异或0x27,再+(5-i)+1,将结果判断是否处在A-Z之间,如果不是就用0x4D+(5-i)来作为新生成的序列号字符。这里的用例是admin,对应生成的前五个字符为LHNQK
之后验证序列号是否为MQGBHLHNQK的变形为KZMKAFADZB,获取每个字符先+0x5如果ASCII码值大于‘Z’,则-0xD,之后再异或0xC,判断小于‘A’则将0x4B+字符串下下标作为生成后的字符,判断大于‘Z’则将0x4B-字符串下下标作为生成后的字符
可以生成keygen:
username=input("Input username:").strip() se1='' se2='' for i,ch in enumerate(username): if i==5: break char1=(ord(ch)^0x29)+(5-i) if char1<0x41 or char1>0x5A: char1=0x52+(5-i) se1+=chr(char1) for i,ch in enumerate(username): if i==5: break char2=(ord(ch)^0x27)+(6-i) if char2<0x41 or char2>0x5A: char2=0x4D+(5-i) se2+=chr(char2) se=se1+se2 serial='' for i,ch in enumerate(se): char=ord(ch)+0x5 if char>0x5A: char-=0xD char=char^0xC if char<0x41: char=0x4B+i if char>0x5A: char=0x4B-i serial+=chr(char) print(serial)