Skip to content

排版效果示例

这篇是给你自己看的语法速查。左边每一节展示效果,源码在 posts/demo.md 里, 写正式文章时直接复制过去改。

看完就可以删掉这个文件,或者在 frontmatter 加 draft: true 把它从列表里藏起来。

一、基础排版

这是加粗,这是斜体,这是行内代码,这是 删除线,这是一个链接

这是引用块。适合放论文原话、文档摘录、或者你想强调的一句结论。

可以有多段。

  • 无序列表
  • 第二项
    • 嵌套一层
    • 再一项
  1. 有序列表
  2. 第二项
  3. 第三项

任务清单也支持:

  • [x] 已经做完的
  • [ ] 还没做的

上面是一条分割线。

二、代码块(重点,逆向文章全靠它)

基础代码块 + 行号

行号是全局开启的,在 .vitepress/config.mts 里的 markdown.lineNumbers

js
function inlineDispatcherCall(path, state) {
  const callee = path.get('callee')
  if (!isProvenDispatcher(callee, state)) return
  const caseId = resolveStaticCaseId(path.node.arguments[0])
  if (caseId == null) return          // 拿不到静态入口就放弃
  const chain = traceCaseChain(caseId, state)
  return materialize(path, chain, state)
}

高亮指定行

在语言后面加 {行号},多行用逗号,范围用连字符:

js
function inlineDispatcherCall(path, state) {
  const callee = path.get('callee')
  const caseId = resolveStaticCaseId(path.node.arguments[0])
  if (caseId == null) return          // ← 这一行被高亮了

  const chain = traceCaseChain(caseId, state)
  if (chain.hasUnknownBranch) {       // ← 这三行也是
    state.rollback()                  //    用来强调"安全约束"
    return                            //    非常适合讲踩坑
  }
  return materialize(path, chain, state)
}

写法:

md
```js{4,7-9}
// 代码
```

展示"改前改后"(diff)

讲重构、讲还原前后对比时特别好用:

js
const chain = traceAllCases(dispatcherNode)
const chain = traceCaseChain(caseId, state)

写法是在行尾加注释 // [!code --]// [!code ++]

标错误和警告

js
const caseId = args[0].value        
const caseId = resolveStatic(args[0]) 

聚焦某一行(其他行虚化)

js
function traceCaseChain(caseId, state) {
  const visited = new Set()
  let cursor = caseId
  while (cursor != null) {
    if (visited.has(cursor)) break
    visited.add(cursor)
    cursor = nextCase(cursor, state)
  }
}

代码组(多个标签页切换)

js
bwY += trY(533, [rn(mYp(D4p & DJY), D4p | DJY)]);
js
bwY += String.fromCharCode(rn(mYp(D4p & DJY), D4p | DJY));
text
case 533 的实际逻辑只是一次 fromCharCode 调用,
把它平铺回调用点比保留 dispatcher 调用可读得多。

写法:

md
::: code-group
```js [标签一]
```
```js [标签二]
```
:::

纯文本块(放日志、AST 结构、流程图)

text
识别 dispatcher 调用
→ 解析 case ID 与参数数组
→ 追踪真实 case 链
→ 规范化路径内代理调用
→ 递归处理嵌套 dispatcher
→ 绑定参数并选择平铺 / IIFE / 命名 helper

三、提示框(讲坑和注意事项必备)

提示

适合放"小技巧""顺带一提"。

说明

适合放背景补充。

注意

适合放"这里容易踩坑"。写安全约束那一节会大量用到。

危险

适合放"这样做一定会出错"。

点我展开

折叠块。特别适合放很长的代码——比如一整段混淆源码, 读者想看就展开,不想看不影响阅读节奏。

js
var LDp = bLp[0];
BWp -= 31;
if (LDp <= 65535) {
    return U[SP[2]][SP[1]](LDp);
} else {
    LDp -= 65536;
    return U[SP[2]][SP[1]][SP[0]](null, [E2(LDp >> j3, 55296), E2(LDp % 1024, 56320)]);
}

写法:

md
::: warning 注意
内容
:::

::: details 点我展开
内容
:::

四、表格

表格我在 custom.css 里加了横向滚动,窄屏不会撑破布局。

输出形态适用场景代价
直接平铺case 链短、无 return、调用点是语句
IIFEreturn、调用点是表达式每次调用都要执行一次函数
命名 helper同一 case 被多处调用需要保证名字不冲突

对齐方式:

左对齐居中右对齐
abc

五、图片

放在 public/ 目录下,用绝对路径引用:

md
![AST 结构](/images/ast-tree.png)

逆向文章截图多,建议在 public/images/ 下按文章分子目录。

六、写文章的 frontmatter 模板

新建 posts/xxx.md,开头照抄这个:

md
---
title: 文章标题
date: 2026-07-30
summary: 一句话摘要,显示在首页列表里
tags: [AST, 反混淆]
---

# 文章标题

正文……

保存后自动出现在首页和 /posts/ 列表,不用手动登记。

想让它更好找,顺手在 .vitepress/config.mtssidebar 里加一行。

七、右侧目录

右边那个"本页目录"是自动生成的,收 ##### 两级。 所以正文里把层级用规范,目录就自动好看。


看完这篇你就知道能用什么效果了。接下来去写 控制流平坦化的还原思路

内容仅供技术研究与学习交流