Typora【超便捷md文本编辑器】 安装与激活教程

2026-04-29 10:012阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述:

最新帖子解决掉激活等问题

解决Typora掉激活问题【个人最喜欢用的markdown编辑器】 资源荟萃
目录 优点 飞速安装 解决方案 接力解决上一篇贴子的问题 优点 typora本身是作为即开即用【快速且有插件支持】,即时渲染用的【在这AI输出markdown盛行的时代】【Obsidian每次打开得选仓库】 不跳试用弹窗 左下角无未激活 不会掉激活【我是已经过了24小时了】 与最新版只差一版 [image] 省钱 [image] 飞速安装 安装正版特定版本【新版更…

前戏

之前在论坛中安装佬友的 Typor1.11.7-x64-CN 虽然能成功激活,但是后面过一阵子就只能同时打开一个markdown文件

在吾爱上刷到大佬的破解分享
https://www.52pojie.cn/forum.php?mod=viewthread&tid=2084047&extra=page%3D1&page=1

看不懂,遂来L站找无脑教程,寻到https://linux.do/t/topic/1505232
尝试根据流程安装,出现报错

看了下评论区发现相似错误
8402634ed8aa40f3840×585 172 KB

尝试根据评论区重新安装,换方法https://linux.do/t/topic/1505232/19?u=horrah
都不行,遂重新去吾爱大佬帖子在找,找到一键脚本。


正文流程

步骤 1:下载并安装 Typora

首先访问 Typora 官方发布页面下载特定版本(V1.12.4):

下载地址:Typora — macOS release channel

[!TIP]
看到有佬友询问版本问题,上述下载地址内也可查询版本迭代信息

安装路径可以随意选择,本教程以 E:\app\install\Typora 为例。

** 注意**:安装完成后暂时不要打开 Typora,取消勾选 Launch Typora 选项,然后点击 Finish

步骤 2:创建破解工作目录

在任意位置创建 typora-crack 文件夹,本教程以 E:\app\install\typora-crack 为例。

步骤 3:创建破解脚本

typora-crack 文件夹内新建 crack.js 文件,粘贴以下代码

