VMP3.2授权分析
多数加壳工具都会提供许可保护功能,来方便用户进行快速的软件产品授权发布。当一款这样的软件被破解后,其他同类软件也会遭到严重威胁,城门失火,殃及池鱼。这里分析一下VMP3.2最新版的授权许可功能及安全性,希望给大家带来一些思考和警示。下面仅使用x86测试用例进行逆向,以此达到通用破解补丁的目的。
1. 授权系统
加壳时使用RSA算法对授权信息进行加密,程序运行时对其进行解密并验证。授权信息加密后使用BASE64算法进行编码。
代码虚拟化绑定产品代码
VMP许可详细
其中序列号为加密后的许可信息,序列号内容为实际要加密的数据,具体格式:
struct VMProtectSerialNumberInfo
{
INT flags;
wchar_t *pUserName;
wchar_t *pEMail;
DWORD dwExpDate;
DWORD dwMaxBuildDate;
BYTE nRunningTimeLimit;
char *pHardwareID;
size_t nUserDataLength;
BYTE *pUserData;
};
2. 测试用例
若要使用VMP的许可授权系统,需要程序中调用VMP特定API实现。无源码程序无法使用VMP授权系统如记事本,代码参考VMP帮助文档,测试代码如下:
VMProtectSetSerialNumber 对许可信息进行验证,返回值表示是否验证通过。
3. 破解分析
下面提供几种破解方法,通过分析利弊选择方法3进行破解分析。
1. 找到VMProtectSetSerialNumber并修改返回值进行破解,由有虚拟化或混淆进行保护比较难找到并且每个程序每次加壳后都需要重新分析确定函数地址方可实现,通用性无法保证。
2. 替换程序中的RSA公钥,首先需要定位RSA-N,由于N的存储进行了加密,无法在文件或内存中进行扫描得到。必须进行虚拟机逆向分析出N的加密算法和密钥,通过特征数据定位内存中的N进行替换。此方法通用性较佳但分析虚拟机和特征定位非常困难,此方法为完美破解同时也需要一定的技术。
3. 通过HOOK特定API,在关键点对RSA-N进行修改替换达到破解的目的。VMP中N在内存里也是被加密的,N在计算过程中不会出现完整的明文N,所以为了替换N还需要分析部分虚拟机加密算法,但工作量远远小于2的方法。
4.算法分析
下面分析方法3中的算法,
1). Base64解码N
使用大数库时内存中为:
扫描上述大数发现程序中未找到,说明该N已被加密,其加密方式后续。
2). 定位RSA-N
大数在使用时通常都需要分配内存,VMP通过RtlAllocateHeap进行大数空间分配其大小为大数字节数+2字节,对其下断点可跟踪到RSA-E/RSA-N和密文空间的分配,
当第一次分配大小为102即为N分配内存空间。
3). 加密算法
通过对N内存空间下硬件断点可查看加密后的数据变化(多重加密),最终形态为密文
经过多次跟踪发现,N由分配后地址进行加密,因此每次加密可能都不一样,因地址而变化。每次加解密2字节,其加密算法如下:
已知条件:
Ptr=00A72C82 N 所在内存地址
P1 = 2C82 地址低2字节
P2 = 72C8 地址2
K = P2 + 10 + 37 = 730F 其中37为固定值,10为随机大小为1字节,每次程序运行该值都有变化(key)
加密算法如下:
M = AD31 明文 N的最低2字节
A = NOT(M) + P1 = 7F50 中间结果
I = NOT(A OR K) = 80A0
J = NOT((NOT(A))OR(NOT(K)) = 7300
C = I OR J = F3A0 结果,可以对照明文和密文
反推解密算法:
M = NOT(NOT(C XOR K) – P1) = AD31
4). 其他
N 的加密过程很可能是 N = A + B 其中A和B 分别存储,如下:
其中 1 很可能是A,而2是最终的A + B,有待进一步验证,如果验证通过可通过方法2进行完美破解。
如果VMP使用了压缩还需要进一步验证,但不会影响方法3。
5. KEY算法
继续分析RSA-N的加密算法,主要针对key的生成及相关算法。
相应RSA-N加密结果及KEY 使用情况
每次加密RSA-N分段及KEY随机变化。其分析代码如下:
查找KEY
Key大小为20字节,存放在栈中,通过堆分配地址定位该KEY。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2019-2-1 10:25
被kanxue编辑
,原因: