https://blog.csdn.net/m0_62312746/artic … /163153769
成功激活 1.14.15
特别提示:注意自己的安装路径以及该教程中的 PowerShell 都是以管理员身份运行的!!!
一、安装 Typera
1、从官方网站下载对应系统的 Typora,这里主要是 Windows64 位的版本
2.安装 Typora,我的安装位置是 C:\Users\hello\AppData\Local\Programs\Typora,这个可以自己修改
C:\Users\hello\AppData\Local\Programs\Typora\Typora.exe
3、安装完成后先打开软件,找到离线激活,然后把机器码复制出来备用
打开Typora->点击工具栏 中的帮助按钮->我的许可证->输入序列号->离线激活->复制机器码
二、安装 Nodejs 以及创建 pj.js 文件
1、通过 PowerShell 安装 Nodejs 并测试 npm 是否可用
|
1 |
<span class="cbp-l">winget <span class="kw2">install</span> OpenJS.NodeJS.LTS</span><span class="cbp-l">node <span class="re5">-v</span> <span class="sy0">//</span> 查看Nodejs的版本</span> |
2、测试 npm
|
1 |
<span class="cbp-l">npm <span class="re5">-v</span> <span class="sy0">//</span> 查看npm的版本</span> |
若是没有问题就会出现对应的版本:
|
1 |
<span class="cbp-l">C:\Users\Administrator<span class="sy0">></span>npm <span class="re5">-v</span></span><span class="cbp-l">11.16.0</span> |
若是在查看版本的时候出现:
|
1 |
<span class="cbp-l">PS C:\Users\Administrator<span class="sy0">></span> npm <span class="re5">-v</span></span><span class="cbp-l">npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:<span class="sy0">/</span>go.microsof</span><span class="cbp-l">t.com<span class="sy0">/</span>fwlink<span class="sy0">/</span>?<span class="re2">LinkID</span>=<span class="nu0">135170</span> 中的 about_Execution_Policies。</span><span class="cbp-l">所在位置 行:<span class="nu0">1</span> 字符: <span class="nu0">1</span></span><span class="cbp-l">+ npm <span class="re5">-v</span></span><span class="cbp-l">+ ~~~</span><span class="cbp-l"> + CategoryInfo : SecurityError: <span class="br0">(</span>:<span class="br0">)</span> <span class="br0">[</span><span class="br0">]</span>,PSSecurityException</span><span class="cbp-l"> + FullyQualifiedErrorId : UnauthorizedAccess</span> |
是因为执行策略禁止运行 npm.sp1,并非 npm 安装失败!
执行以下的命令解决该问题:
|
1 |
<span class="cbp-l">Set-ExecutionPolicy <span class="re5">-Scope</span> CurrentUser <span class="re5">-ExecutionPolicy</span> RemoteSigned</span> |
然后再次查看版本应该就没有问题了!
3、创建 pj.js 文件
在 C:\Users\hello\AppData\Local\Programs\Typora\resources 这个路径下创建 pj.js 文件,文件内容如下:
|
1 |
<span class="cbp-l"><span class="kw1">const</span> asar <span class="sy0">=</span> require<span class="br0">(</span><span class="st0">"asar"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> chalk <span class="sy0">=</span> require<span class="br0">(</span><span class="st0">"chalk"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> fs <span class="sy0">=</span> require<span class="br0">(</span><span class="st0">"fs"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> path <span class="sy0">=</span> require<span class="br0">(</span><span class="st0">"path"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> <span class="br0">{</span> execSync <span class="br0">}</span> <span class="sy0">=</span> require<span class="br0">(</span><span class="st0">"child_process"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> readlineSync <span class="sy0">=</span> require<span class="br0">(</span><span class="st0">"readline-sync"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> WinReg <span class="sy0">=</span> require<span class="br0">(</span><span class="st0">"winreg"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> <span class="br0">{</span> flipFuses<span class="sy0">,</span> FuseV1Options<span class="sy0">,</span> FuseVersion <span class="br0">}</span> <span class="sy0">=</span> require<span class="br0">(</span><span class="st0">"@electron/fuses"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="kw1">function</span> getInsertCode<span class="br0">(</span>EnableHookDebug<span class="sy0">,</span> atobMachineCode<span class="sy0">,</span> email<span class="sy0">,</span> nowDateStr<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">return</span> `</span><span class="cbp-l"><span class="coMULTI">/** Hook破解开始 */</span></span><span class="cbp-l"><span class="kw1">const</span> electron <span class="sy0">=</span> require<span class="br0">(</span><span class="st0">"electron"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="co1">// 是否启用劫持调试</span></span><span class="cbp-l"><span class="kw1">const</span> HookDebug <span class="sy0">=</span> $<span class="br0">{</span>EnableHookDebug <span class="sy0">?</span> <span class="st0">"true"</span> <span class="sy0">:</span> <span class="st0">"false"</span><span class="br0">}</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="co1">// 调试日志定义</span></span><span class="cbp-l"><span class="kw1">const</span> LOG_PATH <span class="sy0">=</span> <span class="st0">".<span class="es0">\\</span><span class="es0">\\</span>Typora_Hook_Log.txt"</span><span class="sy0">;</span></span><span class="cbp-l"><span class="co1">//fs.rmSync(LOG_PATH, { force: true });</span></span><span class="cbp-l"><span class="kw1">function</span> writeLog<span class="br0">(</span>...<span class="me1">data</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">const</span> log <span class="sy0">=</span> `<span class="br0">[</span>\$<span class="br0">{</span><span class="kw1">new</span> <span class="kw4">Date</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">toLocaleString</span><span class="br0">(</span><span class="br0">)</span><span class="br0">}</span><span class="br0">]</span> <span class="br0">[</span>Log<span class="br0">]</span> \$<span class="br0">{</span>data.<span class="me1">join</span><span class="br0">(</span></span><span class="cbp-l"> <span class="st0">" "</span></span><span class="cbp-l"> <span class="br0">)</span><span class="br0">}</span>\\n<span class="sy0">------------------</span>\\n`<span class="sy0">;</span></span><span class="cbp-l"> fs.<span class="me1">appendFileSync</span><span class="br0">(</span>LOG_PATH<span class="sy0">,</span> log<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="co1">// 开启调试窗口,阻止关闭 app.quit 调用</span></span><span class="cbp-l"><span class="co1">// Hook Electron 模块,监控 BrowserWindow 实例化及阻止 app.quit 调用</span></span><span class="cbp-l"><span class="co1">// Node模块require后会进行缓存,即使再次require会指向同一个对象</span></span><span class="cbp-l"><span class="kw1">if</span> <span class="br0">(</span>HookDebug<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw4">Object</span>.<span class="me1">defineProperty</span><span class="br0">(</span>electron.<span class="me1">app</span><span class="sy0">,</span> <span class="st0">"quit"</span><span class="sy0">,</span> <span class="br0">{</span></span><span class="cbp-l"> value<span class="sy0">:</span> <span class="kw1">function</span> <span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> writeLog<span class="br0">(</span><span class="st0">"[&#128737;&#65039; 拦截] 程序试图调用 app.quit(),已阻止。"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span><span class="sy0">,</span></span><span class="cbp-l"> writable<span class="sy0">:</span> <span class="kw2">true</span><span class="sy0">,</span></span><span class="cbp-l"> configurable<span class="sy0">:</span> <span class="kw2">true</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> electron.<span class="me1">app</span>.<span class="me1">on</span><span class="br0">(</span><span class="st0">"browser-window-created"</span><span class="sy0">,</span> <span class="br0">(</span>_event<span class="sy0">,</span> win<span class="br0">)</span> <span class="sy0">=></span> <span class="br0">{</span></span><span class="cbp-l"> writeLog<span class="br0">(</span><span class="st0">"【&#128064; 监控】检测到 BrowserWindow 实例化!"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="co1">// 确保dom-ready后再打开DevTools 否则第一个窗口可能会无法打开</span></span><span class="cbp-l"> win.<span class="me1">webContents</span>.<span class="me1">once</span><span class="br0">(</span><span class="st0">"dom-ready"</span><span class="sy0">,</span> <span class="br0">(</span><span class="br0">)</span> <span class="sy0">=></span> <span class="br0">{</span></span><span class="cbp-l"> writeLog<span class="br0">(</span><span class="st0">"【&#128295;】打开 DevTools..."</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> win.<span class="me1">webContents</span>.<span class="me1">openDevTools</span><span class="br0">(</span><span class="br0">{</span> mode<span class="sy0">:</span> <span class="st0">"detach"</span> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="co1">// Hook fs 模块,重定向对 resources/app 目录的访问</span></span><span class="cbp-l"><span class="co1">// resources/app/ → resources/app.bak/</span></span><span class="cbp-l"><span class="kw1">const</span> fsPathFrom <span class="sy0">=</span> <span class="sy0">/</span>resources<span class="br0">[</span>\\\\<span class="sy0">/</span><span class="br0">]</span>app<span class="br0">[</span>\\\\<span class="sy0">/</span><span class="br0">]</span><span class="sy0">/</span>i<span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> fsPathTo <span class="sy0">=</span> <span class="st0">"resources<span class="es0">\\</span><span class="es0">\\</span>app.bak<span class="es0">\\</span><span class="es0">\\</span>"</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> fsHook <span class="sy0">=</span> <span class="br0">{</span><span class="br0">}</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">[</span></span><span class="cbp-l"> <span class="st0">"readFileSync"</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="st0">"readFile"</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="st0">"statSync"</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="st0">"stat"</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="st0">"Stats"</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="st0">"StatsFs"</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="st0">"open"</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="st0">"openSync"</span><span class="sy0">,</span></span><span class="cbp-l"><span class="br0">]</span>.<span class="me1">forEach</span><span class="br0">(</span><span class="br0">(</span>property<span class="br0">)</span> <span class="sy0">=></span> <span class="br0">{</span></span><span class="cbp-l"> fsHook<span class="br0">[</span>property<span class="br0">]</span> <span class="sy0">=</span> fs<span class="br0">[</span>property<span class="br0">]</span><span class="sy0">;</span></span><span class="cbp-l"> fs<span class="br0">[</span>property<span class="br0">]</span> <span class="sy0">=</span> <span class="kw1">function</span> <span class="br0">(</span>filePath<span class="sy0">,</span> ...<span class="me1">args</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span><span class="kw1">typeof</span> filePath <span class="sy0">==</span> <span class="st0">"string"</span> <span class="sy0">&&</span> fsPathFrom.<span class="me1">test</span><span class="br0">(</span>filePath<span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">const</span> redirectPath <span class="sy0">=</span> filePath.<span class="me1">replace</span><span class="br0">(</span>fsPathFrom<span class="sy0">,</span> fsPathTo<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> writeLog<span class="br0">(</span></span><span class="cbp-l"> `<span class="br0">[</span><span class="sy0">&</span>#<span class="nu0">128737</span><span class="sy0">;&</span>#<span class="nu0">65039</span><span class="sy0">;</span> fsHook<span class="br0">]</span> 程序试图 fs.\$<span class="br0">{</span>property<span class="br0">}</span> 重定向 \$<span class="br0">{</span>filePath<span class="br0">}</span> <span class="sy0">--></span> \$<span class="br0">{</span>redirectPath<span class="br0">}</span>`</span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">return</span> fsHook<span class="br0">[</span>property<span class="br0">]</span>.<span class="me1">call</span><span class="br0">(</span><span class="kw1">this</span><span class="sy0">,</span> redirectPath<span class="sy0">,</span> ...<span class="me1">args</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"> writeLog<span class="br0">(</span>`<span class="br0">[</span><span class="sy0">&</span>#<span class="nu0">128737</span><span class="sy0">;&</span>#<span class="nu0">65039</span><span class="sy0">;</span> fsHook<span class="br0">]</span> 程序试图 fs.\$<span class="br0">{</span>property<span class="br0">}</span> \$<span class="br0">{</span>filePath<span class="br0">}</span>`<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">return</span> fsHook<span class="br0">[</span>property<span class="br0">]</span>.<span class="me1">call</span><span class="br0">(</span><span class="kw1">this</span><span class="sy0">,</span> filePath<span class="sy0">,</span> ...<span class="me1">args</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> fsPromisesHook <span class="sy0">=</span> <span class="br0">{</span><span class="br0">}</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">[</span><span class="st0">"readFile"</span><span class="sy0">,</span> <span class="st0">"open"</span><span class="sy0">,</span> <span class="st0">"stat"</span><span class="br0">]</span>.<span class="me1">forEach</span><span class="br0">(</span><span class="br0">(</span>property<span class="br0">)</span> <span class="sy0">=></span> <span class="br0">{</span></span><span class="cbp-l"> fsPromisesHook<span class="br0">[</span>property<span class="br0">]</span> <span class="sy0">=</span> fs.<span class="me1">promises</span><span class="br0">[</span>property<span class="br0">]</span><span class="sy0">;</span></span><span class="cbp-l"> fs.<span class="me1">promises</span><span class="br0">[</span>property<span class="br0">]</span> <span class="sy0">=</span> async <span class="kw1">function</span> <span class="br0">(</span>filePath<span class="sy0">,</span> ...<span class="me1">args</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span><span class="kw1">typeof</span> filePath <span class="sy0">==</span> <span class="st0">"string"</span> <span class="sy0">&&</span> fsPathFrom.<span class="me1">test</span><span class="br0">(</span>filePath<span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">const</span> redirectPath <span class="sy0">=</span> filePath.<span class="me1">replace</span><span class="br0">(</span>fsPathFrom<span class="sy0">,</span> fsPathTo<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> writeLog<span class="br0">(</span></span><span class="cbp-l"> `<span class="br0">[</span><span class="sy0">&</span>#<span class="nu0">128737</span><span class="sy0">;&</span>#<span class="nu0">65039</span><span class="sy0">;</span> fsHook<span class="sy0">/</span>Promises<span class="br0">]</span> 程序试图 fs.<span class="me1">promises</span>.\$<span class="br0">{</span>property<span class="br0">}</span> 重定向 \$<span class="br0">{</span>filePath<span class="br0">}</span> <span class="sy0">--></span> \$<span class="br0">{</span>redirectPath<span class="br0">}</span>`</span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">return</span> fsPromisesHook<span class="br0">[</span>property<span class="br0">]</span>.<span class="me1">call</span><span class="br0">(</span><span class="kw1">this</span><span class="sy0">,</span> redirectPath<span class="sy0">,</span> ...<span class="me1">args</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"> writeLog<span class="br0">(</span></span><span class="cbp-l"> `<span class="br0">[</span><span class="sy0">&</span>#<span class="nu0">128737</span><span class="sy0">;&</span>#<span class="nu0">65039</span><span class="sy0">;</span> fsHook<span class="sy0">/</span>Promises<span class="br0">]</span> 程序试图 fs.<span class="me1">promises</span>.\$<span class="br0">{</span>property<span class="br0">}</span> \$<span class="br0">{</span>filePath<span class="br0">}</span>`</span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">return</span> fsPromisesHook<span class="br0">[</span>property<span class="br0">]</span>.<span class="me1">call</span><span class="br0">(</span><span class="kw1">this</span><span class="sy0">,</span> filePath<span class="sy0">,</span> ...<span class="me1">args</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="co1">// IPC 通信进行监控</span></span><span class="cbp-l"><span class="kw1">if</span> <span class="br0">(</span>HookDebug<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">const</span> invokeFilter <span class="sy0">=</span> <span class="br0">[</span><span class="st0">"document.addSnapAndLastSync"</span><span class="sy0">,</span> <span class="st0">"document.setContent"</span><span class="br0">]</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">const</span> originalIpcMainHandle <span class="sy0">=</span> electron.<span class="me1">ipcMain</span>.<span class="me1">handle</span><span class="sy0">;</span></span><span class="cbp-l"> electron.<span class="me1">ipcMain</span>.<span class="me1">handle</span> <span class="sy0">=</span> <span class="kw1">function</span> <span class="br0">(</span>channel<span class="sy0">,</span> listener<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="co1">// writeLog(`[IPC 注册] .handle 监听频道: "\${channel}"`);</span></span><span class="cbp-l"> <span class="kw1">const</span> filter <span class="sy0">=</span> <span class="sy0">!</span>invokeFilter.<span class="me1">includes</span><span class="br0">(</span>channel<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">return</span> originalIpcMainHandle.<span class="me1">call</span><span class="br0">(</span><span class="kw1">this</span><span class="sy0">,</span> channel<span class="sy0">,</span> async <span class="br0">(</span>event<span class="sy0">,</span> ...<span class="me1">args</span><span class="br0">)</span> <span class="sy0">=></span> <span class="br0">{</span></span><span class="cbp-l"> filter <span class="sy0">&&</span></span><span class="cbp-l"> writeLog<span class="br0">(</span></span><span class="cbp-l"> `<span class="br0">[</span><span class="sy0">&</span>#<span class="nu0">128064</span><span class="sy0">;</span>IPC 请求<span class="br0">]</span> 收到 .<span class="me1">invoke</span><span class="br0">(</span><span class="st0">"<span class="es0">\$</span>{channel}"</span><span class="br0">)</span> 参数<span class="sy0">:</span>`<span class="sy0">,</span></span><span class="cbp-l"> JSON.<span class="me1">stringify</span><span class="br0">(</span>args<span class="br0">)</span></span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">try</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">const</span> result <span class="sy0">=</span> await listener<span class="br0">(</span>event<span class="sy0">,</span> ...<span class="me1">args</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> filter <span class="sy0">&&</span></span><span class="cbp-l"> writeLog<span class="br0">(</span></span><span class="cbp-l"> `<span class="br0">[</span><span class="sy0">&</span>#<span class="nu0">128064</span><span class="sy0">;</span>IPC 响应<span class="br0">]</span> .<span class="me1">handle</span><span class="br0">(</span><span class="st0">"<span class="es0">\$</span>{channel}"</span><span class="br0">)</span> 返回结果<span class="sy0">:</span>`<span class="sy0">,</span></span><span class="cbp-l"> JSON.<span class="me1">stringify</span><span class="br0">(</span>result<span class="br0">)</span></span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">return</span> result<span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span> <span class="kw1">catch</span> <span class="br0">(</span>error<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> filter <span class="sy0">&&</span> writeLog<span class="br0">(</span>`<span class="br0">[</span><span class="sy0">&</span>#<span class="nu0">128064</span><span class="sy0">;</span>IPC 错误<span class="br0">]</span> .<span class="me1">handle</span><span class="br0">(</span><span class="st0">"<span class="es0">\$</span>{channel}"</span><span class="br0">)</span> 执行出错<span class="sy0">:</span>`<span class="sy0">,</span> error<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">throw</span> error<span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"></span><span class="cbp-l"><span class="kw1">const</span> crypto <span class="sy0">=</span> require<span class="br0">(</span><span class="st0">"crypto"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="kw1">const</span> originalPublicDecrypt <span class="sy0">=</span> crypto.<span class="me1">publicDecrypt</span><span class="sy0">;</span></span><span class="cbp-l">crypto.<span class="me1">publicDecrypt</span> <span class="sy0">=</span> <span class="kw1">function</span> <span class="br0">(</span>key<span class="sy0">,</span> buffer<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span>HookDebug<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> writeLog<span class="br0">(</span><span class="st0">"-------------------------------------------"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> writeLog<span class="br0">(</span><span class="st0">"【&#128064; 监控】 crypto.publicDecrypt 被调用"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> writeLog<span class="br0">(</span><span class="st0">"Key:"</span><span class="sy0">,</span> key<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> writeLog<span class="br0">(</span><span class="st0">"Buffer (Hex):"</span><span class="sy0">,</span> buffer.<span class="me1">toString</span><span class="br0">(</span><span class="st0">"hex"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"> <span class="co1">// return originalPublicDecrypt.call(this, key, buffer);</span></span><span class="cbp-l"> <span class="co1">// 直接返回伪造的明文 Buffer</span></span><span class="cbp-l"> <span class="kw1">return</span> Buffer.<span class="me1">from</span><span class="br0">(</span></span><span class="cbp-l"> JSON.<span class="me1">stringify</span><span class="br0">(</span><span class="br0">{</span></span><span class="cbp-l"> deviceId<span class="sy0">:</span> <span class="st0">"${atobMachineCode.l}"</span><span class="sy0">,</span></span><span class="cbp-l"> fingerprint<span class="sy0">:</span> <span class="st0">"${atobMachineCode.i}"</span><span class="sy0">,</span></span><span class="cbp-l"> email<span class="sy0">:</span> <span class="st0">"${email}"</span><span class="sy0">,</span></span><span class="cbp-l"> license<span class="sy0">:</span> <span class="st0">"Cracked_By_DreamNya"</span><span class="sy0">,</span></span><span class="cbp-l"> version<span class="sy0">:</span> <span class="st0">"${atobMachineCode.v}"</span><span class="sy0">,</span></span><span class="cbp-l"> date<span class="sy0">:</span> <span class="st0">"${nowDateStr}"</span><span class="sy0">,</span></span><span class="cbp-l"> type<span class="sy0">:</span> <span class="st0">"DreamNya"</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="br0">}</span><span class="br0">)</span></span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="co1">// 劫持联网验证</span></span><span class="cbp-l">electron.<span class="me1">app</span>.<span class="me1">whenReady</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">then</span><span class="br0">(</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">=></span> <span class="br0">{</span></span><span class="cbp-l"> electron.<span class="me1">protocol</span>.<span class="me1">handle</span><span class="br0">(</span><span class="st0">"https"</span><span class="sy0">,</span> async <span class="br0">(</span>request<span class="br0">)</span> <span class="sy0">=></span> <span class="br0">{</span></span><span class="cbp-l"> writeLog<span class="br0">(</span>`<span class="br0">[</span><span class="sy0">&</span>#<span class="nu0">128064</span><span class="sy0">;</span>electron.<span class="me1">net</span> Request<span class="br0">]</span> \$<span class="br0">{</span>request.<span class="me1">method</span><span class="br0">}</span> \$<span class="br0">{</span>request.<span class="me1">url</span><span class="br0">}</span>`<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> writeLog<span class="br0">(</span><span class="st0">"request.url typeof:"</span><span class="sy0">,</span> <span class="kw1">typeof</span> request.<span class="me1">url</span><span class="sy0">,</span> <span class="st0">"value:"</span><span class="sy0">,</span> request.<span class="me1">url</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="co1">// 拦截目标请求,伪造响应</span></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span>request.<span class="me1">url</span> <span class="sy0">===</span> <span class="st0">"https://store.typora.io/api/client/renew"</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span>HookDebug<span class="br0">)</span><span class="br0">{</span></span><span class="cbp-l"> writeLog<span class="br0">(</span>`<span class="br0">[</span><span class="sy0">&</span>#<span class="nu0">128737</span><span class="sy0">;&</span>#<span class="nu0">65039</span><span class="sy0">;</span> 拦截<span class="br0">]</span> 伪造激活验证响应<span class="sy0">:</span> <span class="br0">{</span>success<span class="sy0">:</span><span class="kw2">true</span><span class="sy0">,</span> msg<span class="sy0">:</span> \$<span class="br0">{</span>btoa<span class="br0">(</span><span class="st0">"DreamNya"</span><span class="br0">)</span><span class="br0">}</span><span class="br0">}</span>`<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"> <span class="kw1">return</span> <span class="kw1">new</span> Response<span class="br0">(</span></span><span class="cbp-l"> JSON.<span class="me1">stringify</span><span class="br0">(</span><span class="br0">{</span> success<span class="sy0">:</span> <span class="kw2">true</span><span class="sy0">,</span> msg<span class="sy0">:</span> btoa<span class="br0">(</span><span class="st0">"DreamNya"</span><span class="br0">)</span> <span class="br0">}</span><span class="br0">)</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="br0">{</span></span><span class="cbp-l"> status<span class="sy0">:</span> <span class="nu0">200</span><span class="sy0">,</span></span><span class="cbp-l"> headers<span class="sy0">:</span> <span class="br0">{</span> <span class="st0">"content-type"</span><span class="sy0">:</span> <span class="st0">"application/json"</span> <span class="br0">}</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span>HookDebug<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="co1">// 尝试打印 Request Body</span></span><span class="cbp-l"> <span class="kw1">try</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">const</span> reqClone <span class="sy0">=</span> request.<span class="me1">clone</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">const</span> reqBody <span class="sy0">=</span> await reqClone.<span class="me1">text</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span>reqBody<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> writeLog<span class="br0">(</span><span class="st0">'[electron.net Request Body]:'</span><span class="sy0">,</span> reqBody<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"> <span class="br0">}</span> <span class="kw1">catch</span> <span class="br0">{</span> <span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="co1">// 其他请求正常转发</span></span><span class="cbp-l"> <span class="kw1">const</span> response <span class="sy0">=</span> await electron.<span class="me1">net</span>.<span class="me1">fetch</span><span class="br0">(</span>request<span class="sy0">,</span> <span class="br0">{</span> bypassCustomProtocolHandlers<span class="sy0">:</span> <span class="kw2">true</span> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="co1">// 克隆响应用于日志</span></span><span class="cbp-l"> <span class="kw1">const</span> resClone <span class="sy0">=</span> response.<span class="me1">clone</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> resClone</span><span class="cbp-l"> .<span class="me1">text</span><span class="br0">(</span><span class="br0">)</span></span><span class="cbp-l"> .<span class="me1">then</span><span class="br0">(</span><span class="br0">(</span>resText<span class="br0">)</span> <span class="sy0">=></span> <span class="br0">{</span></span><span class="cbp-l"> writeLog<span class="br0">(</span>`<span class="br0">[</span><span class="sy0">&</span>#<span class="nu0">128064</span><span class="sy0">;</span>electron.<span class="me1">net</span> Response<span class="br0">]</span> \$<span class="br0">{</span>response.<span class="me1">status</span><span class="br0">}</span> \$<span class="br0">{</span>request.<span class="me1">url</span><span class="br0">}</span>`<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> writeLog<span class="br0">(</span><span class="st0">'[electron.net Response Body]:'</span><span class="sy0">,</span> resText.<span class="me1">substring</span><span class="br0">(</span><span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">500</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span><span class="br0">)</span></span><span class="cbp-l"> .<span class="kw1">catch</span><span class="br0">(</span><span class="br0">(</span>err<span class="br0">)</span> <span class="sy0">=></span> <span class="br0">{</span></span><span class="cbp-l"> console.<span class="me1">error</span><span class="br0">(</span><span class="st0">'[electron.net Response Error]:'</span><span class="sy0">,</span> err<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="kw1">return</span> response<span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"></span><span class="cbp-l"> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="coMULTI">/** Hook破解结束 */</span></span><span class="cbp-l">`<span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l">let EnableBackup <span class="sy0">=</span> <span class="kw2">false</span><span class="sy0">;</span> <span class="co1">// 是否备份原始文件</span></span><span class="cbp-l">let EnableHookDebug <span class="sy0">=</span> <span class="kw2">false</span><span class="sy0">;</span> <span class="co1">// 是否启用调试日志</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="kw1">const</span> Typora_Installation_Path <span class="sy0">=</span> <span class="st0">"C:<span class="es0">\\</span>Users<span class="es0">\\</span>hello<span class="es0">\\</span>AppData<span class="es0">\\</span>Local<span class="es0">\\</span>Programs<span class="es0">\\</span>Typora<span class="es0">\\</span>"</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> resourcesPath <span class="sy0">=</span> path.<span class="me1">join</span><span class="br0">(</span>Typora_Installation_Path<span class="sy0">,</span> <span class="st0">"resources"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> asarPath <span class="sy0">=</span> path.<span class="me1">join</span><span class="br0">(</span>resourcesPath<span class="sy0">,</span> <span class="st0">"app.asar"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> appDir <span class="sy0">=</span> path.<span class="me1">join</span><span class="br0">(</span>resourcesPath<span class="sy0">,</span> <span class="st0">"app"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> appBakDir <span class="sy0">=</span> path.<span class="me1">join</span><span class="br0">(</span>resourcesPath<span class="sy0">,</span> <span class="st0">"app.bak"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> asarBakPath <span class="sy0">=</span> path.<span class="me1">join</span><span class="br0">(</span>resourcesPath<span class="sy0">,</span> <span class="st0">"app.asar.bak"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> TyporaEXE <span class="sy0">=</span> path.<span class="me1">join</span><span class="br0">(</span>Typora_Installation_Path<span class="sy0">,</span> <span class="st0">"Typora.exe"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> LaunchDistJS <span class="sy0">=</span> path.<span class="me1">join</span><span class="br0">(</span>appDir<span class="sy0">,</span> <span class="st0">"launch.dist.js"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="co1">// 随机生成一个符合前端验证格式的注册码</span></span><span class="cbp-l"><span class="kw1">function</span> generateRegCode<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">const</span> chars <span class="sy0">=</span> <span class="st0">'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'</span><span class="sy0">;</span></span><span class="cbp-l"> let code <span class="sy0">=</span> <span class="st0">'+'</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">for</span> <span class="br0">(</span>let i <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> i <span class="sy0"><</span> <span class="nu0">8</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> code <span class="sy0">+=</span> chars.<span class="me1">charAt</span><span class="br0">(</span><span class="kw4">Math</span>.<span class="me1">floor</span><span class="br0">(</span><span class="kw4">Math</span>.<span class="me1">random</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">*</span> chars.<span class="me1">length</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"> code <span class="sy0">+=</span> <span class="st0">'#'</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">return</span> code<span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="kw1">function</span> closeTyporaProcesses<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">try</span> <span class="br0">{</span></span><span class="cbp-l"> execSync<span class="br0">(</span><span class="st0">"taskkill /F /IM Typora.exe"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">green</span><span class="br0">(</span><span class="st0">"已关闭所有 Typora.exe 进程"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span> <span class="kw1">catch</span> <span class="br0">(</span>e<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">red</span><span class="br0">(</span><span class="st0">"Typora.exe 未运行或关闭失败,请手动关闭后继续。"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span></span><span class="cbp-l"> chalk.<span class="me1">yellow</span><span class="br0">(</span></span><span class="cbp-l"> <span class="st0">"已尝试自动关闭所有 Typora.exe 进程,如果未关闭请手动关闭后再运行此程序。"</span></span><span class="cbp-l"> <span class="br0">)</span></span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="co1">// 回车继续</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">cyan</span><span class="br0">(</span><span class="st0">"请按回车键继续..."</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> readlineSync.<span class="me1">question</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="kw1">function</span> setRegValue<span class="br0">(</span>regKey<span class="sy0">,</span> name<span class="sy0">,</span> value<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">return</span> <span class="kw1">new</span> Promise<span class="br0">(</span><span class="br0">(</span>resolve<span class="sy0">,</span> reject<span class="br0">)</span> <span class="sy0">=></span> <span class="br0">{</span></span><span class="cbp-l"> regKey.<span class="kw1">set</span><span class="br0">(</span>name<span class="sy0">,</span> WinReg.<span class="me1">REG_SZ</span><span class="sy0">,</span> value<span class="sy0">,</span> <span class="kw1">function</span> <span class="br0">(</span>err<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span>err<span class="br0">)</span> reject<span class="br0">(</span>err<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">else</span> resolve<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="kw1">function</span> getNowDateStr<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">const</span> now <span class="sy0">=</span> <span class="kw1">new</span> <span class="kw4">Date</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">const</span> dd <span class="sy0">=</span> <span class="kw4">String</span><span class="br0">(</span>now.<span class="me1">getDate</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span>.<span class="me1">padStart</span><span class="br0">(</span><span class="nu0">2</span><span class="sy0">,</span> <span class="st0">"0"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">const</span> mm <span class="sy0">=</span> <span class="kw4">String</span><span class="br0">(</span>now.<span class="me1">getMonth</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">+</span> <span class="nu0">1</span><span class="br0">)</span>.<span class="me1">padStart</span><span class="br0">(</span><span class="nu0">2</span><span class="sy0">,</span> <span class="st0">"0"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">const</span> yyyy <span class="sy0">=</span> now.<span class="me1">getFullYear</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">return</span> `$<span class="br0">{</span>mm<span class="br0">}</span><span class="sy0">/</span>$<span class="br0">{</span>dd<span class="br0">}</span><span class="sy0">/</span>$<span class="br0">{</span>yyyy<span class="br0">}</span>`<span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span></span><span class="cbp-l"><span class="kw1">const</span> nowDateStr <span class="sy0">=</span> getNowDateStr<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="co1">// 要求输入机器码和邮箱</span></span><span class="cbp-l">console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">cyan</span><span class="br0">(</span><span class="st0">"请输入机器码: "</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> machineCode <span class="sy0">=</span> readlineSync.<span class="me1">question</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l">console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">cyan</span><span class="br0">(</span><span class="st0">"请输入邮箱: "</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> email <span class="sy0">=</span> readlineSync.<span class="me1">question</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="co1">// 询问是否开启备份(默认开启)与调试(默认关闭)</span></span><span class="cbp-l">console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">cyan</span><span class="br0">(</span><span class="st0">"请选择是否开启备份与调试选项:"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l">console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">cyan</span><span class="br0">(</span><span class="st0">"【建议开启】是否开启备份?(Y/N): "</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> backupAnswer <span class="sy0">=</span> readlineSync.<span class="me1">question</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l">console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">cyan</span><span class="br0">(</span><span class="st0">"【建议关闭】是否开启调试?(Y/N): "</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="kw1">const</span> debugAnswer <span class="sy0">=</span> readlineSync.<span class="me1">question</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l">EnableBackup <span class="sy0">=</span> backupAnswer.<span class="me1">toLowerCase</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">===</span> <span class="st0">"y"</span><span class="sy0">;</span></span><span class="cbp-l">EnableHookDebug <span class="sy0">=</span> debugAnswer.<span class="me1">toLowerCase</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">===</span> <span class="st0">"y"</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="co1">// Base64 解码</span></span><span class="cbp-l"><span class="kw1">function</span> atob<span class="br0">(</span>str<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">return</span> Buffer.<span class="me1">from</span><span class="br0">(</span>str<span class="sy0">,</span> <span class="st0">"base64"</span><span class="br0">)</span>.<span class="me1">toString</span><span class="br0">(</span><span class="st0">"utf-8"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span></span><span class="cbp-l"><span class="kw1">const</span> atobMachineCode <span class="sy0">=</span> JSON.<span class="me1">parse</span><span class="br0">(</span>atob<span class="br0">(</span>machineCode<span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l">console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">yellow</span><span class="br0">(</span><span class="st0">"deviceId: "</span> <span class="sy0">+</span> atobMachineCode.<span class="me1">l</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l">console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">yellow</span><span class="br0">(</span><span class="st0">"fingerprint: "</span> <span class="sy0">+</span> atobMachineCode.<span class="me1">i</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l">console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">yellow</span><span class="br0">(</span><span class="st0">"version: "</span> <span class="sy0">+</span> atobMachineCode.<span class="me1">v</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"><span class="co1">// 关闭所有 Typora.exe 进程</span></span><span class="cbp-l">closeTyporaProcesses<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l">console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">green</span><span class="br0">(</span><span class="st0">"==== 开始破解... ===="</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l">async <span class="kw1">function</span> main<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="co1">// 一、反反调试</span></span><span class="cbp-l"></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">yellow</span><span class="br0">(</span><span class="st0">"一、正在进行反反调试操作..."</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">yellow</span><span class="br0">(</span><span class="st0">"解包 asar"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> await asar.<span class="me1">extractAll</span><span class="br0">(</span>asarPath<span class="sy0">,</span> appDir<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span></span><span class="cbp-l"> chalk.<span class="me1">yellow</span><span class="br0">(</span><span class="st0">"复制 app 到 app.bak(递归复制)【应对完整性校验】"</span><span class="br0">)</span></span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="co1">// 2. 复制 app 到 app.bak(递归复制)</span></span><span class="cbp-l"> <span class="kw1">function</span> copyDir<span class="br0">(</span>src<span class="sy0">,</span> dest<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span><span class="sy0">!</span>fs.<span class="me1">existsSync</span><span class="br0">(</span>dest<span class="br0">)</span><span class="br0">)</span> fs.<span class="me1">mkdirSync</span><span class="br0">(</span>dest<span class="sy0">,</span> <span class="br0">{</span> recursive<span class="sy0">:</span> <span class="kw2">true</span> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">for</span> <span class="br0">(</span><span class="kw1">const</span> entry of fs.<span class="me1">readdirSync</span><span class="br0">(</span>src<span class="sy0">,</span> <span class="br0">{</span> withFileTypes<span class="sy0">:</span> <span class="kw2">true</span> <span class="br0">}</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">const</span> srcPath <span class="sy0">=</span> path.<span class="me1">join</span><span class="br0">(</span>src<span class="sy0">,</span> entry.<span class="me1">name</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">const</span> destPath <span class="sy0">=</span> path.<span class="me1">join</span><span class="br0">(</span>dest<span class="sy0">,</span> entry.<span class="me1">name</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span>entry.<span class="me1">isDirectory</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> copyDir<span class="br0">(</span>srcPath<span class="sy0">,</span> destPath<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span></span><span class="cbp-l"> fs.<span class="me1">copyFileSync</span><span class="br0">(</span>srcPath<span class="sy0">,</span> destPath<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"> copyDir<span class="br0">(</span>appDir<span class="sy0">,</span> appBakDir<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">yellow</span><span class="br0">(</span><span class="st0">"移除 app.asar 文件"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="co1">// 3. 重命名 app.asar 为 app.asar.bak</span></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span>EnableBackup<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> fs.<span class="me1">renameSync</span><span class="br0">(</span>asarPath<span class="sy0">,</span> asarBakPath<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span></span><span class="cbp-l"> fs.<span class="me1">rmSync</span><span class="br0">(</span>asarPath<span class="sy0">,</span> <span class="br0">{</span> force<span class="sy0">:</span> <span class="kw2">true</span> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span></span><span class="cbp-l"> chalk.<span class="me1">yellow</span><span class="br0">(</span><span class="st0">"修改 Typora.exe 的 fuse 配置,允许加载未打包的 app 目录"</span><span class="br0">)</span></span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span>EnableBackup<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="co1">// 修改前先备份</span></span><span class="cbp-l"> fs.<span class="me1">copyFileSync</span><span class="br0">(</span>TyporaEXE<span class="sy0">,</span> `$<span class="br0">{</span>TyporaEXE<span class="br0">}</span>.<span class="me1">bak</span>`<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="co1">// 修改fuse配置(同时会修改程序hash)</span></span><span class="cbp-l"> flipFuses<span class="br0">(</span>TyporaEXE<span class="sy0">,</span> <span class="br0">{</span></span><span class="cbp-l"> version<span class="sy0">:</span> FuseVersion.<span class="me1">V1</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="br0">[</span>FuseV1Options.<span class="me1">OnlyLoadAppFromAsar</span><span class="br0">]</span><span class="sy0">:</span> <span class="kw2">false</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">green</span><span class="br0">(</span><span class="st0">"反反调试操作完成!"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="co1">// 二、注入破解代码</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">yellow</span><span class="br0">(</span><span class="st0">"二、正在注入破解代码到 launch.dist.js..."</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="co1">// 读取原文件内容</span></span><span class="cbp-l"> let content <span class="sy0">=</span> fs.<span class="me1">readFileSync</span><span class="br0">(</span>LaunchDistJS<span class="sy0">,</span> <span class="st0">"utf-8"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="co1">// 查找第一个require语句后的分号</span></span><span class="cbp-l"> <span class="kw1">const</span> requireRegex <span class="sy0">=</span> <span class="co2">/require\([^)]+\);/</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">const</span> match <span class="sy0">=</span> requireRegex.<span class="me1">exec</span><span class="br0">(</span>content<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="kw1">if</span> <span class="br0">(</span>match<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> <span class="kw1">const</span> insertPos <span class="sy0">=</span> match.<span class="me1">index</span> <span class="sy0">+</span> match<span class="br0">[</span><span class="nu0">0</span><span class="br0">]</span>.<span class="me1">length</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">const</span> insertCode <span class="sy0">=</span> getInsertCode<span class="br0">(</span></span><span class="cbp-l"> EnableHookDebug<span class="sy0">,</span></span><span class="cbp-l"> atobMachineCode<span class="sy0">,</span></span><span class="cbp-l"> email<span class="sy0">,</span></span><span class="cbp-l"> nowDateStr</span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="co1">// 插入代码</span></span><span class="cbp-l"> content <span class="sy0">=</span></span><span class="cbp-l"> content.<span class="me1">slice</span><span class="br0">(</span><span class="nu0">0</span><span class="sy0">,</span> insertPos<span class="br0">)</span> <span class="sy0">+</span> insertCode <span class="sy0">+</span> content.<span class="me1">slice</span><span class="br0">(</span>insertPos<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> fs.<span class="me1">writeFileSync</span><span class="br0">(</span>LaunchDistJS<span class="sy0">,</span> content<span class="sy0">,</span> <span class="st0">"utf-8"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">green</span><span class="br0">(</span><span class="st0">"成功插入破解代码到 launch.dist.js"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span></span><span class="cbp-l"> chalk.<span class="me1">red</span><span class="br0">(</span><span class="st0">"未找到 require 语句,破解代码未插入launch.dist.js。"</span><span class="br0">)</span></span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">green</span><span class="br0">(</span><span class="st0">"注入破解代码完成!"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="co1">// // 三、注册激活</span></span><span class="cbp-l"> <span class="co1">// console.log(chalk.yellow("三、正在注册激活..."));</span></span><span class="cbp-l"> <span class="co1">// try {</span></span><span class="cbp-l"> <span class="co1">// execSync(`start "" "${TyporaEXE}"`);</span></span><span class="cbp-l"> <span class="co1">// console.log(chalk.green("Typora 已启动!"));</span></span><span class="cbp-l"> <span class="co1">// } catch (e) {</span></span><span class="cbp-l"> <span class="co1">// console.log(chalk.red("Typora 启动失败,请手动打开。"));</span></span><span class="cbp-l"> <span class="co1">// }</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="co1">// const regCode = generateRegCode();</span></span><span class="cbp-l"> <span class="co1">// console.log(chalk.green(`您的注册码为:${regCode}`));</span></span><span class="cbp-l"> <span class="co1">// console.log(chalk.yellow("请复制并用于激活。"));</span></span><span class="cbp-l"> <span class="co1">// console.log(chalk.cyan("请按回车键继续..."));</span></span><span class="cbp-l"></span><span class="cbp-l"></span><span class="cbp-l"> <span class="co1">// // 关闭Typora进程</span></span><span class="cbp-l"> <span class="co1">// closeTyporaProcesses();</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="co1">// 三、修改注册表</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">yellow</span><span class="br0">(</span><span class="st0">"三、正在修改注册表以关闭联网验证..."</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="co1">// 修改注册表,尽量关闭联网验证</span></span><span class="cbp-l"> <span class="co1">// 注册表路径</span></span><span class="cbp-l"> <span class="kw1">const</span> regKey <span class="sy0">=</span> <span class="kw1">new</span> WinReg<span class="br0">(</span><span class="br0">{</span></span><span class="cbp-l"> hive<span class="sy0">:</span> WinReg.<span class="me1">HKCU</span><span class="sy0">,</span></span><span class="cbp-l"> key<span class="sy0">:</span> <span class="st0">"<span class="es0">\\</span>Software<span class="es0">\\</span>Typora"</span><span class="sy0">,</span></span><span class="cbp-l"> <span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"></span><span class="cbp-l"> <span class="kw1">try</span> <span class="br0">{</span></span><span class="cbp-l"> await setRegValue<span class="br0">(</span>regKey<span class="sy0">,</span> <span class="st0">"SLicense"</span><span class="sy0">,</span> <span class="st0">"RHJlYW1OeWE=#0#1/1/2029"</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">green</span><span class="br0">(</span><span class="st0">"SLicense 注册表字段写入成功"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> await setRegValue<span class="br0">(</span>regKey<span class="sy0">,</span> <span class="st0">"IDate"</span><span class="sy0">,</span> nowDateStr<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">green</span><span class="br0">(</span><span class="st0">"IDate 注册表字段写入成功"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span> <span class="kw1">catch</span> <span class="br0">(</span>err<span class="br0">)</span> <span class="br0">{</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">red</span><span class="br0">(</span><span class="st0">"写入注册表失败:"</span><span class="br0">)</span><span class="sy0">,</span> err<span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">green</span><span class="br0">(</span><span class="st0">"==== 破解完成!使用愉快!===="</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">yellow</span><span class="br0">(</span><span class="st0">"后续操作建议:<span class="es0">\n</span>"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> <span class="kw1">const</span> regCode <span class="sy0">=</span> generateRegCode<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">green</span><span class="br0">(</span>`\t1.您的注册码为:$<span class="br0">{</span>regCode<span class="br0">}</span> 请复制并用于激活。`<span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span>chalk.<span class="me1">yellow</span><span class="br0">(</span><span class="st0">"<span class="es0">\t</span>2. 关闭【自动检查更新】功能,防止被覆盖。"</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"> console.<span class="me1">log</span><span class="br0">(</span></span><span class="cbp-l"> chalk.<span class="me1">yellow</span><span class="br0">(</span></span><span class="cbp-l"> <span class="st0">"<span class="es0">\t</span>3. 关闭【Typora服务器使用国内服务器】功能,避免绕过联网验证失败。"</span></span><span class="cbp-l"> <span class="br0">)</span></span><span class="cbp-l"> <span class="br0">)</span><span class="sy0">;</span></span><span class="cbp-l"><span class="br0">}</span></span><span class="cbp-l"></span><span class="cbp-l">main<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></span> |
注意:209行 const Typora_Installation_Path = “D:\\Software\\Typora”; 这一行要换成自己对应的路径!!!
三、开始激活
1、在 D:\Typora\resources 路径下打开命令行窗口
|
1 |
<span class="cbp-l">C:\Users\Administrator<span class="sy0">></span>D:</span><span class="cbp-l">D:\<span class="sy0">></span><span class="kw3">cd</span> C:\Users\hello\AppData\Local\Programs\Typora\resources</span> |
2、安装 chalk@4 asar readline-sync winreg @electron /fuses
|
1 |
<span class="cbp-l">C:\Users\hello\AppData\Local\Programs\Typora\resources<span class="sy0">></span>npm <span class="kw2">install</span> chalk<span class="sy0">@</span>4 asar readline-sync winreg <span class="sy0">@</span>electron<span class="sy0">/</span>fuses</span> |
3、运行脚本
|
1 |
<span class="cbp-l">C:\Users\hello\AppData\Local\Programs\Typora\resources<span class="sy0">></span>node pj.js</span> |
4、按照提示输入上面复制出来的机器码
5、输入邮箱(这个邮箱只要格式正确就可以)
6、按照提示输入:
|
1 |
<span class="cbp-l">【建议开启】是否开启备份?<span class="br0">(</span>Y<span class="sy0">/</span>N<span class="br0">)</span>:</span><span class="cbp-l">Y</span><span class="cbp-l">【建议关闭】是否开启调试?<span class="br0">(</span>Y<span class="sy0">/</span>N<span class="br0">)</span>:</span><span class="cbp-l">N</span> |
7、敲回车继续
8、回到命令行安装 native-reg
|
1 |
<span class="cbp-l">C:\Users\hello\AppData\Local\Programs\Typora\resources<span class="sy0">></span>npm <span class="kw2">install</span> native-reg</span> |
9、完成激活
再次打开Typora查看我的许可证就显示已经激活了!!!
原文作者: BG6RSH | 查看原帖