吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 21284|回复: 101
收起左侧

[原创] Xmind macOS 23.05 2005 & Windows 22.09.3168 优化指南

    [复制链接]
QiuChenly 发表于 2022-10-3 13:15
本帖最后由 QiuChenly 于 2023-5-14 15:57 编辑

简单优化Xmind for macOS (22.09.3173) & For Windows (22.09.3168 )

2023.5.14 版本更新

Xmind 23.05 2005 Mac版本破解方法是asar解包后全局批量一次性暴力替换以下字符串:
c.ACTIVATION_STATUS.TRIAL 替换为 c.ACTIVATION_STATUS.VALID
d.ACTIVATION_STATUS.TRIAL 替换为 d.ACTIVATION_STATUS.VALID

替换完后直接pack成新的asar文件 替换原始asar文件即可激活所有功能。

番外 另一个世界的故事

-============     备注     =============
macOS版本号为22.09.3173,昨天写错了。
WinOS版本号为22.09.3168,今天刚加上。
windows下有加密为什么macOS下没加密?
因为bytecode只能在目标平台机器上编译为同平台的字节码,macOS无法执行windows下生成的bytecode,这显然是极大的局限性。
-================================
注意:由于main.js暂时无法修改,所以zen模式和演说模式无法正常打开使用。Windows 下仅导出无水印可用。
修改main.js主要是修改掉主界面菜单栏的【立即激活】按钮。
只需要狠狠的优化掉common.js即可。
楼主这里是Windows下最新版本22.09.3168.
楼下有人反馈我要Windows版本,还有说已经被加密了,Windows楼主只拿来打游戏,不过既然有人问了那就给带伙们看看。
加密了兄弟们就不要去狠狠地注入了,bytecode是nodejs的编译后字节码,暂时没法修改(修改后校验不一致会拒绝执行),只能尝试利用js的动态语言特性在运行时动态修改main.js中覆盖重要函数去替换内存中的代码,楼主随便测了一下没弄出什么结果,没兴趣弄了,反正能用。
直接报出结果吧,只修改common.js里面的 computeSubscriptionStatus: e => t => s.ACTIVATION_STATUS.VALID 函数就可以优化Windows最新版,缺点就是没有修改main.js导致菜单中会显示一个立即激活按钮。
导出无水印等功能已经正常,修改代码处见下图。反向查找逻辑和macOS下一样,自行查阅第一章内容。
微信截图_20221004120406.png
微信截图_20221004120447.png
微信截图_20221004121400.png
微信截图_20221004121800.png

第一章 前世

众嗦粥汁...
呃,众所周知: 思维导图哪家强,还得去找山东蓝翔深圳市爱思软件技术有限公司旗下的王牌产品----xmind了。
官网App下载地址: Page On Here Download

首先,我先说,我知道你急,但是你先别急,can can word.
支持正版, 此生誓与赌毒不共戴天。
大家要支持正版!!!

第二章 机缘

  1. 安装nodejs,最新版即可。
  2. 安装npm install -g asar, 用于解包xmind的app.asar文件。
  3. 下载上方链接中的正版App,安装。
  4. 找到安装目录,楼主这里是/Applications/Xmind.app/Contents/Resources/app.asar. Windows更好找, 安装目录下既有。
  5. 安装一个文本编辑器,如Sublime/VSCode。
  6. 你需要熟悉两个指令:
    asar extract app.asar文件所在全路径 解包后想放在哪个目录
    asar pack 解包后想放在哪个目录 app.asar文件所在全路径
  7. 记得提前备份好app.asar原始文件,第一次操作难免操作失误。

我优化前的目录是这样的:
16647695437966.jpg
unpacked文件夹不能删除,是依赖文件。
准备工作到此结束。欲知后事如何,且看下回分解。

第三章 初心

首先执行解包指令(打包指令先不急执行):

//解包asar到文件夹里
asar extract /Applications/Xmind.app/Contents/Resources/app.asar /Applications/Xmind.app/Contents/Resources/app.asar.pk
//重新打包文件到asar中
asar pack /Applications/Xmind.app/Contents/Resources/app.asar.pk /Applications/Xmind.app/Contents/Resources/app.asar

然后code /Applications/Xmind.app/Contents/Resources/app.asar.pk用vscode打开这个文件夹。

现在看起来是这样的:
16647697808673.jpg

我们先打开软件看看哪里能找到突破口:
16647698172957.jpg
右上角黄色的试用模式显然是一个不错的goto point.
我们搜索一下:
16647699024624.jpg

