33 Commits

Author SHA1 Message Date
mason
768f9e870a updaate aesIv for 1.2.2-dev 2022-03-15 12:24:26 +08:00
mason
4d15e2a665 updaate aesKey for 1.2.2-dev 2022-03-14 21:07:22 +08:00
Mas0nShi
6a052ea508 fix #32. 2022-02-22 16:20:34 +08:00
Mas0nShi
214f7b5c79 fix the temp folder existence errors. 2022-02-22 10:58:36 +08:00
Mason Shi
7c83710ede Update README_CN.md 2022-02-21 17:26:24 +08:00
Mason Shi
dac502ef7f Update README.md 2022-02-20 18:08:39 +08:00
Mason Shi
6874fc54bf Update README_CN.md 2022-01-04 23:26:44 +08:00
Mason Shi
f74141b4fa Update README_CN.md 2022-01-04 23:25:59 +08:00
Mason Shi
71c41fcaec Create README.md 2021-12-23 14:53:06 +08:00
Mason
1d28997146 solve #18 2021-12-12 14:54:44 +08:00
Mason
ed3fb49ad0 solve issue #13 and optimize some details 2021-12-04 22:27:20 +08:00
Mason
f3310f448a rewrite details 2021-12-03 05:29:04 +08:00
Mason Shi
1927e06b26 Update README.md 2021-12-01 16:12:28 +08:00
Mason
d067e4e296 Merge remote-tracking branch 'origin/master' 2021-12-01 16:10:55 +08:00
Mason
0147f7c384 add Note 2021-12-01 16:10:08 +08:00
Mason
1c7a0daf60 add Note 2021-12-01 16:09:39 +08:00
Mason Shi
a45d1b01a8 Update codeql-analysis.yml 2021-12-01 15:28:35 +08:00
Mason
957e412291 Initial commit 2021-12-01 15:21:18 +08:00
Mason
d5c1bc55c2 Initial commit 2021-12-01 15:21:18 +08:00
Mason Shi
6152b16fca Update codeql-analysis.yml 2021-12-01 15:15:43 +08:00
Mason Shi
f8ef3769c7 Merge pull request #6 from Mas0nShi/add-license-1
Delete keygen.js
2021-12-01 15:11:31 +08:00
Mason Shi
b43a44045f Delete keygen.js
abide by the rules
2021-12-01 15:11:03 +08:00
Mason Shi
9787c2dd50 Delete keygen.js
abide by the rules
2021-12-01 15:10:47 +08:00
Mason Shi
9589526703 Delete patch directory 2021-12-01 15:10:35 +08:00
Mason
263c976b1a abide by the rules 2021-12-01 15:10:09 +08:00
Mason
9fd4bad0ab Initial commit 2021-11-30 23:20:33 +08:00
Mason Shi
009b2ebff3 Merge pull request #3 from laowenruo/patch-1
Update README.md
2021-11-30 19:55:28 +08:00
Mason Shi
583ae2efe7 Merge pull request #4 from laowenruo/patch-2
Update README_CN.md
2021-11-30 19:54:47 +08:00
coder_ryan
f586be4b1e Update README_CN.md
typroa -> typora
2021-11-30 19:14:51 +08:00
coder_ryan
c60fa54d54 Update README.md
typroa -> typora
2021-11-30 19:14:05 +08:00
Mason
4532c94d2b Initial commit 2021-11-30 15:32:21 +08:00
Mason Shi
41ae7e552b Update README.md 2021-11-30 15:24:07 +08:00
Mason Shi
00f916b16f none 2021-11-30 15:16:00 +08:00
7 changed files with 103 additions and 52 deletions

View File

