这份文档描述了一种用于解密特定资源(通常为 Delphi 窗体文件 .dfm)的单字节滚动密钥算法。该算法通过一个初始密钥对数据进行异或解密,并在解密每个字节后动态更新密钥状态。
key = 0xD7
for each byte c of the form's class name (original case): key ^= c
for i in 0 .. n-1: # n = resource size
plain[i] = cipher[i] XOR key
key = (key + ((n - i) & 0xFF)) & 0xFF # add remaining byte count
key = ROL8(key, 1) # rotate-left 1 within a byte
算法流程详解
- 密钥初始化
算法的第一步是生成一个基于窗体类名的初始密钥。
- 设定种子:将一个临时密钥变量初始化为固定值 0xD7。
- 类名混淆:遍历窗体类名的每一个字节(区分大小写),并将临时密钥与该类名字节进行异或(XOR)运算。
- 结果:经过上述运算后得到的临时密钥值,即为解密数据的初始密钥。
- 解密主循环
获取初始密钥后,算法将遍历资源的每一个字节(设资源总大小为 n),执行以下操作:
- 解密字节:将密文的当前字节与当前密钥进行异或运算,得到明文的对应字节。
- 更新密钥(加法):将当前密钥加上“剩余的未解密字节数”(即 n - 当前索引 i),并只保留结果的低 8 位(确保值在 0-255 之间)。
- 更新密钥(位旋转):将上一步计算出的新密钥值进行8位循环左移1位操作。
通过以上步骤循环往复,直至所有字节解密完成。
核心原理分析
为何无需类名即可解密
该算法虽然使用类名作为密钥种子的一部分,但在实际解密时,可以利用数据格式的特征直接反推初始密钥,而无需预先知道类名。
- 已知明文特征:所有目标资源(DFM 文件)在明文状态下,其文件头的第一个字节必然是字母 T(这是文件内部特定标记的开头)。
- 反推逻辑:
- 解密公式为:明文[0] = 密文[0] XOR 初始密钥。
- 由于 明文[0] 已知为 T,且 密文[0] 可以直接读取,因此可以直接计算出 初始密钥 = 密文[0] XOR 'T'。
- 结论:既然初始密钥可以通过计算得出,那么解密过程就不再依赖于窗体类名。
关于旧版算法的说明
早期的同类资源(如旧版插件或工具涉及的资源)可能采用了不同的加密方式(例如基于 4 个 32 位状态字的流密码)。然而,当前所述的算法与旧版不同,它采用了更简洁的单字节滚动密钥机制,旧版的解密工具在此场景下将无法使用。
这份文档描述了一种用于解密特定资源(通常为 Delphi 窗体文件 .dfm)的单字节滚动密钥算法。该算法通过一个初始密钥对数据进行异或解密,并在解密每个字节后动态更新密钥状态。
算法流程详解
算法的第一步是生成一个基于窗体类名的初始密钥。
获取初始密钥后,算法将遍历资源的每一个字节(设资源总大小为 n),执行以下操作:
通过以上步骤循环往复,直至所有字节解密完成。
核心原理分析
为何无需类名即可解密
该算法虽然使用类名作为密钥种子的一部分,但在实际解密时,可以利用数据格式的特征直接反推初始密钥,而无需预先知道类名。
关于旧版算法的说明
早期的同类资源(如旧版插件或工具涉及的资源)可能采用了不同的加密方式(例如基于 4 个 32 位状态字的流密码)。然而,当前所述的算法与旧版不同,它采用了更简洁的单字节滚动密钥机制,旧版的解密工具在此场景下将无法使用。