可以看到有两个试用模式的字符串。
这个项目使用了国际化,所以需要复制对应字符串的key值去进一步搜索。
我们怎么判断到底哪一个才是界面上显示的那个字符串?
很简单,改一下重新打包就知道了。
我改成这样:
16647700249521.jpg

重新打包,打开软件看看:
16647700590542.jpg

打包没有出现错误,我们打开软件看看:
16647700840279.jpg

确定了,那么我们就开始以这个为入口,反向寻找需要优化的函数。
16647701861620.jpg

搜索一番后发现80行这里有一个函数,看样子是一个按钮。

            activateButtonText() {
              return c.isMasDemo ||
                this.activationStatus === c.ACTIVATION_STATUS.VALID
                ? null
                : (this.subscriptionStatus,
                  c.ACTIVATION_STATUS.EXPIRED,
                  this.$T("Evaluation Mode"));
            }

这段代码认为,当this.activationStatus === c.ACTIVATION_STATUS.VALID时不显示字符串,如果不相等则显示试用模式字样,显然这就是我们看到的黄色按钮上面显示的字符串引用地址了。

备注:
这里是about.js文件中,显然是关于软件界面的那个按钮。主窗口黄色按钮所在位置为:“editor-frame.js”。但是这并不重要。

那么我们有一个疑问:this.activationStatus从哪里来?如果我们想办法把它的值固定为ACTIVATION_STATUS.VALID,是否就能绕过激活呢?
搜索一下:
16647706379066.jpg
很尴尬。找不到引用,他是用了vuex,用了mapGetter获取Store里面的动态值,这样子搜索无法找到最终设置这个值的函数。
这个线索就此断掉。

本来写到这里想直接爆出具体函数的,但是楼主开始急了。
这里是之前备课时做的笔记,可以直接搜这些函数。但是这么直接就出现正确答案省略做题过程只能给结果分,作为一个刚入门的新手,抄答案永远是长不大的。
16647710246785.jpg

退一步越想越气,楼主不服。简单来说,就是楼主迟迟得不到效果,开始急了。楼主确实急了,但没完全急。我们注意到,这个“ACTIVATION_STATUS.VALID”很有束缚的味道。确实,女大三抱金砖,很喜欢束缚风格。
那么我们开始狠狠的暴力搜索:
16647709113916.jpg

在一大串的文件中,common.js中我们找到了getter中的status来源,虽然绕了一个大圈。
他是根据subscriptionStatus这个字段来判断的,而这个字段来自于参数t。
-----===========================================
这里简单科普一下vue里的值为什么会有(e,t)。
前面说过,mapGetter只是一个VuexStore的动态值,那么其实他这里t其实就是this。在Store中t可以调用getters对象中的函数。
这里的this就是图中的getters对象。
不信楼主的话可以上一张官方文档图大家就懂了:
16647717849933.jpg
看不懂没关系,反正不懂的人不只你一个。
-----===========================================
既然我们已经知道t就是这个getters对象,那么就意味着这个对象里有一个叫“subscriptionStatus”的函数,我们找一下:
16647721116794.jpg

成功找到这个函数,但是我们仔细一看,这函数又Call了上方的computeSubscriptionStatus,两个回调函数直接返回一个是否激活的状态。
但是我们别看花了眼,这里2739行又是一个t,这个t可不是this对象了,我们看2749行代码是调用了t.subscriptionData函数,而这个函数我们可以看到是把r.account.rawsubscriptionData解密后传递结果给computeSubscriptionStatus函数的e参数,然后返回结果是一个(t)=>{...}函数。也就是说,我们得出以下结论:
subscriptionStatus这个方法最后返回的是2739行处的(t)=> {...}函数体,最后在上方的status函数中对比这个函数的返回值。有人可能会问:这t.subscriptionStatus(e,t)不是要传一个t参数给这个函数吗?为什么直接可以对比t.subscriptionStatus === s.ACTIVATION_STATUS.VALID?
回头看下vuex的官方文档截图,谢谢。两个参数是自带的。

        computeSubscriptionStatus: (e) => (t) =>
            t && t.status === s.SUBSCRIPTION_SERVER_STATUS.EXPIRED
              ? s.ACTIVATION_STATUS.EXPIRED
              : t && t.status === s.SUBSCRIPTION_SERVER_STATUS.VALID
              ? t.expireTime &&
                e.checkpointTime &&
                new Date(t.expireTime) < new Date(e.checkpointTime)
                ? s.ACTIVATION_STATUS.EXPIRED
                : s.ACTIVATION_STATUS.VALID
              : s.ACTIVATION_STATUS.TRIAL

