mirror of
https://github.com/Mas0nShi/typoraCracker.git
synced 2023-07-10 13:41:20 +08:00
Compare commits
35 Commits
v1.0.0
...
1.2.3-x64-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08041c56e1 | ||
|
|
b3e809d2af | ||
|
|
768f9e870a | ||
|
|
4d15e2a665 | ||
|
|
6a052ea508 | ||
|
|
214f7b5c79 | ||
|
|
7c83710ede | ||
|
|
dac502ef7f | ||
|
|
6874fc54bf | ||
|
|
f74141b4fa | ||
|
|
71c41fcaec | ||
|
|
1d28997146 | ||
|
|
ed3fb49ad0 | ||
|
|
f3310f448a | ||
|
|
1927e06b26 | ||
|
|
d067e4e296 | ||
|
|
0147f7c384 | ||
|
|
1c7a0daf60 | ||
|
|
a45d1b01a8 | ||
|
|
957e412291 | ||
|
|
d5c1bc55c2 | ||
|
|
6152b16fca | ||
|
|
f8ef3769c7 | ||
|
|
b43a44045f | ||
|
|
9787c2dd50 | ||
|
|
9589526703 | ||
|
|
263c976b1a | ||
|
|
9fd4bad0ab | ||
|
|
009b2ebff3 | ||
|
|
583ae2efe7 | ||
|
|
f586be4b1e | ||
|
|
c60fa54d54 | ||
|
|
4532c94d2b | ||
|
|
41ae7e552b | ||
|
|
00f916b16f |
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript', 'python' ]
|
||||
language: ["javascript" , 'python' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||
|
||||
|
||||
29
README.md
29
README.md
@@ -1,36 +1,39 @@
|
||||
# typora Cracker
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2FMas0nShi%2FtyporaCracker?ref=badge_shield)
|
||||
|
||||

|
||||

