Typora 1.0.4版本破解复现
本帖最后由 Kvancy 于 2024-9-27 20:50 编辑## 1. 找到app.asar文件解包得到License.js加密代码
根据火绒剑在系统日志里监控Typore的启动,找到可疑的asar文件,程序访问并读取了该文件,并启动了其中的main.node模块,疑似开发者对加密源代码的解密过程
找到app.asar文件,根据日志显示,可以猜测这个类似压缩包,问Bing得知
> (https://blog.csdn.net/happydeer/article/details/123162612)
根据提示内容进行解压, `asar extract app.asar unpacked`
得到unpacked文件,貌似找到关于许可证的有关文件--License.js,Winhex打开看一眼
有种base64编码的感觉,难道只是base64编码加密?拖进CyberChef解密一下
可能还有一层或几层加密
## 2. 从main.node文件找License.js的解密逻辑
根据火绒剑日志显示,在app.asar解包后运行了main.node模块,又根据前面License.js被加密了,可以推测main.node有可能运行时解密了License.js文件,先DIE看一眼main.node,DLL64位,IDA64打开,先不管其他的,shift+f12查找字符串
疑似有base64解密过程,交叉引用找到引用处伪代码
根据Bing得知
> napi_get_named_property 是一个 Node-API 的函数,它的作用是从一个对象中获取一个指定名称的属性,并返回它的值。
> ```C
> napi_status napi_call_function(napi_env env, napi_value recv, napi_value func, size_t argc, const napi_value* argv, napi_value* result);
> ```
>
> 其中,参数的含义是:
>
> - `env`: 当前调用 N-API 的环境。
> - `recv`: 要作为函数接收者的对象,通常是 `this` 的值。
> - `func`: 要调用的函数对象。
> - `argc`: 要传递的参数的个数。
> - `argv`: 要传递的参数的数组。
> - `result`: 用于接收函数返回值的指针。
分析得知,这段代码类似给v40进行解码,v40 =base64.from(v38),v38又来自函数的第三个参数a3+8,猜测这个a3+8指向的就是密文的地址,动调验证下,x64dbg直接拖Typora,手动下一个main.node的断点,再根据IDA中给出的偏移计算出调试器里解密函数的地址,根据64位下寄存器默认传参顺序是ECX,EDX,R8,R9知道a3的值储存在R8中,所以R8+8指向密文地址,验证:
这里的数据刚好对应的是atom.js里的密文
验证成功,继续分析
找到类似加密算法的密钥初始化,用findcrypt看一眼发现了AES的S盒和逆S盒,推测这里应该是AES的密钥,而且长度为32个字节,猜测是256位模式
接着找AES解密线索,找到F4E0偏移处函数
里面有S盒和异或的继续分析,确定下ECB模式还是CBC模式
进入3A8F偏移处函数分析,在这里先猜测block应该是密文(void 指针数组)
函数里面又出现了一个循环异或,可以肯定这是个CBC模式下的异或偏移量了,那偏移量又是怎么来的呢,追踪a2(密文地址)进行判断的话,函数里面是复制了一份a2给v3,也就是说v3可能指向了密文
那么result就是偏移量了,偏移量来自密文地址+v5处,进行16次循环,也就是说偏移量可能来自密文的0-15个字节位?
## 3. CyberChef验证猜测
依据之前的猜测,main.node通过base64解码,再AES,CBC模式解码,密钥IDA动调得到
> 0x4E, 0xE1, 0xB3, 0x82, 0x94, 0x9A, 0x02, 0x4B, 0x80, 0x2F, 0x52, 0xB4, 0xB4, 0xFE, 0x57, 0xF1, 0xBE, 0xF4, 0x08, 0x53, 0x10, 0x92, 0x56, 0xE2, 0xC2, 0x0D, 0xEC, 0xA3, 0xDD, 0x8D, 0xD5, 0x6D
偏移量为密文的前16个字节,带入CyberChef检验
这下应该是得到了License.js源码,下载得到文件,找在线js美化工具美化
## 4. 最终的Patch
简单审计了下代码,不懂的找Bing问就是。首先应该patch掉网络验证类似request的东西,找到了几处
patch掉网络验证,对doActivation的验证直接改成永恒真,使得邮箱和序列号随便填即可激活,再改写hasLicense的值,使得下次登录时访问许可证信息时得到软件已被激活的信息,再打包生成app.asar,打开软件随便输入序列号和邮箱即可
## 5. 破解成功
虽然我很仔细的看了,还是没有看明白 旧版本注册机源码:
function randomSerial() {
var $chars = 'L23456789ABCDEFGHJKMNPQRSTUVWXYZ';
var maxPos = $chars.length;
var serial = '';
for (i = 0; i < 22; i++) {
serial += $chars.charAt(Math.floor(Math.random() * maxPos));
}
serial += (e => {
for (var t = "", i = 0; i < 2; i++) {
for (var a = 0, s = 0; s < 16; s += 2) a += $chars.indexOf(e);
t += $chars
}
return t
})(serial)
return serial.slice(0, 6) + "-" + serial.slice(6, 12) + "-" + serial.slice(12, 18) + "-" + serial.slice(18, 24);
}
console.log(randomSerial()); Hmily 发表于 2024-9-27 19:42
@Kvancy 图片盗链无法显示,上传本地吧。
感谢提醒{:1_919:} 有一个问题,打包回去的时候,是AES加密再base64编码一下这样?还是直接用解密后的源码打包成app.asar
大佬牛逼 大佬,图挂 了,飞书上的图? @Kvancy 图片盗链无法显示,上传本地吧。 感谢楼主分享的原创教程 大佬牛逼,可惜我不懂分析,哈哈。 一张图片我也没看到{:301_1008:} 跟着大佬学逆向