t.statusl来自于正版用户的加密数据,但是我们没有啊!啥也没有这个值只能返回TRIAL字段了。所以,我们不需要这个值,将这个函数改为(t) => s.SUBSCRIPTION_SERVER_STATUS.VALID即可。

至此,成功找到了需优化函数的位置。
分析到此结束,开始优化。

第四章 优化

开始狠狠的注入正版基因。
首先修改这里:
16647732011709.jpg
这里注入第一段正版基因,除此之外main.js中还有一个正版基因需要狠狠的注入:
16647732592853.jpg
是的,你没看错,通篇长篇大论,最后竟然只需要modify两句代码。
至此,优化完成。
这是未优化前的xmind:
16647732894304.jpg
打包没有出现错误,打开软件看看是否已经狠狠的注入正版基因成功。
16647733113133.jpg
16647733603298.jpg

这里优化完后订阅信息已经能显示了,但是点不开。因为我没有伪造注册信息。能用就行了,谁没事天天打开这个信息看?
16647734140505.jpg
可自由关闭水印

至此,优化结束。

打包app.asar原始版和修改版,仅用于做技术对比!不得用于其他用途!禁止传播!
链接: https://pan.baidu.com/s/1V9gsIODx9YhYcttUBCpf_A?pwd=qcly 提取码: qcly
--来自百度网盘超级会员v6的分享

大结局 疑惑

为什么?为什么翻遍整个论坛没有一个逆向贴?都是发的app.asar,我也不敢乱用,很惶恐。一看版本号都是2021年的了,是和谐了吗?
论坛翻不到也就罢了,Baidu也罢了工,全是2021年的版本。
Baidu本来就不报希望,Google才是王道。
结果Google搜索Xmind for macOS crack显示的都是这样的:
16647690790515.jpg

搜到的xmind是另一个厂商的Xmind Pro,版本号都对不上,傻眼。
作为一个懒狗,想下载一个学习版本就这么难?本来就懒不想动手,纯属无奈。
xmind也不常用,但是每次偶尔用一下导出还有水印,楼主也有点强迫症,关键就在于这个水印没法主动去关闭,必须要激活才能关,这让楼主我很不舒服。
另外,作为正版软件死忠粉,必须要update lasted。不是最新版不用。这个应该不属于强迫症,纯属闲的蛋疼。

仅此记录一下自用Xmind软件的优化方法,希望各位还是要支持正版,学习一下就好。本文仅供爱好者研究学习,文中所述并不代表楼主主观意识,禁止用本文所述方法不当牟利,禁止传播pj,所带来的法律责任由牟利/传播者承担一切责任,本人概不负责。

免费评分

参与人数 24威望 +1 吾爱币 +45 热心值 +21 收起 理由
莫奇 + 1 + 1 我很赞同!
tunis + 1 + 1 我很赞同!
乌巢禅师 + 1 + 1 谢谢@Thanks!
tsoawcn + 1 + 1 谢谢@Thanks!
nnzhs + 1 + 1 谢谢@Thanks!
Kytamin + 1 谢谢@Thanks!
zhouzq709 + 1 + 1 用心讨论,共获提升!
sunnyzls + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
hurricane_tx + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
xcyang + 1 + 1 谢谢@Thanks!
pothunter + 1 + 1 用心讨论,共获提升!
小朋友呢 + 2 + 1 热心回复!
LuckyClover + 1 + 1 谢谢@Thanks!
抱薪风雪雾 + 1 + 1 谢谢@Thanks!
deadlybugs + 1 + 1 用心讨论,共获提升!
爱飞的猫 + 1 + 1 用心讨论,共获提升!
开心熊猫741 + 1 热心回复!
YorkWaugh + 1 + 1 谢谢@Thanks!
lingyun011 + 1 + 1 用心讨论,共获提升!
Patches + 2 + 1 用心讨论,共获提升!
pojiecainiao + 1 + 1 谢谢@Thanks!
lfm333 + 1 + 1 谢谢@Thanks!
lqwer123456 + 1 + 1 我很赞同!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| QiuChenly 发表于 2022-10-15 21:56
根据#34楼道友所述 想到可以本地生成激活序列号
"rawSubscriptionData":"ZsZbGQIBXYN5o9XXh+6qGV9meueJYv6lQzAaqWP1xl7DL8xnP1sBEJia+ws9rW/nax4qVczmG9fy6BOzzR8lX/W8ZhvQVAvwOvIOkvjkbsNK9MP0YrrvEvvSMcJfPxmTa70LzXcSlWturHweqryIK6tJ5VKeqigTj3EN/LJJO5E="
这串数据在本帖中也简单提到是本地解密后来判断是否vip
所以可以利用生成激活码方式绕过激活 缺点是需要屏蔽host ip
过段时间楼主我再简单分析一下试试能不能实现

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
whentai + 1 + 1 win版等你了

