点击上方↑↑↑蓝字[协议分析与还原]关注我们
“ 放出Charles注册激活码算法。”
前几(好多)天分析过Charles注册激活码算法,想着很简单,授人以鱼不如授之以渔,就没有详细写算法。结果有人问我:代码呢?
罢了罢了,没问题,今天放出完整代码。简单说下,算法主体是RC5,里面加了随机值,所以相同的Registered Name,每次生成的License Key是不一样的,其它都是细节,这里不做详细说明了,认真尝试,你肯定能学到一些东西的。
代码是python的,用好不谢。
本来准备写成小程序提供给大家体验的,结果备案太复杂,把我打败了,罢了罢了,以后再说。
import random
import struct
def rotl(n, bits):
dsec = bits % 32
n = n & 0xffffffff
return ((n << dsec) | (n >> (32 - dsec))) & 0xffffffff
def rotr(n, bits):
dproto = bits % 32
n = n & 0xffffffff
return ((n << (32 - dproto )) | (n >> dproto )) & 0xffffffff
class RC5(object):
def __init__(self, key):
nrounds = 12
t = nrounds * 2 + 2
S = [0xb7e15163]
for i in range(1, t):
S.append((S[-1] + 0x9e3779b9) & 0xffffffff)
A = 0
B = 0
i = 0
j = 0
L = list(key)
for ii in range(3 * max(t, len(key))):
A = S[i] = rotl(S[i] + A + B, 3)
B = L[j] = rotl(L[j] + A + B, A + B)
i = (i + 1) % t
j = (j + 1) % len(key)
self.nrounds = nrounds
self.t = t
self.S = S
def encrypt_block(self, A, B):
A = (A + self.S[0]) & 0xffffffff
B = (B + self.S[1]) & 0xffffffff
for i in range(1, self.nrounds + 1):
A = (rotl(A ^ B, B) + self.S[2 * i]) & 0xffffffff
B = (rotl(B ^ A, A) + self.S[2 * i + 1]) & 0xffffffff
return A, B
def decrypt_block(self, A, B):
for i in range(self.nrounds, 0, -1):
B = rotr(B - self.S[2 * i + 1], A) ^ A
A = rotr(A - self.S[2 * i], B) ^ B
B = (B - self.S[1]) & 0xffffffff
A = (A - self.S[0]) & 0xffffffff
return A, B
def pad0(s): return s + bytes([0] * (16 - len(s) % 16))
def crack(text):
buff = struct.pack('>I',len(text))+text.encode('utf-8')
length = len(text) + 4
if(length % 16==0):
padded = length
else:
padded = 16 - length % 16+length
buff = pad0(buff)
protosecName = RC5((0x691cd470, 0x7a21c951))
outBuff=b''
for i in range(0,padded,8):
bf=buff[i:i+8]
(nowVar1,nowVar0)=struct.unpack('>II',bf)
(dd1,dd0) = protosecName.encrypt_block(nowVar0,nowVar1)
outBuff=outBuff+struct.pack('>II', dd0,dd1)
n=0
for i in range(0,len(outBuff)):
b =int.from_bytes(outBuff[i:i+1], byteorder='big', signed=True)
n=rotl(n^b, 0x3)
n=int.from_bytes((n).to_bytes(4, 'little', signed=False), 'little', signed=True)
prefix= n ^ 0x54882f8a
suffix= random.randint(1,2147483647)
inn = prefix << 32
s = suffix
s1=suffix >> 16
if s1==0x0401 or s1==0x0402 or s1==0x0403:
inn |= s
else:
inn |= 0x01000000 | (s & 0xffffff)
(innb, inna) = struct.unpack('>II', inn.to_bytes(8, 'big', signed=True))
out = RC5((0xEC0EAFAD,0xB4F0E0CC)).decrypt_block(inna, innb)
n2=0
for i in range(56, -8, -8):
nprotosec = int.from_bytes((inn).to_bytes(8, 'big', signed=True), 'big', signed=False)>> i
nprotosec &=0xff
n2 ^= int.from_bytes(nprotosec.to_bytes(8, 'big', signed=False),'big', signed=True)
vv= n2 & 0xff
if vv < 0:
vv = -vv
return (vv.to_bytes(4, 'big', signed=True)[3:]+out[1].to_bytes(8, 'big', signed=True)[4:] + out[0].to_bytes(8, 'big', signed=True)[4:]).hex().upper()
if __name__ == '__main__':
name='protosec'
protoseckey=crack(name)
print(name,protoseckey)
别忘点“在看”、“赞”和“分享”
新的规则,及时收推文要先给公号星标
别忘了星标一下,不然就错过了
长按进行关注,时刻进行交流。