首页
社区
课程
招聘
[原创]DMM的DRM解密
发表于: 2020-12-12 10:45 50895

[原创]DMM的DRM解密

2020-12-12 10:45
50895

大家好, 我又来破解电子书了.

话不多说, 这次搞的是DMM和DLsite的DRM保护. 有认识半仙的观众们可能要说了, 你咋老是盯着电子书电纸书一类的薅, 咋不去搞点硬货? 那没办法, 老了牙口不好只会吃软柿子嘛.

本来上次ida时候打算发一发爆破的优化的, 不过写着写着热度就过去了. 毕竟嘛, 10分钟优化到1秒, 别人看你的目光就是你花了几天搞这个还不如等九分钟这样的.

好了这次DMM的电子书, DRM保护系统使用的是CypherTec的CypherGuard, 包括了授权, 反截图, 文件解密三个模块, 分别是ctlicis.dll, cguard.dll, ctcrypt.dll. 这些dll有Themdia壳, exe无壳.

主程序架构是Qt+cocos2d, 应该是为了多平台支持的缘故. 果然它Mac版, 同样是Qt+cocos2d的.

众所周知, DRM一定存在的弱点就是, 本地在某个阶段存在解密数据. 对于图片构成的电子书讲, 可能是中间数据, 也可能是解码后的RGB像素等.

当然了, 这些做DRM的公司也不是吃干饭的, 一定会想办法比如返回后销毁原数据, 对抗apihook, 使用内嵌memcpy等等, 不过嘛再好的SDK也得写exe的程序员用, 你到了Qt和cocos2d这个大坑里, 哪怕exe程序员小心翼翼地使用抗hook的思维, 他们里面那些默认的对象/结构拷贝一类的还是memcpy/memmove, 让我们来看看有没有敏感信息.

简单的写了个Logger的dll, 取名DMMLogger1, 勾了memcpy, memcpy_s, 然后发现尺寸较大时候就hexdump到日志文件, 果不其然, 里面发现了JPEG的文件头, 一块一块的, 每块4k.

结合静态分析和尝试log一些ctcrypt的函数, 我发现4634D4这里的

    if ( !ctcrypt_94(*(_DWORD *)(this + 4148), workmem, size, this + 52, &procsize, rev1048, isscrap) )

这个栈上的workmem就是memcpy的内容来源, 也是4k一块, 第一块有JFIF文件头, 然后dump下执行ctcrypt_94之前的workmem, 再在加密的电子书文件dmmb里面搜索, 可以发现就是dmmb里面的内容.

这时候观众老爷可能就要想了, 啊, 这个破解笔记就到头了, 把dump下来的解密数据组装一下不就jpeg图出来了吗? 比起截图大法已经是原汁原味了.

对于强迫症患者来说, 算法呢, 没有算法, 睡不着觉啊.

刚才在dmmb里面搜索解密前数据时候我也没闲着, 用010Editor打开进程内存, 果不其然搜索解密后的JFIF头, 也能找到完整的jpeg解密后的内容, 其后跟随着解码后的RGB像素. 这应该是cocos2d或者是Qt包装后的对象, 这里也是一个入手点, 最早的时候我也是想过hook下QImage, 从那里抓; 不过现在已经不重要了.

我找到了更好的软柿子. 那就是Mac版的DMMbookViewer.app, 让我们来看看里面有什么敏感信息.

经过一番探索, 在主程序100082150地方发现这么一个函数

 

这里可以看出, authenticationType分为2和6两种, case 2时尝试去取缓存到本地的授权信息, 实际测试中dmmb文件是走到这里的. dmmb文件被他们叫做capsulized file, 直译就是包了胶囊的文件.

刚才说到的windows版有一个ctcrypt_94函数会对来自dmmb文件中的内容进行解密, 然后我习惯性的hook了OSX下的CCCryptorUpdate, 在看到感兴趣的解密后的数据就设法让其崩溃.

我们写好dylib, 使用DYLD_INSERT_LIBRARIES=./DMMLogger1.dylib ./DMMbookviewer, 启动后打开一本书, 如愿以偿地崩了.