const asar = require("asar"); const chalk = require("chalk"); const fs = require("fs"); const path = require("path"); const { execSync } = require("child_process"); const readlineSync = require("readline-sync"); const WinReg = require("winreg"); const { flipFuses, FuseV1Options, FuseVersion } = require("@electron/fuses"); function getInsertCode(EnableHookDebug, atobMachineCode, email, nowDateStr) { return ` /** Hook破解开始 */ const electron = require("electron"); // 是否启用劫持调试 const HookDebug = ${EnableHookDebug ? "true" : "false"}; // 调试日志定义 const LOG_PATH = ".\\\\Typora_Hook_Log.txt"; //fs.rmSync(LOG_PATH, { force: true }); function writeLog(...data) { const log = \`[\${new Date().toLocaleString()}] [Log] \${data.join( " " )}\\n------------------\\n\`; fs.appendFileSync(LOG_PATH, log); } // 开启调试窗口,阻止关闭 app.quit 调用 // Hook Electron 模块,监控 BrowserWindow 实例化及阻止 app.quit 调用 // Node模块require后会进行缓存,即使再次require会指向同一个对象 if (HookDebug) { Object.defineProperty(electron.app, "quit", { value: function () { writeLog("[&#128737;&#65039; 拦截] 程序试图调用 app.quit(),已阻止。"); }, writable: true, configurable: true, }); electron.app.on("browser-window-created", (_event, win) => { writeLog("【&#128064; 监控】检测到 BrowserWindow 实例化!"); // 确保dom-ready后再打开DevTools 否则第一个窗口可能会无法打开 win.webContents.once("dom-ready", () => { writeLog("【&#128295;】打开 DevTools..."); win.webContents.openDevTools({ mode: "detach" }); }); }); } // Hook fs 模块,重定向对 resources/app 目录的访问 // resources/app/ → resources/app.bak/ const fsPathFrom = /resources[\\\\/]app[\\\\/]/i; const fsPathTo = "resources\\\\app.bak\\\\"; const fsHook = {}; [ "readFileSync", "readFile", "statSync", "stat", "Stats", "StatsFs", "open", "openSync", ].forEach((property) => { fsHook[property] = fs[property]; fs[property] = function (filePath, ...args) { if (typeof filePath == "string" && fsPathFrom.test(filePath)) { const redirectPath = filePath.replace(fsPathFrom, fsPathTo); writeLog( \`[&#128737;&#65039; fsHook] 程序试图 fs.\${property} 重定向 \${filePath} --> \${redirectPath}\` ); return fsHook[property].call(this, redirectPath, ...args); } writeLog(\`[&#128737;&#65039; fsHook] 程序试图 fs.\${property} \${filePath}\`); return fsHook[property].call(this, filePath, ...args); }; }); const fsPromisesHook = {}; ["readFile", "open", "stat"].forEach((property) => { fsPromisesHook[property] = fs.promises[property]; fs.promises[property] = async function (filePath, ...args) { if (typeof filePath == "string" && fsPathFrom.test(filePath)) { const redirectPath = filePath.replace(fsPathFrom, fsPathTo); writeLog( \`[&#128737;&#65039; fsHook/Promises] 程序试图 fs.promises.\${property} 重定向 \${filePath} --> \${redirectPath}\` ); return fsPromisesHook[property].call(this, redirectPath, ...args); } writeLog( \`[&#128737;&#65039; fsHook/Promises] 程序试图 fs.promises.\${property} \${filePath}\` ); return fsPromisesHook[property].call(this, filePath, ...args); }; }); // IPC 通信进行监控 if (HookDebug) { const invokeFilter = ["document.addSnapAndLastSync", "document.setContent"]; const originalIpcMainHandle = electron.ipcMain.handle; electron.ipcMain.handle = function (channel, listener) { // writeLog(\`[IPC 注册] .handle 监听频道: "\${channel}"\`); const filter = !invokeFilter.includes(channel); return originalIpcMainHandle.call(this, channel, async (event, ...args) => { filter && writeLog( \`[&#128064;IPC 请求] 收到 .invoke("\${channel}") 参数:\`, JSON.stringify(args) ); try { const result = await listener(event, ...args); filter && writeLog( \`[&#128064;IPC 响应] .handle("\${channel}") 返回结果:\`, JSON.stringify(result) ); return result; } catch (error) { filter && writeLog(\`[&#128064;IPC 错误] .handle("\${channel}") 执行出错:\`, error); throw error; } }); }; } const crypto = require("crypto"); const originalPublicDecrypt = crypto.publicDecrypt; crypto.publicDecrypt = function (key, buffer) { if (HookDebug) { writeLog("-------------------------------------------"); writeLog("【&#128064; 监控】 crypto.publicDecrypt 被调用"); writeLog("Key:", key); writeLog("Buffer (Hex):", buffer.toString("hex")); } // return originalPublicDecrypt.call(this, key, buffer); // 直接返回伪造的明文 Buffer return Buffer.from( JSON.stringify({ deviceId: "${atobMachineCode.l}", fingerprint: "${atobMachineCode.i}", email: "${email}", license: "Cracked_By_DreamNya", version: "${atobMachineCode.v}", date: "${nowDateStr}", type: "DreamNya", }) ); }; // 劫持联网验证 electron.app.whenReady().then(() => { electron.protocol.handle("https", async (request) => { writeLog(\`[&#128064;electron.net Request] \${request.method} \${request.url}\`); writeLog("request.url typeof:", typeof request.url, "value:", request.url); // 拦截目标请求,伪造响应 if (request.url === "https://store.typora.io/api/client/renew") { if (HookDebug){ writeLog(\`[&#128737;&#65039; 拦截] 伪造激活验证响应: {success:true, msg: \${btoa("DreamNya")}}\`); } return new Response( JSON.stringify({ success: true, msg: btoa("DreamNya") }), { status: 200, headers: { "content-type": "application/json" }, } ); } if (HookDebug) { // 尝试打印 Request Body try { const reqClone = request.clone(); const reqBody = await reqClone.text(); if (reqBody) { writeLog('[electron.net Request Body]:', reqBody); } } catch { } // 其他请求正常转发 const response = await electron.net.fetch(request, { bypassCustomProtocolHandlers: true }); // 克隆响应用于日志 const resClone = response.clone(); resClone .text() .then((resText) => { writeLog(\`[&#128064;electron.net Response] \${response.status} \${request.url}\`); writeLog('[electron.net Response Body]:', resText.substring(0, 500)); }) .catch((err) => { console.error('[electron.net Response Error]:', err); }); return response; } }); }); /** Hook破解结束 */ `; } let EnableBackup = false; // 是否备份原始文件 let EnableHookDebug = false; // 是否启用调试日志 const Typora_Installation_Path = "E:\\app\\install\\Typora"; const resourcesPath = path.join(Typora_Installation_Path, "resources"); const asarPath = path.join(resourcesPath, "app.asar"); const appDir = path.join(resourcesPath, "app"); const appBakDir = path.join(resourcesPath, "app.bak"); const asarBakPath = path.join(resourcesPath, "app.asar.bak"); const TyporaEXE = path.join(Typora_Installation_Path, "Typora.exe"); const LaunchDistJS = path.join(appDir, "launch.dist.js"); // 随机生成一个符合前端验证格式的注册码 function generateRegCode() { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; let code = '+'; for (let i = 0; i < 8; i++) { code += chars.charAt(Math.floor(Math.random() * chars.length)); } code += '#'; return code; } function closeTyporaProcesses() { try { execSync("taskkill /F /IM Typora.exe"); console.log(chalk.green("已关闭所有 Typora.exe 进程")); } catch (e) { console.log(chalk.red("Typora.exe 未运行或关闭失败,请手动关闭后继续。")); } console.log( chalk.yellow( "已尝试自动关闭所有 Typora.exe 进程,如果未关闭请手动关闭后再运行此程序。" ) ); // 回车继续 console.log(chalk.cyan("请按回车键继续...")); readlineSync.question(); } function setRegValue(regKey, name, value) { return new Promise((resolve, reject) => { regKey.set(name, WinReg.REG_SZ, value, function (err) { if (err) reject(err); else resolve(); }); }); } function getNowDateStr() { const now = new Date(); const dd = String(now.getDate()).padStart(2, "0"); const mm = String(now.getMonth() + 1).padStart(2, "0"); const yyyy = now.getFullYear(); return `${mm}/${dd}/${yyyy}`; } const nowDateStr = getNowDateStr(); // 要求输入机器码和邮箱 console.log(chalk.cyan("请输入机器码: ")); const machineCode = readlineSync.question(); console.log(chalk.cyan("请输入邮箱: ")); const email = readlineSync.question(); // 询问是否开启备份(默认开启)与调试(默认关闭) console.log(chalk.cyan("请选择是否开启备份与调试选项:")); console.log(chalk.cyan("【建议开启】是否开启备份?(Y/N): ")); const backupAnswer = readlineSync.question(); console.log(chalk.cyan("【建议关闭】是否开启调试?(Y/N): ")); const debugAnswer = readlineSync.question(); EnableBackup = backupAnswer.toLowerCase() === "y"; EnableHookDebug = debugAnswer.toLowerCase() === "y"; // Base64 解码 function atob(str) { return Buffer.from(str, "base64").toString("utf-8"); } const atobMachineCode = JSON.parse(atob(machineCode)); console.log(chalk.yellow("deviceId: " + atobMachineCode.l)); console.log(chalk.yellow("fingerprint: " + atobMachineCode.i)); console.log(chalk.yellow("version: " + atobMachineCode.v)); // 关闭所有 Typora.exe 进程 closeTyporaProcesses(); console.log(chalk.green("==== 开始破解... ====")); async function main() { // 一、反反调试 console.log(chalk.yellow("一、正在进行反反调试操作...")); console.log(chalk.yellow("解包 asar")); await asar.extractAll(asarPath, appDir); console.log( chalk.yellow("复制 app 到 app.bak(递归复制)【应对完整性校验】") ); // 2. 复制 app 到 app.bak(递归复制) function copyDir(src, dest) { if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true }); for (const entry of fs.readdirSync(src, { withFileTypes: true })) { const srcPath = path.join(src, entry.name); const destPath = path.join(dest, entry.name); if (entry.isDirectory()) { copyDir(srcPath, destPath); } else { fs.copyFileSync(srcPath, destPath); } } } copyDir(appDir, appBakDir); console.log(chalk.yellow("移除 app.asar 文件")); // 3. 重命名 app.asar 为 app.asar.bak if (EnableBackup) { fs.renameSync(asarPath, asarBakPath); } else { fs.rmSync(asarPath, { force: true }); } console.log( chalk.yellow("修改 Typora.exe 的 fuse 配置,允许加载未打包的 app 目录") ); if (EnableBackup) { // 修改前先备份 fs.copyFileSync(TyporaEXE, `${TyporaEXE}.bak`); } // 修改fuse配置(同时会修改程序hash) flipFuses(TyporaEXE, { version: FuseVersion.V1, [FuseV1Options.OnlyLoadAppFromAsar]: false, }); console.log(chalk.green("反反调试操作完成!")); // 二、注入破解代码 console.log(chalk.yellow("二、正在注入破解代码到 launch.dist.js...")); // 读取原文件内容 let content = fs.readFileSync(LaunchDistJS, "utf-8"); // 查找第一个require语句后的分号 const requireRegex = /require\([^)]+\);/; const match = requireRegex.exec(content); if (match) { const insertPos = match.index + match[0].length; const insertCode = getInsertCode( EnableHookDebug, atobMachineCode, email, nowDateStr ); // 插入代码 content = content.slice(0, insertPos) + insertCode + content.slice(insertPos); fs.writeFileSync(LaunchDistJS, content, "utf-8"); console.log(chalk.green("成功插入破解代码到 launch.dist.js")); } else { console.log( chalk.red("未找到 require 语句,破解代码未插入launch.dist.js。") ); } console.log(chalk.green("注入破解代码完成!")); // // 三、注册激活 // console.log(chalk.yellow("三、正在注册激活...")); // try { // execSync(`start "" "${TyporaEXE}"`); // console.log(chalk.green("Typora 已启动!")); // } catch (e) { // console.log(chalk.red("Typora 启动失败,请手动打开。")); // } // const regCode = generateRegCode(); // console.log(chalk.green(`您的注册码为:${regCode}`)); // console.log(chalk.yellow("请复制并用于激活。")); // console.log(chalk.cyan("请按回车键继续...")); // // 关闭Typora进程 // closeTyporaProcesses(); // 三、修改注册表 console.log(chalk.yellow("三、正在修改注册表以关闭联网验证...")); // 修改注册表,尽量关闭联网验证 // 注册表路径 const regKey = new WinReg({ hive: WinReg.HKCU, key: "\\Software\\Typora", }); try { await setRegValue(regKey, "SLicense", "RHJlYW1OeWE=#0#1/1/2029"); console.log(chalk.green("SLicense 注册表字段写入成功")); await setRegValue(regKey, "IDate", nowDateStr); console.log(chalk.green("IDate 注册表字段写入成功")); } catch (err) { console.log(chalk.red("写入注册表失败:"), err); } console.log(chalk.green("==== 破解完成!使用愉快!====")); console.log(chalk.yellow("后续操作建议:\n")); const regCode = generateRegCode(); console.log(chalk.green(`\t1.您的注册码为:${regCode} 请复制并用于激活。`)); console.log(chalk.yellow("\t2. 关闭【自动检查更新】功能,防止被覆盖。")); console.log( chalk.yellow( "\t3. 关闭【Typora服务器使用国内服务器】功能,避免绕过联网验证失败。" ) ); } main();

修改代码中的安装路径(第 209 行)

使用 Ctrl + F 搜索 const Typora_Installation_Path =,将路径修改为你的实际安装路径:

const Typora_Installation_Path = "E:\\app\\install\\Typora"; // 替换为实际安装地址

步骤 4:安装依赖包

typora-crack 文件夹内右键选择在终端中打开,依次执行以下命令:

4.1 初始化 npm 项目

npm init -y

4.2 安装所需依赖

npm install asar chalk@4 readline-sync winreg @electron/fuses

** 注意**:这里必须使用旧版 chalk@4,否则下一步运行时会报错。

4.3 运行破解脚本

node crack.js

执行后,脚本会要求输入机器码(稍后获取)。

步骤 5:获取机器码并完成激活

按照以下流程图操作:

graph TD A[打开 Typora] --> B[跳出首次使用引导弹窗] B --> C[一直点击下一步到激活步骤] C --> D{能否看到离线激活选项?} D -->|看不到| E[任务栏右键关闭 Typora] E --> F[重新打开 Typora] F --> D D -->|能看到| G[点击离线激活] G --> H[复制机器码] H --> I[关闭 Typora] I --> J[回到终端粘贴机器码] J --> K[按提示完成激活流程] K --> L[done!] style A fill:#e1f5ff style L fill:#d4edda style E fill:#fff3cd style I fill:#fff3cd


后续建议

激活成功后,建议进行以下设置:

  1. 关闭自动检查更新:防止破解被覆盖
  2. 关闭"使用国内服务器"选项:避免绕过联网验证失败

声明:本教程仅供学习交流使用,请支持正版软件。


插件分享

github.com

GitHub - MadMaxChow/VLOOK: VLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is...

VLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is an elegant and practical THEME PACKAGE × ENHANCEMENT PLUGIN for Typora/Markdown.

github.com

GitHub - obgnail/typora_plugin: Typora plugin. Feature enhancement tool | Typora...

Typora plugin. Feature enhancement tool | Typora 插件,功能增强工具

网友解答:
--【壹】--:

mark,typora激活


--【贰】--:

感谢佬的分享,已经激活了


--【叁】--:

感谢佬友的分享啊


--【肆】--:

TQL,感谢佬


--【伍】--:

马上试试,感谢分享


--【陆】--:

感谢分享


--【柒】--:

很不错的帖子


--【捌】--:

感谢佬友深夜分享!!


--【玖】--:

感谢大佬分享 红心奉上


--【拾】--:

佬能力太强了!
感谢分享教程!


--【拾壹】--:

马住,改文件的之前出现用一段时间就打开没反应。
回头试试


--【拾贰】--:

感谢佬友分享


--【拾叁】--:

吾爱上这类很多


--【拾肆】--:

e帮,之前只能打来一个文件烦死了


--【拾伍】--:

感谢分享,还是用的一个老版本。


--【拾陆】--:

感谢佬分享


--【拾柒】--:

感谢佬友的分享


--【拾捌】--:

我一直是用
alias ty=“path”然后 ty -n docs.md好像就行了
有时候文件是空的就 echo “#”>>docs.md 然后再ty -n docs.md就好了(#可以是任意字符)


--【拾玖】--:

感谢大佬分享!流程图似乎看不到?