@@ -32,7 +32,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
language: [ 'javascript', 'python' ] language: ["javascript" , 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support # Learn more about CodeQL language support at https://git.io/codeql-language-support

View File

@@ -1,36 +1,39 @@
# typora Cracker # typora Cracker
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FMas0nShi%2FtyporaCracker.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FMas0nShi%2FtyporaCracker?ref=badge_shield)
![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FMas0nShi%2FtyporaCracker.svg?type=shield)
![GitHub](https://img.shields.io/github/license/Mas0nShi/typoraCracker) ![GitHub](https://img.shields.io/github/license/Mas0nShi/typoraCracker)
A patch and keygen tools for typora. A extract & decryption and pack & encryption tools for typora.
中文说明请戳[这里](README_CN.md) 中文说明请戳[这里](README_CN.md)
## WARNING ## WARNING
**NOTE: typoraCracker doesn't provide support for crack.**
``` ```
FOR STUDY AND DISCUSSION ONLY, PLEASE DO NOT ENGAGE IN ANY ILLEGAL ACTS. FOR STUDY AND DISCUSSION ONLY, PLEASE DO NOT ENGAGE IN ANY ILLEGAL ACTS.
ANY PROBLEMS ARISING FROM THIS WILL BE BORNE BY THE USER (YOU). ANY PROBLEMS ARISING FROM THIS WILL BE BORNE BY THE USER (YOU).
``` ```
## Features ## Features
- Supports Version 1.0.0+ (At least for now.)
- Supports ALL OS supported by typora - tested fine in Windows, Ubuntu
## Usage ## Usage
1. `pip install -r requirements.txt` 1. `pip install -r requirements.txt`
2. `python typroa.py --help` 2. `python typora.py --help`
3. read and use. 3. read and use.
4. patch License.js. 4. do something.
5. replace app.asar. 5. pack and replace app.asar.
6. run keygen. 6. enjoy it.
7. enjoy it.
## Example ## Example
```shell ```shell
> python typroa.py --help > python typora.py --help
usage: typora.py [-h] [-u] [-f] asarPath dirPath usage: typora.py [-h] [-u] [-f] asarPath dirPath
[extract and decryption / pack and encryption] app.asar file from [Typora]. [extract and decryption / pack and encryption] app.asar file from [Typora].
@@ -48,12 +51,12 @@ If you have any questions, please contact [ MasonShi@88.com ]
> python typora.py {installRoot}/Typora/resources/app.asar workstation/outfile/ > python typora.py {installRoot}/Typora/resources/app.asar workstation/outfile/
> python typora.py -u workstation/outfile/ workstation/outappasar # (patch code by yourself in workstation/outfile/dec_app)
> python typora.py -u workstation/outfile/dec_app workstation/outappasar
> cp {installRoot}/Typora/resources/app.asar {installRoot}/Typora/resources/app.asar.bak > cp {installRoot}/Typora/resources/app.asar {installRoot}/Typora/resources/app.asar.bak
> mv workstation/outappasar/app.asar {installRoot}/Typora/resources/app.asar > mv workstation/outappasar/app.asar {installRoot}/Typora/resources/app.asar
# (patch code) > node example/keygen.js
> node keygen.js
XXXXXX-XXXXXX-XXXXXX-XXXXXX XXXXXX-XXXXXX-XXXXXX-XXXXXX
> typora > typora
# (input info) # (input info)

View File

@@ -1,8 +1,11 @@
# typora Cracker # typora Cracker
一个typora的Patch和KeyGen工具 一个typora的解包&解密,打包&加密工具
## 敬告 ## 敬告
**请注意:** typoraCracker不会提供破解相关支持包括但不限于思路、流程、成品。
``` ```
仅供学习和讨论,请不要从事任何非法行为。 仅供学习和讨论,请不要从事任何非法行为。
由此产生的任何问题都将由用户(您)承担。 由此产生的任何问题都将由用户(您)承担。
@@ -10,23 +13,23 @@
## Features ## Features
- 理论上支持Typora支持的所有操作系统 - 支持版本1.0.0以上(至少现在是这样)
- 测试通过平台Win/Ubuntu
## 食用方式 ## 食用方式
1. `pip install -r requirements.txt` 1. `pip install -r requirements.txt`
2. `python typroa.py --help` 2. `python typora.py --help`
3. 阅读帮助文档及使用。 3. 阅读帮助文档及使用。
4. 修改导出的 License.js 4. 做你想做的事
5. 替换原目录下的 app.asar。 5. 打包并替换原目录下的 app.asar。
6. 运行KeyGen程序 6. 享受成果
7. 正常激活。
## 示例 ## 示例
```shell ```shell
> python typroa.py --help > python typora.py --help
usage: typora.py [-h] [-u] [-f] asarPath dirPath usage: typora.py [-h] [-u] [-f] asarPath dirPath
[extract and decryption / pack and encryption] app.asar file from [Typora]. [extract and decryption / pack and encryption] app.asar file from [Typora].
@@ -44,12 +47,12 @@ If you have any questions, please contact [ MasonShi@88.com ]
> python typora.py {installRoot}/Typora/resources/app.asar workstation/outfile/ > python typora.py {installRoot}/Typora/resources/app.asar workstation/outfile/
> python typora.py -u workstation/outfile/ workstation/outappasar # (patch code by yourself in workstation/outfile/dec_app)
> python typora.py -u workstation/outfile/dec_app workstation/outappasar
> cp {installRoot}/Typora/resources/app.asar {installRoot}/Typora/resources/app.asar.bak > cp {installRoot}/Typora/resources/app.asar {installRoot}/Typora/resources/app.asar.bak
> mv workstation/outappasar/app.asar {installRoot}/Typora/resources/app.asar > mv workstation/outappasar/app.asar {installRoot}/Typora/resources/app.asar
# (patch code) > node example/keygen.js
> node keygen.js
XXXXXX-XXXXXX-XXXXXX-XXXXXX XXXXXX-XXXXXX-XXXXXX-XXXXXX
> typora > typora
# (input info) # (input info)
@@ -58,4 +61,4 @@ serial: XXXXXX-XXXXXX-XXXXXX-XXXXXX
``` ```
## LICENSE ## LICENSE
MIT LICENSE MIT LICENSE

12
example/README.md Normal file
View File

@@ -0,0 +1,12 @@
## example
tested in version 1.0.2 only, it's means that you may need to make changes yourself if release the latest version.
v1.0.2 download:
- windows(64bit): https://download.typora.io/windows/typora-setup-x64-1.0.2.exe
- windows(32bit): https://download.typora.io/windows/typora-setup-ia32-1.0.2.exe
- windows(arm): https://download.typora.io/windows/typora-setup-arm64-1.0.2.exe
- linux(64bit|DEB): https://download.typora.io/linux/typora_1.0.2_amd64.deb
- linux(64bit|TAR): https://download.typora.io/linux/Typora-linux-x64-1.0.2.tar.gz
- linux(arm|DEB): https://download.typora.io/linux/typora_1.0.2_arm64.deb
- linux(arm|TAR): https://download.typora.io/linux/Typora-linux-arm64-1.0.2.tar.gz

1
example/patch/License.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -6,38 +6,50 @@
@Desc: It's all about getting better. @Desc: It's all about getting better.
""" """
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Util.Padding import pad from Crypto.Util.Padding import pad, unpad
from Crypto.Util.Padding import unpad
from base64 import b64decode, b64encode from base64 import b64decode, b64encode
from jsbeautifier import beautify from jsbeautifier import beautify
from jsmin import jsmin from jsmin import jsmin
from os import listdir, urandom, makedirs from os import listdir, urandom, makedirs
from os.path import isfile, isdir, join as pjoin, split as psplit from os.path import isfile, isdir, join as pjoin, split as psplit, exists, abspath
from loguru import logger as log from loguru import logger as log
from masar import extract_asar, pack_asar from masar import extract_asar, pack_asar
import argparse from shutil import rmtree
from argparse import ArgumentParser
import struct
import sys
key = [0x4B029A9482B3E14E, 0xF157FEB4B4522F80, 0xE25692105308F4BE, 0x6DD58DDDA3EC0DC2] # DEBUG
aesKey = b"" DEBUG = False
for akey in key:
aesKey += int.to_bytes(akey, byteorder="little", length=8) log.remove()
if DEBUG:
log.add(sys.stderr, level="DEBUG")
else:
log.add(sys.stderr, level="INFO")
AES_KEY = struct.pack("<4Q", *[0x252A4C7BD0B85281, 0xA31BD92CE099F719, 0x13E283392646D82D, 0x118BDE501CF74120])
AES_IV = struct.pack("<4L", *[0x33706964, 0x5387CDD2, 0xD05F336D, 0x53F82468])
def _mkdir(_path): def _mkDir(_path):
try: if not exists(_path):
makedirs(_path) makedirs(_path)
except FileExistsError: else:
log.warning(f"May FolderExists: {_path}") if _path == psplit(__file__)[0]:
log.warning("plz try not to use the root dir.")
else:
log.warning(f"May FolderExists: {_path}")
def decScript(b64: bytes, prettify: bool): def decScript(b64: bytes, prettify: bool):
lCode = b64decode(b64) lCode = b64decode(b64)
# iv: the first 16 bytes of the file # iv
aesIv = lCode[0:16] aesIv = AES_IV
# cipher text # cipher text
cipherText = lCode[16:] cipherText = lCode[:]
# AES 256 CBC # AES 256 CBC
ins = AES.new(key=aesKey, iv=aesIv, mode=AES.MODE_CBC) ins = AES.new(key=AES_KEY, iv=aesIv, mode=AES.MODE_CBC)
code = unpad(ins.decrypt(cipherText), 16, 'pkcs7') code = unpad(ins.decrypt(cipherText), 16, 'pkcs7')
if prettify: if prettify:
code = beautify(code.decode()).encode() code = beautify(code.decode()).encode()
@@ -46,13 +58,18 @@ def decScript(b64: bytes, prettify: bool):
def extractWdec(asarPath, path, prettify): def extractWdec(asarPath, path, prettify):
""" """
:param prettify: bool
:param asarPath: asar out dir :param asarPath: asar out dir
:param path: out dir :param path: out dir
:return: None :return: None
""" """
# try to create empty dir to save extract files # try to create empty dir to save extract files
path = pjoin(path, "tmp_app") path = pjoin(path, "typoraCrackerTemp")
_mkdir(path)
if exists(path):
rmtree(path)
_mkDir(path)
log.info(f"extract asar file: {asarPath}") log.info(f"extract asar file: {asarPath}")
# extract app.asar to {path}/* # extract app.asar to {path}/*
extract_asar(asarPath, path) extract_asar(asarPath, path)
@@ -62,7 +79,10 @@ def extractWdec(asarPath, path, prettify):
# construct the save directory {pathRoot}/dec_app # construct the save directory {pathRoot}/dec_app
outPath = pjoin(psplit(path)[0], "dec_app") outPath = pjoin(psplit(path)[0], "dec_app")
# try to create empty dir to save decryption files # try to create empty dir to save decryption files
_mkdir(outPath) if exists(outPath):
rmtree(outPath)
_mkDir(outPath)
log.info(f"set Directory: {outPath}") log.info(f"set Directory: {outPath}")
# enumerate extract files # enumerate extract files
fileArr = listdir(path) fileArr = listdir(path)
@@ -80,13 +100,16 @@ def extractWdec(asarPath, path, prettify):
open(pjoin(outPath, name), "wb").write(scode) open(pjoin(outPath, name), "wb").write(scode)
log.success(f"decrypt and save file: {name}") log.success(f"decrypt and save file: {name}")
rmtree(path)
log.debug("remove temp dir")
def encScript(_code: bytes, compress): def encScript(_code: bytes, compress):
if compress: if compress:
_code = jsmin(_code.decode(), quote_chars="'\"`").encode() _code = jsmin(_code.decode(), quote_chars="'\"`").encode()
aesIv = urandom(16) aesIv = AES_IV
cipherText = aesIv + _code cipherText = _code
ins = AES.new(key=aesKey, iv=aesIv, mode=AES.MODE_CBC) ins = AES.new(key=AES_KEY, iv=aesIv, mode=AES.MODE_CBC)
enc = ins.encrypt(pad(cipherText, 16, 'pkcs7')) enc = ins.encrypt(pad(cipherText, 16, 'pkcs7'))
lCode = b64encode(enc) lCode = b64encode(enc)
return lCode return lCode
@@ -99,11 +122,17 @@ def packWenc(path, outPath, compress):
:param compress: Bool :param compress: Bool
:return: None :return: None
""" """
if not isdir(outPath): # check out path
if isfile(outPath):
log.error("plz input Directory for app.asar") log.error("plz input Directory for app.asar")
raise NotADirectoryError raise NotADirectoryError
encFilePath = pjoin(psplit(outPath)[0], "enc_app")
_mkdir(encFilePath) _mkDir(outPath)
encFilePath = pjoin(psplit(outPath)[0], "typoraCrackerTemp")
if exists(encFilePath):
rmtree(encFilePath)
_mkDir(encFilePath)
outFilePath = pjoin(outPath, "app.asar") outFilePath = pjoin(outPath, "app.asar")
log.info(f"set outFilePath: {outFilePath}") log.info(f"set outFilePath: {outFilePath}")
@@ -127,9 +156,12 @@ def packWenc(path, outPath, compress):
pack_asar(encFilePath, outFilePath) pack_asar(encFilePath, outFilePath)
log.success("pack done") log.success("pack done")
rmtree(encFilePath)
log.debug("remove temp dir")
def main(): def main():
argParser = argparse.ArgumentParser( argParser = ArgumentParser(
description="[extract and decryption / pack and encryption] app.asar file from [Typora].", description="[extract and decryption / pack and encryption] app.asar file from [Typora].",
epilog="If you have any questions, please contact [ MasonShi@88.com ]") epilog="If you have any questions, please contact [ MasonShi@88.com ]")
argParser.add_argument("asarPath", type=str, help="app.asar file path/dir [input/ouput]") argParser.add_argument("asarPath", type=str, help="app.asar file path/dir [input/ouput]")