这个工作线程崩的不是地方, 因为这是一种Block调用, 是看不到发起方的, 不过崩溃也没白费,下一个线程恰好就是Block的发起方

赶得早不如赶得巧, 忽略后面写日志的调用. 往回看, 有一个函数叫做CypherGuardCore::AES_PCTS_Decrypt_Body, 对应的库在DMMbookviewer.app\Contents\Frameworks\CypherGuardCore.framework, 没有加壳.

而调用方Capsule是加壳了的, 在DMMbookviewer.app\Contents\PlugIns\Capsule.bundle\Contents\MacOS中. 看来这个CypherGuardCore做加解密操作, 而Capsule做文件解析操作.

继续分析主程序可见, 在100214256处, 有如下代码加载Capsule.bundle:

func_decypt_bundle会在/Users/Shared/.Cypher License Information新建包含相对路径的临时文件, 并把原来目录中的capsule解密写入. 然后因为osx允许载入macho后删除, 运行起来后实际是找不到文件的. 它应该是对NSBundle加载的hook.

我们可以选择hook NSBundle的loadAndReturnError方法, 把解密后的文件复制出来, 不过我比较懒, 我hook的是dlopen, 然后检查路径是否在此目录下, 并且复制出来.

我们先来看CypherGuardCore::AES_PCTS_Decrypt_Body的参数, 好来hook它.

void CypherGuardCore::AES_PCTS_Decrypt_Body(char *dst, const char *src, uint64_t srcsize, const void *key, size_t keylen, char *iv, uint64_t offset, void* ivcache, char *finiv)

这里unsigned char vector[16]*都给我简化为了char*, 实际源码应该有类似typedef char aesblock[16]的定义, 然后参数写成aesblock*, 据说是这样数组指针相对于char*更方便编译器对齐和寻址优化, 当然对现代编译器没有意义.

我们顺便把CypherGuardCore::AES_PCTS_Decrypt_CFB_scrap/ AES_PCTS_Decrypt_CBC_scrap/AES_PCTS_Decrypt_CTS_scrap也加上日志

这两者一个处理52000一个处理F57是整个一个子文件的大小52F57, 分为body和scrap分别处理, scrap估计他们取得是边角料的意思, 也就是不能按照4k对齐的部分.

然后是下一个body和scrap.

Body的数据拆分为4k的大块进行解密, 让我们把大块单位设为cube, 和每组16字节的block区分开来.

首先分为n个大块, 然后每块的key是EFBD5E7E3C4463019186D0B23AC670C1, 每块的iv是初始iv使用key循环加密的结果, 第0块经过1轮加密, 依次类推. 最后经过n+1次加密的iv复制给finiv, 后继还有用.

然后CTS_scrap的解密不是太复杂, 也是以16字节为一组的粒度, 分为前面n-2行和后面两行, 前面连续解密后面分两次解密.

连续解密使用的iv从日志中可以看出, 是跟Body输出的finiv同一个地址. 实际确实是解密body最后一次的iv.

后面两块的key也是输入的key, iv则要看是否存在倒数第三行.

如果存在倒数第三行, 使用倒数第三行的密文作为iv, 否则用输入的iv做iv.

最后处理这最后两行, 倒数第二行一定是16字节字节, 直接aes_ecb解密, 输出记为decfullrow,

然后最后一行左对齐复制到16字节的本地缓存tailrow, 与decfullrow进行xor后存入localrow1.

如果最后一行是不完整的, 将localrow1的右侧和tailrow的左侧组合成localrow0.

然后localrow0再进行aes_ecb解密, 输出记为localrowdec. localrowdec 与iv进行xor后存入倒数第二行.

localrow1则存入最后一行.

 

根据以上信息, 我写了个dmmbdec小程序, 能够解出dmmb文件中的子文件的原文. 如果再加上dmmb的文件解析, 就能够解出整个”胶囊包”了.

胶囊包的格式是从哪整理出来的呢?

