我又在幻想欣芈朵了...
由于X - m - i - n - d五星的大手影响,避免被和谐,本篇所有X - m - i - n - d均化名为欣芈朵,阅读时注意字符串替换。
==== 02.19更新js代码
- 修复windows上路径不存在会报错的问题。
- 修复macOS上会被强制取消激活的bug。
0x01 oi! 错过了情人节,女朋友「欣芈朵」依然陪我,送我巧克力...
刚起床(僵尸诈尸起床.gif)(油光面满凌乱头发双目无神嘴唇发白干裂身穿黑色羽绒服家徒四壁农村床单),旁边坐着的是我的女朋友欣芈朵, 粉色的头发, 粉色的洛丽塔连衣裙, 黑色的酷洛米Lolita小皮鞋,胭脂色的嘴唇,稚嫩的脸蛋,匀称的身材和白皙的皮肤,名牌的香水一身的jk和裙子, 非常诱人。
突然我紧紧抱着【欣芈朵】:“别离开我好吗?“,【欣芈朵】吓了一跳“呀?怎么啦?我会一直在你身边的哦?”(摸头),我盘坐起来,“对不起,前几天的情人节没有和你好好约会...”,欣芈朵温柔的说“好啦?下次可要好好记住不许忘了哦?出去散散心吧!”(摸头)。
我开心的牵着欣芈朵的手,“走吧!”(牵着她的手出发)
虽然天气非常的寒冷,但我能感受到她手心传来的温度。不!那是爱的热情!
行至城楼阶梯口,我牵着欣芈朵的手“注意楼梯哦?欣芈朵酱~”
欣芈朵:“好的~”抱着我的手一起登上城楼。俯瞰楼下人间大地,观世间百态人生,走了一会儿我们并排靠坐在公共木椅上,突然,欣芈朵说:“qiu酱~有东西想送给你哦~”
我惊喜的问:“诶?纳尼纳尼?me喋喋?”
欣芈朵偷偷向我手心塞了一块巧克力:“是情人节巧克力哦!”,我不禁感动的流下了口水,抱着欣芈朵顺势就要索吻。欣芈朵娇羞的推开我,撕开巧克力的锡箔纸包装:“阿qiu酱,啊~”
我咬下去,巧克力在口中一点点融化,香甜的味道伴随着少女的清香,醇厚的巧克力在我的舌尖纵享丝滑,哦一西!
但就在此时,原本温馨的画面画风一转!
只见疯狂伊文冲了上来,口呐喊着:“炸死你们这对狗男女!”我大惊失色,连忙冲上去挡在欣芈朵身前,没想到还是慢了一步,他双手结印,已经在欣芈朵上施加了火之意志诅咒,我一拳打飞(人设是280斤肥宅)crazy even。
疯狂伊文死前冷笑道:“oioioi! 欧吉桑!qio多麻袋!杀手皇后已经触碰过那个女人了!”
随着疯狂伊文的消失,我缓缓地在欣芈朵面前瘫坐下来。欣芈朵已经被突如其来的攻击吓呆了,被施加了诅咒后晕倒在长椅上。欣芈朵身上时不时浮起红色的咒文,倒映在我的脸上,我缓缓捏紧了拳头,自责道:“马萨卡...无路赛...拔个牙路...又没保护好你...!”(此处内容符合原著一字不改)
0x02 突发!人质劫持事件再升级!可恶!欣芈朵! 等我救你...
就在这时,我手机上收到了一段视频, 里面是一段音频,播放后听到一个谜之黑衣人冷笑着说:“原来欣芈朵在你这里是这样的呀[笑哭]在我那边可是完全不同的哦[呲牙]如果你承受得住的话 就继续播放我给你的视频吧[笑哭][笑哭]”
我颤抖着手点开视频: "这是什么影像.....?这是欣芈朵?不,不是这样的,我可爱的欣芈朵怎么会和你们这么亲.....😭😭😭我们才刚刚交往一个月,这不是真的这不是真的! !但,为什么,为什么看着这个录像带...我心里那么难受😭"
为了拯救欣芈朵,我发誓要破解封印,拯救我的天使少女!
0x021 探索封印!恶毒组织浮出水面!
我打开我的华为笔记本,安装npm i -g @electron/asar.
只见刚触摸到欣芈朵,就弹出各种符咒!好霸道的咒术!
我盘坐在长椅上,缓缓解包asar 欣芈朵包,一探究竟。
Last login: Tue Feb 18 10:44:29 on ttys059
❯ asar extract /Applications/欣芈朵.app/Contents/Resources/app.asar /Applications/欣芈朵.app/Contents/Resources/app
❯ cp /Applications/欣芈朵.app/Contents/Resources/app.asar /Applications/欣芈朵.app/Contents/Resources/app.asar1
╭─ ~ ········································· ✔ 11:45:16 上午
╰─ code /Applications/欣芈朵.app/Contents/Resources/app
首先我备份了一下原始符咒,然后使用木叶村的祖传图腾asar开始拆解符咒。
wgrhufuvsv@iubridge.com 密码 wgrhufuvsv@iubridge.com,这是我随便注册的账号,登录进去看看数据存放在哪里?
由于木叶村的环境是macOS,所以我就从code ~/Library/Application\ Support/欣芈朵开始搜索。
哈哈,黄天不负二次元,果然被我找到了临时存放的数据点位!
但是这个数据点位居然是加密的数据~!不!我要decrypt它!解除封印!
macOS:
~/Library/Application Support/欣芈朵/Electron v3/vana/state/account.json
Windows:
C:\Users\username\AppData\Roaming\欣芈朵\Electron v3\vana\state\account.json
在我的电脑上是这个地址,在你们电脑上应该是用户名换一下就是了.
在这段内容中,我们只关注rawSubscriptionData, 这显然是一个加密的激活信息,其他的信息都随便写都可以。
在解包的js中搜索:
rawSubscriptionData
我们可以看到这里是一个RSA的数据加解密计算。如果你查看其他的地方,你会发现这个数据关系到app是否激活。
x = (0, o.computed)(() => {
var e;
if (!Q.value) return A.ACTIVATION_STATUS.TRIAL;
{
const { status: t, expireTime: n } =
null !== (e = Q.value) && void 0 !== e ? e : {};
if (t && t === A.SUBSCRIPTION_SERVER_STATUS.EXPIRED)
return A.ACTIVATION_STATUS.EXPIRED;
if (t && t === A.SUBSCRIPTION_SERVER_STATUS.VALID)
return n && i.value && new Date(n) < new Date(i.value)
? A.ACTIVATION_STATUS.EXPIRED
: A.ACTIVATION_STATUS.VALID;
}
return A.ACTIVATION_STATUS.TRIAL;
}),
不难看出,加密的数据解密出来是{ status: t, expireTime: n }这种结构,也就是说status必须要等于A.SUBSCRIPTION_SERVER_STATUS.VALID才行。
6113: (e) => {
"use strict";
e.exports = require("crypto");
};
....
s = n(6113);
....
W = (e) => {
const t = Buffer.from(e, "base64"),
n = s.default.publicDecrypt(
{
key: m,
padding: s.default.constants.RSA_PKCS1_PADDING,
},
t
);
return JSON.parse(n.toString());
};
鼠标点击s可以看到来自n(6113),最终其实是require("crypto")来导出。
结合nodejs中的crypto模块, 我咖喱马西哒~!
0x022 编写模块开始模块重导出hook!
鉴于上一章节对其之分析,我们知道其实是s.default.publicDecrypt进行加密数据解密并得到是否订阅数据。
const crypto = require("crypto");
const originalPublicDecrypt = crypto.publicDecrypt;
Object.defineProperty(crypto, "publicDecrypt", {
get() {
return function myPublicDecrypt(...args) {
let result;
try {
result = originalPublicDecrypt.call(this, ...args);
let data = JSON.parse(result.toString());
result = Buffer.from(JSON.stringify(data));
console.log("秋城落叶Hook 欣芈朵开始", data, { ...args }, result);
} catch (e) {
result = null;
}
return result;
};
},
});
module.exports = crypto;
然后asar pack app目录 asar文件打包回去启动欣芈朵看看输出什么信息:
可以看到解密出来是
{
status: 'Trial',
expireTime: 0,
ss: '',
deviceId: '4050AEDD-2E96-5CDA-9F8F-777D7F25ACD8'
}
随便找了个网站,在线解密结果也是一样的:
基本知道他的套路之后,我们看一下需要伪造的字段:
asar pack app app.asar打包,然后在终端直接启动app看日志输出:
A.ACTIVATION_STATUS {"TRIAL":"trial","VALID":"valid","EXPIRED":"expired"} {"VALID":"sub","EXPIRED":"expired","TRIAL":"trial"}
秋城落叶Hook 欣芈朵开始 {
status: 'Trial',
expireTime: 0,
ss: '',
deviceId: '4050AEDD-2E96-5CDA-9F8F-777D7F25ACD8'
} {
'0': {
key: '-----BEGIN PUBLIC KEY-----\n' +
'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCDYH31l0llicBavbUZRg0y1LnI\n' +
'2JJuPZak0498wGmK0N+ksqCzA0XUfCgQ5E9itYyPuT+z6Pz/+0q6NeApkWcnC/Th\n' +
'WQY6ZlEOMonrhPub8zsWYOZzckQutx3jn6k+6ZXx7yUbbkxIk+wqWgnlQxnx6TMd\n' +
'S3rgo3r4blFTWi6EEQIDAQAB\n' +
'-----END PUBLIC KEY-----',
padding: 1
},
'1': <Buffer 3e 74 b0 c1 4d a0 5f 6a bd fa 0b 67 5a 1c 80 94 1a 0c 22 18 af c2 85 22 7f dd 36 c3 de 23 36 9e 90 71 99 7a 15 b2 08 ec cd 70 8e 52 30 95 13 d2 13 63 ... 78 more bytes>
} <Buffer 7b 22 73 74 61 74 75 73 22 3a 22 54 72 69 61 6c 22 2c 22 65 78 70 69 72 65 54 69 6d 65 22 3a 30 2c 22 73 73 22 3a 22 22 2c 22 64 65 76 69 63 65 49 64 ... 41 more bytes>
所以需要伪造的数据是:
32476309774000表示2999年到期
{"status": "sub", "expireTime": 32476309774000, "ss": "", "deviceId": "ABCDEF-AAAA-AAAA-AAAA-AAAAAA"}
0x023 替换公钥并计算自己的激活序列号
随便生成了一对公私钥,并对{"status": "sub", "expireTime": 32476309774000, "ss": "", "deviceId": "ABCDEF-AAAA-AAAA-AAAA-AAAAAA"}进行加密.
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqIGfghxs/schjid+mHlK
AQhWHm1z1uPX/CWr2TBHPcg3PDmF8vViyhuxpkVe4/X4Tz9hN9BGA+h7toHUw6rK
z2Mk5M5peG5Id4DVLADuVdpcbjo0Ypc0mOdDDTJtlc2T8q10rdGYD0ErpeR9Su9i
aJxDWMOLlNzpmWXpgKQWjRuzoIrOiiHvGzAiSrCMKt6m+/m+Svr5CQHw+/Jx1iAw
yMZIMwux8gsgawVtU1u6MmIB9px4JncFepsg3FdSEbqdYZL3MeExDT7PPh2GQcbS
fcl1gYTrCgJFUZUr2JBOSVIoIvGATH7VIMYBWantbAiQgGqkJstXb8UngEM4hrsX
uQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCogZ+CHGz+xyGO
J36YeUoBCFYebXPW49f8JavZMEc9yDc8OYXy9WLKG7GmRV7j9fhPP2E30EYD6Hu2
gdTDqsrPYyTkzml4bkh3gNUsAO5V2lxuOjRilzSY50MNMm2VzZPyrXSt0ZgPQSul
5H1K72JonENYw4uU3OmZZemApBaNG7Ogis6KIe8bMCJKsIwq3qb7+b5K+vkJAfD7
8nHWIDDIxkgzC7HyCyBrBW1TW7oyYgH2nHgmdwV6myDcV1IRup1hkvcx4TENPs8+
HYZBxtJ9yXWBhOsKAkVRlSvYkE5JUigi8YBMftUgxgFZqe1sCJCAaqQmy1dvxSeA
QziGuxe5AgMBAAECggEBAKeV+yiw0qn1K+cwWlSUVEiAnP24B3xRr+5DHQ1tWX0V
kfGgmBqReAXf0ye1WHFJoQJX231h8zBR2DAkIZHUW840IW4552Vx8TqA9AHGj0Lt
X/30f0MKdLIZVnNakuhow9qYLjHtANkzDJD5lK6hM/MsbkJqgHi12NHKLJfXGeKN
bD5DFIkM39mrrU8AWmxtSEdRindSLcZVnjv7YWaCRdWjkJcD5I1NpgpxNd9j+jum
rgmL4O4RNlNzO1p/cl9CutjH5Wl1cMH/y8U3GsXFaZWZ1K/AGnwl0AT50lWMUX8n
fUH3m5wxq/lhV0h3Vzc8h08kgXKpV57oUVZ9xDusnnECgYEA05hYpP3T8UC1SBnS
KUECy0pDZspaMHPYABhIdpOoR/q3woiK0xeyfWTbhy18yc/mBVUXC+SH6PWk/xVz
k/D8hfpAmU3nuAkvVHWst/NFpbgCN5MoyHCq29UzLJM698nI177zd1f0S5LookUG
OLi26lvPCmEoXaKSa9ZMQe/Lm/0CgYEAy95kiwIV1KJ0Me2K1fmJA3WQpSYL0cBv
5N9OSgJl41SCn1e69UpwwVBQDQmAhxoJCqXXiEkS7RIhcF3BVERoukDpDtdiD6av
tnan4R7djj6xcj+81DTE3POdbdcoCkjH+FrETd7X/2gpeo0kIBqE0fUJcl2D/E1v
oFYL1PebcW0CgYEAg+wL+HI43cVWQOm4WfgqYcyfUUsACA1xsj1xkFxnItlyEFtJ
EmtH4V4scI8vqjNwWgq/H68P/XKJuHALa0Voa6+m7u3fdqJjW+kyEk4eMkATQcsC
NlXocL7v9O6maS7phXmMGfBAY43odKNMSbkAcgVjhDknDZn6aDlnugRjkZECgYA4
NguW4G5QgLJ1CcAcG3+Rupq1TnY30U2I16FoepzJP4X8lV3xQCMyyggocBRGLAGO
NAfnhe53+2XI67DgoTQXFsqr0usw0Y7lSnYjdjU0gUi/7Z8NC7e0DF+953Mc0tCA
Q9aYefcobvnw1nW9fFJe6ac/J1W6/Ubn+JGumM79SQKBgDVgSiOyXgG7V1dERiAT
B/dS8Yc/4RQafnfqtzXKUpo2BJu3PHx1cmOTEBxn+gPOl090dbiM8yOPQR/7uHGQ
kjgD/o7pVy66bk44SHuq297MzXpkOHiLdtpKaYuaKIZzb0bhfovyaTReGb0vfsVo
hFup9gAFhkXo13NrZr5bd29P
-----END PRIVATE KEY-----
得到加密结果:
TsAGB8YCswoPCSFbs/kG580C0GJgm6xgJoLLVK5c2uNm+jgGCOVnEomfKT1dIwPPCp3ApSYUX88qc2Q+PaaWyqphTZcKGB96Ji6+ECwxbpa781EzbyzBMd/d8OceknI97uRE5bnLIj1oGU8EIYV7/5DSrmUmTLM12SPm9CbVyakv3dJhF8e+z0OR+BkplJ4RTv14pcTeZYgTUrhwgIy2KB1XrFfGX46Y2dnf8HuFPGXNQoYcYBQh1D/LnmhkoGz+ASep+fULjUKUNLBM6yKqXKEt4rRgbZA6xlRV7El0hGTJAWWupWP44GPkG4beJM68OMqcW5ecKVV/iTTZK7vKhQ==
从0x022章节我们知道args[0]["key"]是传进来的参数公钥,然后我们前面知道文件是存放在
macOS:
~/Library/Application Support/欣芈朵/Electron v3/vana/state/account.json
Windows:
C:\Users\username\AppData\Roaming\欣芈朵\Electron v3\vana\state\account.json
所以最终整个hook代码是:
const crypto = require("crypto");
const originalPublicDecrypt = crypto.publicDecrypt;
Object.defineProperty(crypto, "publicDecrypt", {
get() {
return function myPublicDecrypt(...args) {
let result;
args[0]["key"] =
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqIGfghxs/schjid+mHlK\nAQhWHm1z1uPX/CWr2TBHPcg3PDmF8vViyhuxpkVe4/X4Tz9hN9BGA+h7toHUw6rK\nz2Mk5M5peG5Id4DVLADuVdpcbjo0Ypc0mOdDDTJtlc2T8q10rdGYD0ErpeR9Su9i\naJxDWMOLlNzpmWXpgKQWjRuzoIrOiiHvGzAiSrCMKt6m+/m+Svr5CQHw+/Jx1iAw\nyMZIMwux8gsgawVtU1u6MmIB9px4JncFepsg3FdSEbqdYZL3MeExDT7PPh2GQcbS\nfcl1gYTrCgJFUZUr2JBOSVIoIvGATH7VIMYBWantbAiQgGqkJstXb8UngEM4hrsX\nuQIDAQAB\n-----END PUBLIC KEY-----";
try {
result = originalPublicDecrypt.call(this, ...args);
let data = JSON.parse(result.toString());
result = Buffer.from(JSON.stringify(data));
console.log("秋城落叶Hook 欣芈朵开始", data, { ...args }, result);
} catch (e) {
result = null;
}
return result;
};
},
});
function fuck_欣芈朵() {
var fs = require("fs");
var path = require("path");
var os = require("os");
license = JSON.stringify({
region: "cn",
user: "QiuChenly",
token: "_fucku欣芈朵",
fireflyToken: "_fucku欣芈朵",
uid: "QiuChenly",
primaryEmail: "@qiuchenlymac",
fullname: "秋城落叶 k'ed",
phone: "FUCK-U",
rawSubscriptionData:
"TsAGB8YCswoPCSFbs/kG580C0GJgm6xgJoLLVK5c2uNm+jgGCOVnEomfKT1dIwPPCp3ApSYUX88qc2Q+PaaWyqphTZcKGB96Ji6+ECwxbpa781EzbyzBMd/d8OceknI97uRE5bnLIj1oGU8EIYV7/5DSrmUmTLM12SPm9CbVyakv3dJhF8e+z0OR+BkplJ4RTv14pcTeZYgTUrhwgIy2KB1XrFfGX46Y2dnf8HuFPGXNQoYcYBQh1D/LnmhkoGz+ASep+fULjUKUNLBM6yKqXKEt4rRgbZA6xlRV7El0hGTJAWWupWP44GPkG4beJM68OMqcW5ecKVV/iTTZK7vKhQ==",
openActivateDialogDate: "2025-02-17T05:40:57.771Z",
});
var platform = os.platform();
var username = os.userInfo().username;
var basePath;
if (platform === "darwin") {
basePath = path.join(
"/Users",
username,
"Library/Application Support/欣芈朵/Electron v3/vana/state"
);
} else if (platform === "win32") {
basePath = path.join(
"C:",
"Users",
username,
"AppData",
"Roaming",
"欣芈朵",
"Electron v3",
"vana",
"state"
);
} else {
console.error("Unsupported platform");
return;
}
var accountFilePath = path.join(basePath, "account.json");
fs.writeFileSync(accountFilePath, license, "utf-8");
}
fuck_欣芈朵();
module.exports = crypto;
这里要注意的是欣芈朵有两个地方都用到了公钥解密,所以我们手动需要替换掉renderer文件夹内的公钥为我们自己的:
这段代码输出结果就是
-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCDYH31l0llicBavbUZRg0y1LnI\n2JJuPZak0498wGmK0N+ksqCzA0XUfCgQ5E9itYyPuT+z6Pz/+0q6NeApkWcnC/Th\nWQY6ZlEOMonrhPub8zsWYOZzckQutx3jn6k+6ZXx7yUbbkxIk+wqWgnlQxnx6TMd\nS3rgo3r4blFTWi6EEQIDAQAB\n-----END PUBLIC KEY-----
也就是说对整个renderer文件夹全局暴力搜索替换
String.fromCharCode(45,45,45,45,45,66,69,71,73,78,32,80,85,66,76,73,67,32,75,69,89,45,45,45,45,45,10,77,73,71,102,77,65,48,71,67,83,113,71,83,73,98,51,68,81,69,66,65,81,85,65,65,52,71,78,65,68,67,66,105,81,75,66,103,81,67,68,89,72,51,49,108,48,108,108,105,99,66,97,118,98,85,90,82,103,48,121,49,76,110,73,10,50,74,74,117,80,90,97,107,48,52,57,56,119,71,109,75,48,78,43,107,115,113,67,122,65,48,88,85,102,67,103,81,53,69,57,105,116,89,121,80,117,84,43,122,54,80,122,47,43,48,113,54,78,101,65,112,107,87,99,110,67,47,84,104,10,87,81,89,54,90,108,69,79,77,111,110,114,104,80,117,98,56,122,115,87,89,79,90,122,99,107,81,117,116,120,51,106,110,54,107,43,54,90,88,120,55,121,85,98,98,107,120,73,107,43,119,113,87,103,110,108,81,120,110,120,54,84,77,100,10,83,51,114,103,111,51,114,52,98,108,70,84,87,105,54,69,69,81,73,68,65,81,65,66,10,45,45,45,45,45,69,78,68,32,80,85,66,76,73,67,32,75,69,89,45,45,45,45,45)
替换为
String.fromCharCode(45,45,45,45,45,66,69,71,73,78,32,80,85,66,76,73,67,32,75,69,89,45,45,45,45,45,10,77,73,73,66,73,106,65,78,66,103,107,113,104,107,105,71,57,119,48,66,65,81,69,70,65,65,79,67,65,81,56,65,77,73,73,66,67,103,75,67,65,81,69,65,113,73,71,102,103,104,120,115,47,115,99,104,106,105,100,43,109,72,108,75,10,65,81,104,87,72,109,49,122,49,117,80,88,47,67,87,114,50,84,66,72,80,99,103,51,80,68,109,70,56,118,86,105,121,104,117,120,112,107,86,101,52,47,88,52,84,122,57,104,78,57,66,71,65,43,104,55,116,111,72,85,119,54,114,75,10,122,50,77,107,53,77,53,112,101,71,53,73,100,52,68,86,76,65,68,117,86,100,112,99,98,106,111,48,89,112,99,48,109,79,100,68,68,84,74,116,108,99,50,84,56,113,49,48,114,100,71,89,68,48,69,114,112,101,82,57,83,117,57,105,10,97,74,120,68,87,77,79,76,108,78,122,112,109,87,88,112,103,75,81,87,106,82,117,122,111,73,114,79,105,105,72,118,71,122,65,105,83,114,67,77,75,116,54,109,43,47,109,43,83,118,114,53,67,81,72,119,43,47,74,120,49,105,65,119,10,121,77,90,73,77,119,117,120,56,103,115,103,97,119,86,116,85,49,117,54,77,109,73,66,57,112,120,52,74,110,99,70,101,112,115,103,51,70,100,83,69,98,113,100,89,90,76,51,77,101,69,120,68,84,55,80,80,104,50,71,81,99,98,83,10,102,99,108,49,103,89,84,114,67,103,74,70,85,90,85,114,50,74,66,79,83,86,73,111,73,118,71,65,84,72,55,86,73,77,89,66,87,97,110,116,98,65,105,81,103,71,113,107,74,115,116,88,98,56,85,110,103,69,77,52,104,114,115,88,10,117,81,73,68,65,81,65,66,10,45,45,45,45,45,69,78,68,32,80,85,66,76,73,67,32,75,69,89,45,45,45,45,45)
即可。
asar pack 重新打包,终端启动欣芈朵,可以看到:
主界面一开始解锁了pro,但是beta版本会去请求ai接口,如果请求失败则会强制清空本地数据。
没想到这诅咒这么强大,我不禁颓然跪倒在欣芈朵面前,马萨卡...就这样要认输吗?
这时, 我突然幻听到欣芈朵的声音,想到我们在一起的美好生活,体内涌出了一股新的力量勉力支撑着我起来(再次强调人设是280斤 所以是勉力支撑),不!我呐喊!我不甘!我命由我不由天!
0x024 拦截es模块定义系统!我就是jsvm的化身!当我就是解释器的时候,你一个js代码该如何应对?
根据日志细节观察,我们不难知道这就是一个请求接口。
结合清除本地账户信息的操作,我们查找一番:
日志报错58717处调用了updateAccount,所以我们需要查看定义:
关键函数大出现!
由于它是在这里进行模块定义:
所以我们直接夺舍解释器:
const originalDefineProperty = Object.defineProperty;
Object.defineProperty = function (obj, prop, descriptor) {
if (Object(obj).hasOwnProperty("updateUserProfile")) {
obj.clearAccount = () => {};
}
return originalDefineProperty(obj, prop, descriptor);
};
当解释器在执行这段代码时,会被我们首先拦截到,然后我们只要检查到在定义这个VueStore定义,就直接进行实现替换。
最后我们成功拦截!
0x025 最中幻想! Windows 版本与最终版!
最后,只需要80行js,通杀Windows/macOS, Linux/iOS/Android 操作一样可自行研究。
function fuck_xmind() {
var license = JSON.stringify({
region: "cn",
user: "QiuChenly",
token: "_fuckuxmind",
fireflyToken: "_fuckuxmind",
uid: "QiuChenly",
primaryEmail: "@qiuchenlymac",
fullname: "秋城落叶破解",
phone: "FUCK-U",
rawSubscriptionData:
"TiT1ul64lE+EMrH0ogOPWHZw5r3sE+jU1l2smjmRuvxmqN3v0NPklgJI9ZpGBt3MZ/mRXM+KmmlZy/bXopy74SH7VLeg3Y1aCATUoWsY2O0XXy1I0JtvLsIF+uM6G2oOx8F6f5Wz+Embhg6b9SIF19MBckmXOOfahd0zWJDaxzpAYthagLgakhbG8k7ynXrUmGIaVmxcktxg3hnRgxlwKvJfM56x5lxF+eLY/t4EFBKfk++omYQExwflUwTrwdeP4kbQvNTMGi9v5Nmyg8Nq7w47sfc1zfeg5opDhW47JTzu29EveGXXAxgV88pjQDZMWjL5c+v4PprDSzF+KJGSfA==",
openActivateDialogDate: "2025-02-17T05:40:57.771Z",
});
var fs = require("fs");
var path = require("path");
var os = require("os");
var userHomeDir = "",
platform = os.platform(),
basePath = "";
if (platform === "win32") {
userHomeDir =
process.env.USERPROFILE || process.env.HOMEPATH || process.env.HOME;
basePath = path.join(
userHomeDir,
"AppData",
"Roaming",
"Xmind",
"Electron v3",
"vana",
"state"
);
} else {
userHomeDir = process.env.HOME;
basePath = path.join(
userHomeDir,
"Library/Application Support/Xmind/Electron v3/vana/state"
);
}
if (!fs.existsSync(basePath)) fs.mkdirSync(basePath, { recursive: true });
var accountFilePath = path.join(basePath, "account.json");
fs.writeFileSync(accountFilePath, license, "utf-8");
}
fuck_xmind();
const originalDefineProperty = Object.defineProperty;
Object.defineProperty = function (obj, prop, descriptor) {
if (Object(obj).hasOwnProperty("clearAccount")) {
obj.clearAccount = () => {
};
}
return originalDefineProperty(obj, prop, descriptor);
};
const crypto = require("crypto");
const originalPublicDecrypt = crypto.publicDecrypt;
Object.defineProperty(crypto, "publicDecrypt", {
get() {
return function myPublicDecrypt(...args) {
args[0]["key"] =
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqIGfghxs/schjid+mHlK\nAQhWHm1z1uPX/CWr2TBHPcg3PDmF8vViyhuxpkVe4/X4Tz9hN9BGA+h7toHUw6rK\nz2Mk5M5peG5Id4DVLADuVdpcbjo0Ypc0mOdDDTJtlc2T8q10rdGYD0ErpeR9Su9i\naJxDWMOLlNzpmWXpgKQWjRuzoIrOiiHvGzAiSrCMKt6m+/m+Svr5CQHw+/Jx1iAw\nyMZIMwux8gsgawVtU1u6MmIB9px4JncFepsg3FdSEbqdYZL3MeExDT7PPh2GQcbS\nfcl1gYTrCgJFUZUr2JBOSVIoIvGATH7VIMYBWantbAiQgGqkJstXb8UngEM4hrsX\nuQIDAQAB\n-----END PUBLIC KEY-----";
let result;
try {
result = originalPublicDecrypt.call(this, ...args);
let data = JSON.parse(result.toString());
result = Buffer.from(JSON.stringify(data));
} catch (e) {
result = null;
}
return result;
};
},
});
module.exports = crypto;
对于windows版本, 只需要安装好asar后同样进行解包,然后复制上方的javascript代码为hook.js,然后在main.js中第一行插入require("./hook");
这句代码,接着替换renderer层暴力搜索替换公钥:
也就是说对整个renderer文件夹全局暴力搜索替换
String.fromCharCode(45,45,45,45,45,66,69,71,73,78,32,80,85,66,76,73,67,32,75,69,89,45,45,45,45,45,10,77,73,71,102,77,65,48,71,67,83,113,71,83,73,98,51,68,81,69,66,65,81,85,65,65,52,71,78,65,68,67,66,105,81,75,66,103,81,67,68,89,72,51,49,108,48,108,108,105,99,66,97,118,98,85,90,82,103,48,121,49,76,110,73,10,50,74,74,117,80,90,97,107,48,52,57,56,119,71,109,75,48,78,43,107,115,113,67,122,65,48,88,85,102,67,103,81,53,69,57,105,116,89,121,80,117,84,43,122,54,80,122,47,43,48,113,54,78,101,65,112,107,87,99,110,67,47,84,104,10,87,81,89,54,90,108,69,79,77,111,110,114,104,80,117,98,56,122,115,87,89,79,90,122,99,107,81,117,116,120,51,106,110,54,107,43,54,90,88,120,55,121,85,98,98,107,120,73,107,43,119,113,87,103,110,108,81,120,110,120,54,84,77,100,10,83,51,114,103,111,51,114,52,98,108,70,84,87,105,54,69,69,81,73,68,65,81,65,66,10,45,45,45,45,45,69,78,68,32,80,85,66,76,73,67,32,75,69,89,45,45,45,45,45)
替换为
String.fromCharCode(45,45,45,45,45,66,69,71,73,78,32,80,85,66,76,73,67,32,75,69,89,45,45,45,45,45,10,77,73,73,66,73,106,65,78,66,103,107,113,104,107,105,71,57,119,48,66,65,81,69,70,65,65,79,67,65,81,56,65,77,73,73,66,67,103,75,67,65,81,69,65,113,73,71,102,103,104,120,115,47,115,99,104,106,105,100,43,109,72,108,75,10,65,81,104,87,72,109,49,122,49,117,80,88,47,67,87,114,50,84,66,72,80,99,103,51,80,68,109,70,56,118,86,105,121,104,117,120,112,107,86,101,52,47,88,52,84,122,57,104,78,57,66,71,65,43,104,55,116,111,72,85,119,54,114,75,10,122,50,77,107,53,77,53,112,101,71,53,73,100,52,68,86,76,65,68,117,86,100,112,99,98,106,111,48,89,112,99,48,109,79,100,68,68,84,74,116,108,99,50,84,56,113,49,48,114,100,71,89,68,48,69,114,112,101,82,57,83,117,57,105,10,97,74,120,68,87,77,79,76,108,78,122,112,109,87,88,112,103,75,81,87,106,82,117,122,111,73,114,79,105,105,72,118,71,122,65,105,83,114,67,77,75,116,54,109,43,47,109,43,83,118,114,53,67,81,72,119,43,47,74,120,49,105,65,119,10,121,77,90,73,77,119,117,120,56,103,115,103,97,119,86,116,85,49,117,54,77,109,73,66,57,112,120,52,74,110,99,70,101,112,115,103,51,70,100,83,69,98,113,100,89,90,76,51,77,101,69,120,68,84,55,80,80,104,50,71,81,99,98,83,10,102,99,108,49,103,89,84,114,67,103,74,70,85,90,85,114,50,74,66,79,83,86,73,111,73,118,71,65,84,72,55,86,73,77,89,66,87,97,110,116,98,65,105,81,103,71,113,107,74,115,116,88,98,56,85,110,103,69,77,52,104,114,115,88,10,117,81,73,68,65,81,65,66,10,45,45,45,45,45,69,78,68,32,80,85,66,76,73,67,32,75,69,89,45,45,45,45,45)
最后打包asar替换原始文件即可激活!
终于,我成功解除了Killer Queen借Crazy even之手在欣芈朵身上施下的符咒, 看着缓缓醒来不知道发生了什么的欣芈朵,我紧紧抱住她,暗暗发誓再也不想让她受到伤害...
但我却没有触碰到欣芈朵, 看着她缓缓消失在空气中,我才惊醒!
0x03 最终章!原来这一切只是我的幻想...?
原来,这一切都是我的幻想...原来这一切都是我的幻想...还好只是幻想...
这时,我突然收到一条未知发信人发过来的信息:"嗯?阿Qiu啊,看来我交代给欣芈朵的任务她完成的很好啊原来欣芈朵平时这么温顺啊还送巧迪克在我这里可是完全不同的模样哦,如果能承受得住的话,就继续播放我发你的视频吧你会看到一个截然不同充满谎言的欣芈朵[笑哭]"
我疯狂了,这真的是我的幻想吗?这个神秘人是谁?欣芈朵去了哪里?我感到了深深的恐惧,仿佛有一个看不见的大阴谋大恐怖笼罩着我...
0x04 参考文献
- b站众多幻想区UP主最新力作
- b站众多幻想区UP主们最新力作评论区
- 模仿二次元真的好累 我不知道我是在什么精神状态下写出来这个东西的。二次元真的🐮🍺
- 打包文件外链下载:
bWFjT1M6Cmh0dHBzOi8vd3d3Lm1lZGlhZmlyZS5jb20vZmlsZS9qa3l6cmptdjNlOTZieXQvWG1pbmRfMjUuMDEuMDEwNjElMjU0MFFpdUNoZW5seVRlYW0uZG1nL2ZpbGUKaHR0cHM6Ly93d3cubWVkaWFmaXJlLmNvbS9maWxlL3U0Y2d0bGpib2VqOWZlei9YbWluZF8yNS4wNC4wMTAxMiUyNTQwUWl1Q2hlbmx5VGVhbS5kbWcvZmlsZQpXaW5kb3dzOgpodHRwczovL3d3dy5tZWRpYWZpcmUuY29tL2ZpbGUvbDN2dTg2ZXZqOWIzeGRpL1htaW5kLWZvci1XaW5kb3dzLXg2NGJpdC0yNS4wMS4wMTA2MS0yMDI1MDEwNzA3NDYucmFyL2ZpbGUKaHR0cHM6Ly93d3cubWVkaWFmaXJlLmNvbS9maWxlLzAzdTR6eGJpMmpjNHNjMy9YbWluZC1mb3ItV2luZG93cy14NjRiaXQtMjUuMDQuMDEwMTItYmV0YS0yMDI1MDEyMTA3NDMucmFyL2ZpbGU=