查看全部评分

zyjsuper 发表于 2022-10-15 20:19
本帖最后由 zyjsuper 于 2022-10-15 20:58 编辑

注册个账号,登录之后可以在C:\Users\Administrator\AppData\Roaming\Xmind\Electron v3\vana\state\account.json中添加"rawSubscriptionData":"ZsZbGQIBXYN5o9XXh+6qGV9meueJYv6lQzAaqWP1xl7DL8xnP1sBEJia+ws9rW/nax4qVczmG9fy6BOzzR8lX/W8ZhvQVAvwOvIOkvjkbsNK9MP0YrrvEvvSMcJfPxmTa70LzXcSlWturHweqryIK6tJ5VKeqigTj3EN/LJJO5E="
这个也是网上别人分享的,有效期2022-11-25 22:47:37.000
需要屏蔽hosts文件:
[Bash shell] 纯文本查看 复制代码
www.xmind.net
www.xmind.cn
www.xmind.app

添加完成文件变成如下:
[Shell] 纯文本查看 复制代码
{"region":"cn","user":"xxx","token":"xxxxx","uid":"xxxxx","primaryEmail":"xxxxx","fullname":"xxxx","rawSubscriptionData":"ZsZbGQIBXYN5o9XXh+6qGV9meueJYv6lQzAaqWP1xl7DL8xnP1sBEJia+ws9rW/nax4qVczmG9fy6BOzzR8lX/W8ZhvQVAvwOvIOkvjkbsNK9MP0YrrvEvvSMcJfPxmTa70LzXcSlWturHweqryIK6tJ5VKeqigTj3EN/LJJO5E=","openActivateDialogDate":"2022-10-15T11:57:11.507Z"}



写个bat文件,启动xmind.exe的时候修改系统时间,关闭之后恢复。即使过期之后,也可以使用。
bat如下:
[Bash shell] 纯文本查看 复制代码
for /f "delims= " %%d in ('echo %date%') do (set "now=%%d")
date 2022/11/24
start /wait Xmind.exe
date %now%


将bat文件放入和xmind.exe同一路径下,也可以使用Quick Batch File Compiler将bat编译为exe,
我已经编译了一个,可以直接使用。
Startxmind.7z (60.33 KB, 下载次数: 307)


免费评分

参与人数 3吾爱币 +3 热心值 +2 收起 理由
889_ + 1 + 1 我很赞同!
henmy168 + 1 热心回复!
卖梦人 + 1 + 1 谢谢@Thanks!

查看全部评分

夜泉 发表于 2022-10-4 08:56
这软件给我的印象就是:来吧,赶紧把我破解了,然后发出去,大家多多用破解版,这样,人用多了知名度就多了,然后正版羊毛用户就买买买了~~太特么开心了~~



/**
* 自身不先改变的话,一切都不会改变。——《银魂》
*/

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
笔墨纸砚 + 1 + 1 热心回复!

查看全部评分

leonzhou 发表于 2022-10-11 00:40
求大神,xmind windows版 asar 的优化文件有没有?
leonzhou 发表于 2022-10-10 23:33
有没有windows版的啊?
Maple2d 发表于 2022-10-3 23:59
lg560852 发表于 2022-10-3 21:11
windows 22.09.3168的\main\main.js里找不到你说的那段代码
倒是有个main.bytecode,怀疑存在这里,是加密 ...

是的,windows想优化最新版只能参考论坛另一篇帖子,account.json中添加"rawSubscriptionData": "Value"

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
RickSanchez + 1 + 1 我很赞同!

查看全部评分

lg560852 发表于 2022-10-3 21:11
本帖最后由 lg560852 于 2022-10-3 21:56 编辑

windows 22.09.3168的\main\main.js里找不到你说的那段代码
倒是有个main.bytecode,怀疑存在这里,是加密的文件
main.js的内容
const fs = require('fs')
const vm = require('vm')
const v8 = require('v8')
const path = require('path')
const Module = require('module')