|
||||
|
||||
A patch and keygen tools for typora.
|
||||
A extract & decryption and pack & encryption tools for typora.
|
||||
|
||||
中文说明请戳[这里](README_CN.md)
|
||||
|
||||
## WARNING
|
||||
|
||||
**NOTE: typoraCracker doesn't provide support for crack.**
|
||||
|
||||
```
|
||||
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).
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- Supports ALL OS supported by typora
|
||||
- Supports Version 1.0.0+ (At least for now.)
|
||||
- tested fine in Windows, Ubuntu
|
||||
|
||||
## Usage
|
||||
|
||||
1. `pip install -r requirements.txt`
|
||||
2. `python typroa.py --help`
|
||||
2. `python typora.py --help`
|
||||
3. read and use.
|
||||
4. patch License.js.
|
||||
5. replace app.asar.
|
||||
6. run keygen.
|
||||
7. enjoy it.
|
||||
4. do something.
|
||||
5. pack and replace app.asar.
|
||||
6. enjoy it.
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
```shell
|
||||
> python typroa.py --help
|
||||
> python typora.py --help
|
||||
usage: typora.py [-h] [-u] [-f] asarPath dirPath
|
||||
|
||||
[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 -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
|
||||
> mv workstation/outappasar/app.asar {installRoot}/Typora/resources/app.asar
|
||||
# (patch code)
|
||||
> node keygen.js
|
||||
> node example/keygen.js
|
||||
XXXXXX-XXXXXX-XXXXXX-XXXXXX
|
||||
> typora
|
||||
# (input info)
|
||||
|
||||
27
README_CN.md
27
README_CN.md
@@ -1,8 +1,11 @@
|
||||
# typora Cracker
|
||||
|
||||
一个typora的Patch和KeyGen工具
|
||||
一个typora的解包&解密,打包&加密工具
|
||||
|
||||
## 敬告
|
||||
|
||||
**请注意:** typoraCracker不会提供破解相关支持,包括但不限于思路、流程、成品。
|
||||
|
||||
```
|
||||
仅供学习和讨论,请不要从事任何非法行为。
|
||||
由此产生的任何问题都将由用户(您)承担。
|
||||
@@ -10,23 +13,23 @@
|
||||
|
||||
## Features
|
||||
|
||||
- 理论上支持Typora支持的所有操作系统
|
||||
- 支持版本1.0.0以上(至少现在是这样)
|
||||
- 测试通过平台:Win/Ubuntu
|
||||
|
||||
## 食用方式
|
||||
|
||||
1. `pip install -r requirements.txt`
|
||||
2. `python typroa.py --help`
|
||||
2. `python typora.py --help`
|
||||
3. 阅读帮助文档及使用。
|
||||
4. 修改导出的 License.js。
|
||||
5. 替换原目录下的 app.asar。
|
||||
6. 运行KeyGen程序。
|
||||
7. 正常激活。
|
||||
4. 做你想做的事。
|
||||
5. 打包并替换原目录下的 app.asar。
|
||||
6. 享受成果。
|
||||
|
||||
|
||||
## 示例
|
||||
|
||||
```shell
|
||||
> python typroa.py --help
|
||||
> python typora.py --help
|
||||
usage: typora.py [-h] [-u] [-f] asarPath dirPath
|
||||
|
||||
[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 -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
|
||||
> mv workstation/outappasar/app.asar {installRoot}/Typora/resources/app.asar
|
||||
# (patch code)
|
||||
> node keygen.js
|
||||
> node example/keygen.js
|
||||
XXXXXX-XXXXXX-XXXXXX-XXXXXX
|
||||
> typora
|
||||
# (input info)
|
||||
@@ -58,4 +61,4 @@ serial: XXXXXX-XXXXXX-XXXXXX-XXXXXX
|
||||
```
|
||||
|
||||
## LICENSE
|
||||
MIT LICENSE
|
||||
MIT LICENSE
|
||||
|
||||
12
example/README.md
Normal file
12
example/README.md
Normal 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
1
example/patch/License.js
Normal file
File diff suppressed because one or more lines are too long
84
typora.py
84
typora.py
@@ -6,38 +6,50 @@
|
||||
@Desc: It's all about getting better.
|
||||
"""
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util.Padding import pad
|
||||
from Crypto.Util.Padding import unpad
|
||||
from Crypto.Util.Padding import pad, unpad
|
||||
from base64 import b64decode, b64encode
|
||||
from jsbeautifier import beautify
|
||||
from jsmin import jsmin
|
||||
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 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]
|
||||
aesKey = b""
|
||||
for akey in key:
|
||||
aesKey += int.to_bytes(akey, byteorder="little", length=8)
|
||||
# DEBUG
|
||||
DEBUG = False
|
||||
|
||||
log.remove()
|
||||
if DEBUG:
|
||||
log.add(sys.stderr, level="DEBUG")
|
||||
else:
|
||||
log.add(sys.stderr, level="INFO")
|
||||
|
||||
AES_KEY = struct.pack("<4Q", *[0xEE22F61DC0C36FD0, 0xCBF8FC4A0D06F3AB, 0xE2F507436D26D722, 0x5AE32AFDEC7872F0])
|
||||
AES_IV = struct.pack("<4L", *[0x33706964, 0x5387CD15, 0xD05F336D, 0x53F82468])
|
||||
|
||||
|
||||
def _mkdir(_path):
|
||||
try:
|
||||
def _mkDir(_path):
|
||||
if not exists(_path):
|
||||
makedirs(_path)
|
||||
except FileExistsError:
|
||||
log.warning(f"May FolderExists: {_path}")
|
||||
else:
|
||||
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):
|
||||
lCode = b64decode(b64)
|
||||
# iv: the first 16 bytes of the file
|
||||
aesIv = lCode[0:16]
|
||||
# iv
|
||||
aesIv = AES_IV
|
||||
# cipher text
|
||||
cipherText = lCode[16:]
|
||||
cipherText = lCode[:]
|
||||
# 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')
|
||||
if prettify:
|
||||
code = beautify(code.decode()).encode()
|
||||
@@ -46,13 +58,18 @@ def decScript(b64: bytes, prettify: bool):
|
||||
|
||||
def extractWdec(asarPath, path, prettify):
|
||||
"""
|
||||
:param prettify: bool
|
||||
:param asarPath: asar out dir
|
||||
:param path: out dir
|
||||
:return: None
|
||||
"""
|
||||
# try to create empty dir to save extract files
|
||||
path = pjoin(path, "tmp_app")
|
||||
_mkdir(path)
|
||||
path = pjoin(path, "typoraCrackerTemp")
|
||||
|
||||
if exists(path):
|
||||
rmtree(path)
|
||||
_mkDir(path)
|
||||
|
||||
log.info(f"extract asar file: {asarPath}")
|
||||
# extract app.asar to {path}/*
|
||||
extract_asar(asarPath, path)
|
||||
@@ -62,7 +79,10 @@ def extractWdec(asarPath, path, prettify):
|
||||
# construct the save directory {pathRoot}/dec_app
|
||||
outPath = pjoin(psplit(path)[0], "dec_app")
|
||||
# try to create empty dir to save decryption files
|
||||
_mkdir(outPath)
|
||||
if exists(outPath):
|
||||
rmtree(outPath)
|
||||
_mkDir(outPath)
|
||||
|
||||
log.info(f"set Directory: {outPath}")
|
||||
# enumerate extract files
|
||||
fileArr = listdir(path)
|
||||
@@ -80,13 +100,16 @@ def extractWdec(asarPath, path, prettify):
|
||||
open(pjoin(outPath, name), "wb").write(scode)
|
||||
log.success(f"decrypt and save file: {name}")
|
||||
|
||||
rmtree(path)
|
||||
log.debug("remove temp dir")
|
||||
|
||||
|
||||
def encScript(_code: bytes, compress):
|
||||
if compress:
|
||||
_code = jsmin(_code.decode(), quote_chars="'\"`").encode()
|
||||
aesIv = urandom(16)
|
||||
cipherText = aesIv + _code
|
||||
ins = AES.new(key=aesKey, iv=aesIv, mode=AES.MODE_CBC)
|
||||
aesIv = AES_IV
|
||||
cipherText = _code
|
||||
ins = AES.new(key=AES_KEY, iv=aesIv, mode=AES.MODE_CBC)
|
||||
enc = ins.encrypt(pad(cipherText, 16, 'pkcs7'))
|
||||
lCode = b64encode(enc)
|
||||
return lCode
|
||||
@@ -99,11 +122,17 @@ def packWenc(path, outPath, compress):
|
||||
:param compress: Bool
|
||||
:return: None
|
||||
"""
|
||||
if not isdir(outPath):
|
||||
# check out path
|
||||
if isfile(outPath):
|
||||
log.error("plz input Directory for app.asar")
|
||||
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")
|
||||
log.info(f"set outFilePath: {outFilePath}")
|
||||
@@ -127,9 +156,12 @@ def packWenc(path, outPath, compress):
|
||||
pack_asar(encFilePath, outFilePath)
|
||||
log.success("pack done")
|
||||
|
||||
rmtree(encFilePath)
|
||||
log.debug("remove temp dir")
|
||||
|
||||
|
||||
def main():
|
||||
argParser = argparse.ArgumentParser(
|
||||
argParser = ArgumentParser(
|
||||
description="[extract and decryption / pack and encryption] app.asar file from [Typora].",
|
||||
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]")
|
||||
|
||||
Reference in New Issue
Block a user