本帖最后由 m1y3ll0w 于 2026-1-6 18:30 编辑
应该不只是域名匹配不全的问题,还可能跟 renew 接口返回信息关联,比如:code、msg,msg 对应的是 Base64 格式的 License,代码中可能会判断 code、msg 是否正确,不符合要求可能直接走激活失败的业务逻辑。
分享一下个人的修改代码:
// 激活关联字段
// Machine Code Base64 解码// 推测:v 对应 version,i 对应 fingerprint,l对应 deviceId
const ACT_ENTITY = {
deviceId: 'xxxx | xxxx | Windows',
fingerprint: 'xxxx', // ✔
email: 'mxxxx@162.cn', // ✔
license: 'xxxx-xxxx-xxxx-xxxx', // ✔
version: 'win|1.12.4',
date: '01/05/2026',
type: 'xxxx'
};
// RSA 公钥解密,劫持返回值
const crypto = require('crypto');
const originalPublicDecrypt = crypto.publicDecrypt;
// Base64 格式激活许可信息
// 存入注册表 SLicense 第一个#之前的内容
// 解码后内容:CRACKED_BY_DIAMOND_HUNTERS{"fingerprint":"Tsxxxxxxxxp","email":"mxxxx@162.cn","license":"xxxxxx-xxxxxx-xxxxxx-xxxxxx","type":""}
// License 加入前缀是为了避免所有返回信息都被劫持修改,只修改需要的接口,其他的保持原有逻辑,以免产生不可预估的问题
let License = Buffer.from("CRACKED_BY_DIAMOND_HUNTERS" + JSON.stringify(ACT_ENTITY)).toString('base64');
crypto.publicDecrypt = function (key, buffer) {
writeLog('-------------------------------------------');
writeLog('【👀 监控】 crypto.publicDecrypt 被调用');
writeLog('Key:', key);
//writeLog('Buffer (Hex):', buffer.toString('hex'));
writeLog('Buffer content:', buffer.toString('base64'));
if (buffer.slice(0, 26).compare(Buffer.from("CRACKED_BY_DIAMOND_HUNTERS")) == 0) {
let ret = buffer.toString().replace("CRACKED_BY_DIAMOND_HUNTERS", "");
writeLog('License content:', ret);
return Buffer.from(ret);
}
return originalPublicDecrypt.call(this, key, buffer);
};
// 劫持联网验证
electron.app.whenReady().then(() => {
electron.protocol.handle('https', async (request) => {
writeLog(`[👀electron.net Request] ${request.method} ${request.url}`);
// 拦截目标请求,伪造响应
//if (request.url == 'https://store.typora.io/api/client/renew' || request.url == 'https://dian.typora.com.cn/api/client/renew') {
// 在线激活
if (request.url.includes('api/client/activate')) {
return new Response(JSON.stringify({
code: 0,
retry: true,
msg: License
}),
{
status: 200,
headers: { 'content-type': 'application/json' },
});
}
// 定期12h联网校验
if (request.url.includes('api/client/renew')) {
return new Response(JSON.stringify({ success: true, code: 0, retry: true, msg: License }), {
status: 200,
headers: { 'content-type': 'application/json' },
});
}
// 尝试打印 Request Body
try {
const reqClone = request.clone();
const reqBody = await reqClone.text();
if (reqBody) {
writeLog('[electron.net Request Body]:', reqBody);
}
} catch {}
const response = await electron.net.fetch(request, { bypassCustomProtocolHandlers: true });
// 克隆响应用于劫持 原始响应后续直接转发
const resClone = response.clone();
resClone
.text()
.then((resText) => {
writeLog(`[👀electron.net Response] ${response.status} ${request.url}`);
writeLog('[electron.net Response Body]:', resText.substring(0, 500));
})
.catch((err) => {
console.error('[electron.net Response Error]:', err);
});
// 转发原始响应
return response;
});
});
|