在+[CPCapsulizedFile capsulizedFileWithContentsOfFile:error:]函数里面, 有一个读取footersize的函数, 然后根据读取出来的footersize选择不同的类初始化.

footersize是输入文件的末尾的4字节内容. 看了下两个dmmb都是3C, 又买了本小说<<龙王的工作>> 网页写是epub, 后缀dmmr, footersize是90. 后面又买了一些限时免费的epub, 后缀dmme的, 也是90.

4个footersize对应4种文件类型, 分别是3C->3 90->1 60->4 F6->2

可见我这里测试的文件都是Version1, 而dmmb对应的处理类是__CPIR_NCwtwzHlh6HmHQ2b, dmmr对应的是__CPIR_XdJKKTxTUCuhXpgR.

这两个类应该分别对应多文件胶囊, 和单文件胶囊. 类的名字估计是用#define的方式, 做了源码级别名称混淆. 应该不是链接后的后处理工具修改macho, 因为后面在这个库和其他库里都会看到, 方法名的每一个参数名都混淆成了很长的字符.

  

因为objc存在着方法类型签名, 所以反混淆必须联动修改签名. 再加上主程序或者多个库之间互相调用, 则需要多个文件一起修改.

我以前没有发现类似的重命名工具, 就自己做了一个, 能够生成修改后的文件也可以生成py脚本补丁到IDA里. 但是这种撑到很长的, 一来不方便通过长度判断本来的单词组合, 二来如果想要改短, 修改字符串表的时候可能会遇到末尾对齐的链接器优化.

比如有两个method, __CPIR_aaaa:__CPIR_bbbb:和__CPIR_bbbb:后者的SEL name可能就是指向前者的中间.

所以我也懒得改它了, 凑合着静态看完了.

当它是多文件胶囊类的时候, 文件末尾的结构如下

根据这个headeroffset我们来到文件对应的偏移, 会有一个这样的结构

当magic正确的时候, 后面会跟

因为没有遇到其他magic, 因此不知道会不会有其他格式的header1.

这个结构末尾紧跟着的是Unicode的文件名, 长度是包含末尾0字符的. 然后跳过padlen后是附带的文件内容, padlen我这里看到都是0.

flag里面会有bit提示文件是不是加密, attributes里面有bit表明他是不是目录. 比如我这里dmmb里面会有一个不加密的index.bin文件, 里面包含了guid信息. 阅读器会用这些信息向CypherTech的服务器请求授权.

这里面还有我们之前提到的iv的前体, 我叫他preiv, 为了便于区分, 之前说的解密文件的叫做filekey/fileiv, 而preiv就是两者的来源.

服务器返回的是证书信息, 存储在cyphertech自己的X:\Cypher License Information\Services目录, 里面会包含servicekey, 用它来解index.bin里面的fileinfo, 在偏移50的地方得到prekey.

描述大概如下

fileiv=aes_ecb_enc(footer1->preiv, keykey)

fileinfo9c=readfile(footer->fileinfodelta, footer->size)   // index.bin for dmmb or entire file

prekey=aes_cts_dec(fileinfo9c, servicekey)->offset50

filekey=aes_ecb_dec(contentskey, prekey)

 

当时主要静态看的, 还发现一种生成key的方式, 估计是测试用途, 实际没有抓到执行.

ivkey=aes_ecb_dec(sha256(phase), keysource)

keykey= hi128(ivkey) ^ lo128(ivkey)

这里ivkey/keykey是servicekey/contentskey昵称, 容易记一些.

我企图比较一下不同的加密文件, 是不是这两个servicekey/contentskey是相同的, 这样我们可以一次抓取, 然后自己生成filekey/fileiv, 不用一本一本书的点开, 并查看日志.

很遗憾根据hook出来的日志, 并非如此.

顺便一提, dmmb里面的index.bin的格式其实和dmmr/dmme格式一样, 只不过不包含文件内容. 它在windows版hook时候是跟dmmr/dmme走同样的VFT函数解析的.

“单文件胶囊”末尾的结构如下

