Skip to content

Commit

Permalink
feat: cli
Browse files Browse the repository at this point in the history
  • Loading branch information
kuizuo committed Dec 22, 2023
1 parent 93bd04d commit 570e92e
Show file tree
Hide file tree
Showing 9 changed files with 603 additions and 41 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ node_modules
*.log
.vercel
out
history_*.js
tmp/*
history_*.js
32 changes: 13 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,42 @@
## JS代码混淆还原
## JS混淆代码还原

让混淆不再成为逆向分析中的绊脚石

## 使用

### 网页

[js-deobfuscator.vercel.app](https://js-deobfuscator.vercel.app/) [js-deobfuscator.kuizuo.cn](https://js-deobfuscator.kuizuo.cn/) 在线体验
[js-deobfuscator.vercel.app](https://js-deobfuscator.vercel.app/) 在线体验

![image-1](./images/1.png)

在执行还原前,请根据实际代码设置反混淆配置

控制台可查看相关处理日志

![image-3](./images/3.png)
在执行还原前,请根据实际代码配置

### 本地

安装

```
git clone https://github.com/kuizuo/js-de-obfuscator
cd js-de-obfuscator
git clone https://github.com/kuizuo/js-deobfuscator
cd js-deobfuscator
pnpm i
```

在 example 目录下存放了一些我个人遇到混淆代码实例分析,每个子目录的结构如:
在 tmp/input.js 存放需要反混淆的代码, 执行 `pnpm run tmp` 将会输出 tmp/output.js 反混淆后的代码.

在 example 目录下存放了一些我个人遇到混淆代码实例分析以及配置选项,每个子目录的结构如:

```
├── xxx # 子目录
│ ├── index.js # 运行代码
│ ├── code.js # 需要反混淆代码
│ ├── code_1.js # 记录反混淆过程代码 1
│ ├── code_2.js # 记录反混淆过程代码 2
│ ├── pretty.js # 可选, 用作美化对比
│ ├── output.js # 最终处理完成的结果
│ ├── index.ts # 运行代码
│ ├── input.js # 混淆代码
│ ├── output.js # 还原后代码
│ ├── pretty.js # 用作美化对比
│ ├── setupCode.js # 注入执行代码
│ ├── errorCode.js # 当替换代码导致语法错误, 则将错误代码输出到该文件
```

> 切记按照要求上述文件名格式, 否则会触发 eslint 格式化。
node index.js 即可开始还原代码
由于项目采用 ts 开发且使用 esmodule,因此建议使用 [tsx](https://github.com/privatenumber/tsx) 来执行 index.ts。

## 使用文档

Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"website:build": "pnpm run -F website build",
"website:generate": "pnpm run -F website generate",
"website:serve": "pnpm run -F website serve",
"tmp": "npx deob tmp/input.js -o tmp",
"lint": "eslint './{packages,website,scripts,meta}/**/*.{js,ts,tsx,vue,md,json}'",
"lint:fix": "nr lint --fix",
"release": "bumpp -r",
Expand All @@ -21,6 +22,7 @@
"devDependencies": {
"@antfu/eslint-config": "^1.1.2",
"bumpp": "^9.2.0",
"deob": "workspace:*",
"eslint": "^8.53.0",
"esm": "^3.2.25",
"prettier": "^3.0.3",
Expand Down
1 change: 1 addition & 0 deletions packages/deob/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "deob",
"type": "module",
"version": "2.2.0",
"description": "javascript deobfuscate",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"bin": "dist/cli.js",
Expand Down
20 changes: 4 additions & 16 deletions packages/deob/src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env node

import { existsSync, readFileSync } from 'node:fs'
import { readFile, rm } from 'node:fs/promises'
import { readFileSync } from 'node:fs'
import { readFile } from 'node:fs/promises'
import { join } from 'node:path'
import * as url from 'node:url'
import debug from 'debug'
Expand All @@ -13,12 +13,11 @@ const { version, description } = JSON.parse(
readFileSync(join(__dirname, '..', 'package.json'), 'utf8'),
) as { version: string; description: string }

debug.enable('webcrack:*')
debug.enable('deob:*')

interface Options {
force: boolean
output?: string
mangle?: boolean
}

async function readStdin() {
Expand All @@ -32,22 +31,11 @@ program
.version(version)
.description(description)
.option('-o, --output <path>', 'output directory for bundled files')
.option('-f, --force', 'overwrite output directory')
.option('-m, --mangle', 'mangle variable names')
.argument('[file]', 'input file, defaults to stdin')
.action(async (input: string | undefined) => {
const { output, force, mangle } = program.opts<Options>()
const { output } = program.opts<Options>()
const code = await (input ? readFile(input, 'utf8') : readStdin())

if (output) {
if (force || !existsSync(output)) {
await rm(output, { recursive: true, force: true })
}
else {
program.error('output directory already exists')
}
}

const deob = new Deob(code)
const result = await deob.run()

Expand Down
8 changes: 4 additions & 4 deletions packages/deob/src/transforms/find-decoder-by-array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { generate } from '../ast-utils'
import { Decoder } from '../deobfuscate/decoder'
import type { ArrayRotator } from '../deobfuscate/array-rotator'

export function findDecoderByArray(ast: t.Node, count?: number) {
export function findDecoderByArray(ast: t.Node, count: number = 100) {
// 大数组 有可能是以函数形式包裹的
let stringArray: {
path: NodePath<t.Node>
Expand Down Expand Up @@ -90,13 +90,13 @@ export function findDecoderByArray(ast: t.Node, count?: number) {
}

if (r.parentKey === 'arguments') {
const parent = r.parentPath.parentPath
const parent_expression = parent.findParent(p => p.isExpressionStatement())
const parent = r.parentPath?.parentPath
const parent_expression = parent?.findParent(p => p.isExpressionStatement())
if (parent_expression?.isExpressionStatement()) {
// (function (h) {
// // ...
// })(array)
rotators.push(parent)
rotators.push(parent_expression)
return
}

Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 570e92e

Please sign in to comment.