元气桌面(kwallpaper)VIP 解锁逆向分析
前言
元气桌面是一款国产壁纸/桌面美化软件,使用 kvipsdk.dll 控制 VIP 功能。本文记录逆向分析过程。
环境
- 软件路径:
D:\新建文件夹\kdesk\
- 核心 DLL:
kvipsdk.dll(1.6MB, x86, VC++ 编译)
- 工具:IDA Pro + Frida
一、日志定位
启动软件后查看日志 log\kwallpaper.kvipsdk.dll.log,发现关键信息:
[WARNING] account.cpp:692 Account::GetLocalUserPermission
→ open reg or read reg or data is empty
[WARNING] vip_sdk_core_interface_impl.cpp:602 KVipSdkCoreImpl::IsVipByCache
→ user is logout or is tourist
[WARNING] vip_sdk_core_interface_impl.cpp:587 KVipSdkCoreImpl::IsVip
→ user is logout or is tourist
DLL 中有两个核心 VIP 校验函数:IsVip(行587)和 IsVipByCache(行602),都报"用户已登出或是游客"。
二、IDA 定位关键函数
用 IDA Pro 加载 kvipsdk.dll,搜索完整日志字符串:
反编译确认后找到两个函数:
| 函数 |
地址 |
大小 |
说明 |
KVipSdkCoreImpl::IsVip |
0x10025950 |
0x303 |
VIP 综合判断 |
KVipSdkCoreImpl::IsVipByCache |
0x10025C60 |
0x2F9 |
VIP 缓存判断 |
两者紧挨着,都是 bool __stdcall 类型,返回 al 寄存器。
IsVip 反编译核心逻辑:
bool __stdcall KVipSdkCoreImpl::IsVip(int a1) {
v8 = 1; // 默认禁止
if (!v17[104]) { // is_logout==0(未登出)
// 检查权限值
if (dword_10180118 != v7)
v8 = 0; // 权限不匹配→放行
}
if (v8) {
LOG("user is logout or is tourist");
return 0; // 返回 false(非VIP)
}
return sub_10025F60(a1, 0) > 0; // 返回VIP状态
}
也就是说即使绕过了 is_logout/is_tourist 标志,函数有两条独立的返回路径,必须直接从源头堵住。
三、Patch 方案
两个函数都改为直接返回 true:
Patch 1 — IsVip 0x25950
原函数入口(SEH 序言):
push -1
push offset SEH_
mov eax, large fs:0
...
改为:
mov al, 1 ; B0 01
ret 4 ; C2 04 00
Patch 2 — IsVipByCache 0x25C60
同上,直接返回 true。
字节修改前后:
原:55 8B EC 83 E4 F8 6A FF 68 ...
改:B0 01 C2 04 00
四、辅助标志清理
日志中还有 is_logout、is_tourist 标志位的设置点,分布在多个函数中。虽然不是必须(因为 IsVip 已经返回 true),但清理了更干净:
| 偏移 |
所在函数 |
修改 |
0x63DB |
GetLocalUserInfo |
setnz dl → mov dl,0(is_logout=false) |
0x65B5 |
GetLocalUserInfo |
setnz al → mov al,0(is_tourist=false) |
0x11110 |
JSON 解析器 |
setnz al → mov al,0(is_tourist=false) |
0x5A3D |
FreshUserInfo |
setnz cl → xor cl,cl(is_tourist=false) |
注意:FreshUserInfo 里用的是 setnz cl(不是 al),一开始没发现导致 patch 无效。
五、踩坑记录
坑 1:两个函数缺一不可
只 patch 了 IsVip,日志还在报 IsVipByCache 错误。两个函数都得改。
坑 2:hosts 文件
一开始发现 duba-defend.zhhainiao.com 在 hosts 中被指向 127.0.0.1,以为需要改 URL。实际检查发现:
127.0.0.1 duba-defend.zhhainiao.com ← VIP 服务器
127.0.0.1 yuanqi-wallpaper-h5.zhhainiao.com ← 壁纸下载域名
127.0.0.1 img-baofun.zhhainiao.com ← 图片 CDN
壁纸下载域名也被拦了。删除 hosts 中所有 zhhainiao.com 条目后网络正常。
坑 3:GetLocalUserPermission 不需要改
最开始 patch 了这个函数,但它有 SEH 序言,直接跳过会破坏异常处理链。只要 IsVip/IsVipByCache 返回 true,这个函数的返回值不影响结果。
坑 4:过度修改
不要动 URL、不要改 HTTP 函数、不要改注册表函数——只改两个核心 VIP 判断函数就够了。
六、最终方案
只需要改 kvipsdk.dll 的两个字节点:
偏移 0x25950: B0 01 C2 04 00 ← IsVip → mov al,1; ret 4
偏移 0x25C60: B0 01 C2 04 00 ← IsVipByCache → mov al,1; ret 4
备选:Frida 运行时注入
也可以使用 Frida 在内存中 Hook 这两个函数,效果相同:
var base = Module.findBaseAddress("kvipsdk.dll");
// Hook IsVip
Interceptor.attach(base.add(0x25950), {
onLeave: function(retval) { retval.replace(1); }
});
// Hook IsVipByCache
Interceptor.attach(base.add(0x25C60), {
onLeave: function(retval) { retval.replace(1); }
});
七、总结
- 核心是
IsVip + IsVipByCache 两个函数,都 patch 为返回 true
- hosts 文件中的
zhhainiao.com 条目需要删除,否则壁纸下载失败
- 最小修改只需要 10 个字节(每个函数 5 字节)
- Frida hook 可作为免修改方案
声明:本文仅作逆向技术研究和学习交流,请勿用于商业用途。