如果是曾经的我, 为了解决”我买了5本书, 还要分5次抓key/iv”的烦恼, 我会花很大功夫, 重写个客户端, 自己搞定验证和返回servicekey/contentskey的流程, 然后就随便怎么解密了.

而现在的我会思考这一切有什么意义, 我起初的初衷只不过是为了博取小朋友的夸奖啊?

抛开这一切, 半仙强迫症复发, 还是决定要做个windows下的工具, 为此我要把mac版的hook位置, 在windows版定位出来.

首先再次用010Editor打开处于阅读状态的阅读器, 然后搜索iv内容, 可以找到iv, 也可以找到key, iv前后的内容还包含有像是证书的字眼.

当然了, mac和windows版虽然界面都是Qt+QML的, 但就是解密架构不一样,  半仙重新拉起来ctcrypt_43开始分析, 因为在之前的分析和hook中, 打开一个dmmb多文件胶囊, ctcrypt_94调用很多次, 而ctcrypt_43只调用一次.

推测的几个导入函数作用为

ctcrypt_43是给CEncryptOperator设置keycontainer.


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2020-12-12 12:22 被曾半仙编辑 ,原因:
上传的附件:
收藏
免费 7
支持
分享
最新回复 (15)
雪    币: 477
活跃值: (1412)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持大仙
2020-12-12 10:56
0
雪    币: 3758
活跃值: (3352)
能力值: ( LV15,RANK:500 )
在线值:
发帖
回帖
粉丝
3
哈哈哈, 不是dmm的dcv解密, 不过dcv我还真的花了时间解了个, 它跟m3u8的ts分段, 压制参数完全相同不说, 帧的数据除了中间一点儿NAL或者时间码一类的几字节格式不同, 其他二进制相等.
再加上electron我不是很熟悉, 也就没写这部分
2020-12-12 11:03
0
雪    币: 220
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
大佬方便传一份可用的安装包吗?DMM更新后就再也找不到旧版了
此外这个软件能否破解DLSITE?用法也是相同吗?
2021-2-9 20:25
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
谢谢大仙
2021-2-15 14:13
0
雪    币: 174
活跃值: (68)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
问一下3.1.13还能用吗,在3.1.13下好像打开书也抓不到文件?提示Select book first!
2021-9-1 16:03
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
问问现在还能用吗
2021-12-9 21:47
0
雪    币: 230
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
能联系到你吗
2022-4-13 15:38
0
雪    币: 230
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
可以私信下我吗
2022-4-13 15:39
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
mb_lpzrormd 可以私信下我吗
fanza的视频(2D,1080p)和电子写真。近两天我自己买了视频和写真,从零碎的帖子里找到了办法,成功提取了。你现在如果仍有需要我可以帮你。
2022-8-5 21:22
0
雪    币: 220
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
745ujx fanza的视频(2D,1080p)和电子写真。近两天我自己买了视频和写真,从零碎的帖子里找到了办法,成功提取了。你现在如果仍有需要我可以帮你。
求私信一下,多谢了
2022-8-26 16:06
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
moenikiller 求私信一下,多谢了
我没法私信,你发其他联系方式嘛
2022-8-28 20:01
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13

fanza的视频(2D,1080p)和电子写真。近两天我自己买了视频和写真,从零碎的帖子里找到了办法,成功提取了。你现在如果仍有需要我可以帮你。




我也买了些fanza的视频和电子写真,必须用它的专用播放器软件,不能用其它的,怎么解密呢?

最后于 2022-8-31 15:22 被mb_npqvimcm编辑 ,原因:
2022-8-31 15:20
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
745ujx 我没法私信,你发其他联系方式嘛
我qq 997279866,我也想了解下提取方法
2022-11-2 15:13
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
745ujx fanza的视频(2D,1080p)和电子写真。近两天我自己买了视频和写真,从零碎的帖子里找到了办法,成功提取了。你现在如果仍有需要我可以帮你。
您好,可以指导一下提取电子写真吗,谢谢
2024-5-8 17:13
0
雪    币: 15
活跃值: (56)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
相当厉害!
2024-10-31 16:54
0
游客
登录 | 注册 方可回帖
返回
//