v8.setFlagsFromString('--no-lazy')
v8.setFlagsFromString('--no-flush-bytecode')

const COMPILED_EXTNAME = '.bytecode'

const compileCode = function(javascriptCode) {
  if (typeof javascriptCode !== 'string') {
    throw new Error(
      `javascriptCode must be string. $$$${typeof javascriptCode} was given.`
    )
  }

  const script = new vm.Script(javascriptCode, {
    produceCachedData: true
  })

  const bytecodeBuffer =
    script.createCachedData && script.createCachedData.call
      ? script.createCachedData()
      : script.cachedData

  return bytecodeBuffer
}

const fixBytecode = function(bytecodeBuffer) {
  if (!Buffer.isBuffer(bytecodeBuffer)) {
    throw new Error('bytecodeBuffer must be a buffer object.')
  }

  const dummyBytecode = compileCode('"ಠ_ಠ"')

  if (
    process.version.startsWith('v8.8') ||
    process.version.startsWith('v8.9')
  ) {
    dummyBytecode.slice(16, 20).copy(bytecodeBuffer, 16)
    dummyBytecode.slice(20, 24).copy(bytecodeBuffer, 20)
  } else if (
    process.version.startsWith('v12') ||
    process.version.startsWith('v13') ||
    process.version.startsWith('v14') ||
    process.version.startsWith('v15') ||
    process.version.startsWith('v16') ||
    process.version.startsWith('v17') ||
    process.version.startsWith('v18')
  ) {
    dummyBytecode.slice(12, 16).copy(bytecodeBuffer, 12)
  } else {
    dummyBytecode.slice(12, 16).copy(bytecodeBuffer, 12)
    dummyBytecode.slice(16, 20).copy(bytecodeBuffer, 16)
  }
}

const readSourceHash = function(bytecodeBuffer) {
  if (!Buffer.isBuffer(bytecodeBuffer)) {
    throw new Error('bytecodeBuffer must be a buffer object.')
  }

  if (
    process.version.startsWith('v8.8') ||
    process.version.startsWith('v8.9')
  ) {
    return bytecodeBuffer
      .slice(12, 16)
      .reduce((sum, number, power) => (sum += number * Math.pow(256, power)), 0)
  } else {
    return bytecodeBuffer
      .slice(8, 12)
      .reduce((sum, number, power) => (sum += number * Math.pow(256, power)), 0)
  }
}

Module._extensions[COMPILED_EXTNAME] = function(fileModule, filename) {
  const bytecodeBuffer = fs.readFileSync(filename)

  fixBytecode(bytecodeBuffer)

  const length = readSourceHash(bytecodeBuffer)

  let dummyCode = ''

  if (length > 1) {
    dummyCode = '"' + '\u200b'.repeat(length - 2) + '"' // "\u200b" Zero width space
  }

  const script = new vm.Script(dummyCode, {
    filename: filename,
    lineOffset: 0,
    displayErrors: true,
    cachedData: bytecodeBuffer
  })

  if (script.cachedDataRejected) {
    throw new Error('Invalid or incompatible cached data (cachedDataRejected)')
  }

  function require(id) {
    return fileModule.require(id)
  }
  require.resolve = function(request, options) {
    return Module._resolveFilename(request, fileModule, false, options)
  }
  if (process.mainModule) {
    require.main = process.mainModule
  }

  require.extensions = Module._extensions
  require.cache = Module._cache

  const compiledWrapper = script.runInThisContext({
    filename: filename,
    lineOffset: 0,
    columnOffset: 0,
    displayErrors: true
  })

  const dirname = path.dirname(filename)

  const args = [
    fileModule.exports,
    require,
    fileModule,
    filename,
    dirname,
    process,
    global
  ]

  return compiledWrapper.apply(fileModule.exports, args)
}
 
 require('./main.bytecode');
agthe 发表于 2022-10-3 21:23
学习 mark
kutwsswhere 发表于 2022-10-3 21:42
学习一下,我以前也尝试看了看XMind22解的代码只能说我技术也不是很够,刚好来学习学习
lfm333 发表于 2022-10-3 21:45
认真学习了,谢谢楼主辛苦分享
gztf 发表于 2022-10-3 21:58
最新win
22.09.3168
li777 发表于 2022-10-3 22:28
谢谢分享~~
jinxin6670 发表于 2022-10-3 22:42
我windows平台呢…
netpeng 发表于 2022-10-3 23:42
跟着教程操作果然有效。感谢分享。
orca007 发表于 2022-10-3 23:53
太强了,感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-29 07:44

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表