内容
# 皮层
> 为Windows游戏和本地应用程序准备的AI就绪运行时检测。




皮层(Cortex)是一个混合外部主机和可注入的Windows代理,通过本地、身份验证的REST API公开正在运行的进程。它提供了内存扫描、运行时分析、调试、修补、输入自动化、截图和持久项目状态,所有这些都通过一个机器可读的接口设计用于工具和AI代理。
HTTP服务器仅绑定到`127.0.0.1`。受保护的路由需要一个256位令牌,该令牌在DLL旁边生成。
> [!WARNING]
> 仅将Cortex与您拥有或有权检查的软件一起使用。它旨在用于离线研究、调试、辅助功能和单人模式修改。不要使用它来绕过反作弊系统或干扰在线服务。
## 目录
- [为什么选择Cortex?](#为什么选择Cortex?)
- [亮点](#亮点)
- [渲染器支持](#渲染器支持)
- [需求](#需求)
- [构建](#构建)
- [外部主机](#外部主机)
- [加载Cortex](#加载Cortex)
- [验证连接](#验证连接)
- [快速入门教程](#快速入门教程)
- [后台捕获和输入](#后台捕获和输入)
- [带有表达式捕获的调试器](#带有表达式捕获的调试器)
- [模型上下文协议(MCP)端点](#模型上下文协议(MCP)端点)
- [网络钩子](#网络钩子)
- [会话导出](#会话导出)
- [配置](#配置)
- [API概述](#API概述)
- [持久项目](#持久项目)
- [操作日志和批次](#操作日志和批次)
- [架构](#架构)
- [安全模型](#安全模型)
- [已知限制](#已知限制)
- [依赖项](#依赖项)
- [贡献](#贡献)
- [适用于AI代理](#适用于AI代理)
- [许可证](#许可证)
## 为什么选择Cortex?
传统的游戏研究通常需要在内存扫描器、调试器、反汇编器、脚本工具和笔记之间进行切换。Cortex通过一个JSON接口将这些工作流程结合起来,同时将批量扫描排除在目标之外:
- 代理可以通過`GET /tools`或`GET /openapi.json`发现完整的API;
- 人类可以通过Dear ImGui叠加层跟踪活动;
- 命名地址、指针路径、冻结、结构和笔记在会话之间存活;
- 编写和修补由操作日志跟踪,可以回滚;
- 批量操作减少API往返次数并支持事务突变。
```text
AI 代理 / 脚本 / 开发工具
|
| HTTP + JSON + X-Cortex-Token
v
127.0.0.1:6970 127.0.0.1:6969
| |
Cortex 主机(外部) Cortex 代理(内部)
扫描、内存、映射 钩子和实时调试
| |
+------ 一个运行时工作区 ------+
```
## 亮点
| 领域 | 功能 |
|---|---|
| 内存 | 类型读取/写入、批次、填充、区域枚举、精确64位整数处理 |
| 扫描 | 外部精确/比较扫描、AOB模式、字符串、代码洞、交集、持久指针映射 |
| 逆向工程 | x86/x64反汇编、CFG、xrefs、vtables、PE头、推断结构、Ghidra桥 |
| 调试 | 断点、基于表达式的内存捕获、类似C的条件、触发跟踪、StackWalk64 +启发式回退、分页日志 |
| 运行时检测 | 跟踪补丁、重定位感知垫片、冻结、调用、页面/分配监视、目标重风 |
| 自动化 | **后台**键盘/鼠标注入(Win32 + DirectInput合成)、**后台**截图(任何渲染器)、输入序列、录制/回放、窗口控制 |
| 网络 | ws2_32 recv/send/WSARecv/WSASend拦截器,带环形缓冲区 |
| 地址 | 通用`module+RVA`解析器(ASLR-proof) |
| AI集成 | 原生**模型上下文协议**(JSON-RPC 2.0)端点、自动派生工具目录、`/session/export`存档 |
| 持久性 | 进程间地址、指针路径、笔记、冻结和命名结构 |
| 安全 | 仅限环回服务器(v4 + v6)、令牌身份验证、主机/源检查、JSON内容验证、突变日志 |
## 渲染器支持
Cortex在运行时选择可用的渲染器钩子。
| 后端 | 32位 | 64位 |
|---|:---:|:---:|
| Direct3D 8 | 是 | 否 |
| Direct3D 9 | 是 | 是 |
| Direct3D 10 | 是 | 是 |
| Direct3D 11 | 是 | 是 |
| Direct3D 12 | 否 | 是 |
| OpenGL | 是 | 是 |
| 原生Vulkan | 否 | 否 |
32位D3D8后端用于遗留标题。其他后端使用[kiero](https://github.com/Rebzzel/kiero)。D3D12仅限于x64,因为ImGui后端需要指针大小的GPU描述符句柄。
## 需求
- Windows 7 或更新版本;
- CMake 3.20 或更新版本;
- Ninja;
- MinGW-w64,带有与目标进程匹配的x86或x64编译器;
- 需要管理员权限时。
> [!IMPORTANT]
> 注入器和DLL的位数必须与目标进程匹配。x86构建不能注入到x64进程中,而x64构建不能注入到x86进程中。
## 构建
依赖项在`CMakeLists.txt`中固定,并使用CMake `FetchContent`填充。
### 32位
```powershell
cmake -S . -B build -G Ninja `
-DCMAKE_C_COMPILER=i686-w64-mingw32-gcc `
-DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++
cmake --build build --config Release
```
### 64位
```powershell
cmake -S . -B build_x64 -G Ninja `
-DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc `
-DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++
cmake --build build_x64 --config Release
```
每个构建都会生成:
- `cortex_core.dll` - 加载到目标进程的DLL;
- `injector.exe` - 命令行注入器;
- `cortex_host.exe` - 外部控制器和自污染扫描器。
在依赖项填充一次后,使用`-DCORTEX_OFFLINE=ON`配置,以防止CMake尝试网络访问。
### 测试
```powershell
ctest --test-dir build -C Release --output-on-failure
ctest --test-dir build_x64 -C Release --output-on-failure
```
回归套件还涵盖了拥有内存排除、重定位感知垫片、多实例结构推断、目标快照和重风。
## 外部主机
对于内存搜索,请优先使用外部主机。它的缓冲区存在于单独的进程中,因此永远不会出现在目标的扫描结果中。
```powershell
.\cortex_host.exe --process game.exe --port 6970
# 或
.\cortex_host.exe --pid 12344
```
主机写入`cortex_host.token`并公开`/health`、`/modules`、`/memory/regions`、`/memory/read`、`/memory/write`、`/scan/new`、`/scan/next`和`/scan/results/{id}`。使用注入的代理访问端口6969的渲染器钩子、断点、跟踪、原生调用、输入和截图。主机和代理可执行文件应与目标位数匹配,以实现完整的地址空间覆盖。
## 加载Cortex
选择一种加载方法。
### 选项1:命令行注入器
启动目标进程,然后运行:
```powershell
.\injector.exe <进程名或PID> [路径到cortex_core.dll]
```
示例:
```powershell
.\injector.exe game.exe
.\injector.exe 12344 .\cortex_core.dll
```
如果省略DLL路径,注入器将在`injector.exe`旁边查找`cortex_core.dll`。
### 选项2:ASI加载器
如果目标已经使用ASI加载器:
1. 重命名匹配的`cortex_core.dll`版本为`cortex.asi`;
2. 将其复制到游戏的ASI或`scripts`目录中;
3. 正常启动游戏。
## 验证连接
公共健康和发现端点不需要令牌:
```powershell
Invoke-RestMethod http://127.0.0.1:6969/health
Invoke-RestMethod http://127.0.0.1:6969/tools
```
所有其他端点都需要存储在DLL旁边的令牌:
```powershell
$token = (Get-Content .\cortex.token -Raw).Trim()
$headers = @{ "X-Cortex-Token" = $token }
Invoke-RestMethod `
-Uri http://127.0.0.1:6969/modules `
-Headers $headers
```
读取一个类型化值:
```powershell
$body = @{
address = "0x400000"
type = "u32"
} | ConvertTo-Json
Invoke-RestMethod `
-Method Post `
-Uri http://127.0.0.1:6969/memory/read `
-Headers $headers `
-ContentType "application/json" `
-Body $body
```
## 快速入门教程
使用捆绑的`test_target`二进制文件完成第一次命中遍历。它有已知的金丝雀值,您可以验证每个子系统端到端,无需游戏。
**1. 启动测试目标**
```powershell
.\test_target_x64.exe
```
它打开一个小蓝色窗口,并打印其PID +金丝雀值地址(`g_cortex_u32 = 0xDEADBEEF`、`g_health = 100`,帧计数器...)。
**2. 注入Cortex**
```powershell
.\injector_x64.exe test_target_x64.exe
```
**3. 读取令牌并确认健康**
```powershell
$token = (Get-Content .\cortex.token -Raw).Trim()
$h = @{ "X-Cortex-Token" = $token }
Invoke-RestMethod http://127.0.0.1:6969/health
```
**4. 通过`module+RVA`**读取值(存活ASLR/重启)
```powershell
$body = @{ address = "test_target_x64.exe+0x4000"; type = "u32" } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri http://127.0.0.1:6969/memory/read `
-Headers $h -ContentType "application/json" -Body $body
# -> { "value": 3735928559 } (0xDEADBEEF)
```
**5. 截取后台截图** (无需聚焦窗口)
```powershell
Invoke-WebRequest "http://127.0.0.1:6969/screenshot?mode=auto" `
-Headers $h -OutFile shot.png
```
**6. 发送后台输入序列**
```powershell
$seq = @{
mode = "os"
steps = @(
@{ type = "key_tap"; vk = 0x57; hold_ms = 50 }, # W
@{ type = "delay"; ms = 200 },
@{ type = "text"; text = "hello" }
)
} | ConvertTo-Json -Depth 5
Invoke-RestMethod -Method Post -Uri http://127.0.0.1:6969/input/sequence `
-Headers $h -ContentType "application/json" -Body $seq
```
**7. 设置一个捕获内存的断点**
```powershell
$bp = @{
address = "test_target_x64.exe+0x1234"
kind = "hw"
capture = @(
@{ name = "health"; expression = "[rcx+0x18]"; type = "i32" }
)
} | ConvertTo-Json -Depth 5
$r = Invoke-RestMethod -Method Post -Uri http://127.0.0.1:6969/debug/breakpoint `
-Headers $h -ContentType "application/json" -Body $bp
# 稍后:分页日志
Invoke-RestMethod "http://127.0.0.1:6969/debug/breakpoint/$($r.id)/log?limit=50" -Headers $h
```
**8. 导出完整会话存档**
```powershell
Invoke-RestMethod -Method Post http://127.0.0.1:6969/session/export -Headers $h
# 写入 cortex_sessions/session_<UTC>/session.json + screenshot.png
```
**9. 从MCP客户端驱动Cortex**
```powershell
$req = @{ jsonrpc="2.0"; id=1; method="tools/list" } | ConvertTo-Json
Invoke-RestMethod -Method Post http://127.0.0.1:6969/mcp `
-Headers $h -ContentType "application/json" -Body $req
```
## 后台捕获和输入
Cortex捕获和注入输入 **无需目标窗口聚焦**。此功能适用于任何渲染器(D3D8/9/10/11/12,OpenGL),甚至在最小化窗口上。
**截图** - `GET /screenshot?mode=<mode>`:
| 模式 | 行为 |
|---|---|
| `render` | 抓取钩定的后台缓冲区(最高保真度,需要活动渲染循环) |
| `window` | `PrintWindow(PW_RENDERFULLCONTENT)` - 在后台工作,任何渲染器 |
| `last` | 返回上一个缓存的帧(零成本,可能会过时) |
| `auto` | 尝试 `render` → `window` → `last`,头部报告源 |
响应包括一个`X-Cortex-Capture-Source`头部,以便调用者知道哪个路径提供了图像。
**输入** - 三种传输方式,根据目标选择合适的方式:
| 路由 | 传输方式 | 何时使用 |
|---|---|---|
| `POST /input/key`, `/input/mouse_*` | `PostMessage` | 后台,Win32消息驱动的游戏 |
| `POST /input/sequence` with `mode:"dinput"` | DirectInput vtable钩子 `GetDeviceState` | 直接读取DirectInput的游戏(较旧的标题) |
| `POST /input/sequence` with `mode:"game"` | `SendInput` | 前台,适用于所有游戏 |
**序列** 排队多步骤脚本(`key_tap`、`mouse_click`、`mouse_move`、`text`、`delay`)。轮询 `GET /input/sequence/{id}` 获取状态;使用 `DELETE /input/sequence/{id}` 取消。
**记录和回放** - `POST /input/record/start` 安装低级键盘和鼠标钩子在一个专用的泵线程上。 `POST /input/record/stop` 返回捕获的序列,准备好反馈到 `/input/sequence`。
**窗口控制** - `GET /window`, `POST /window/{focus,restore,minimize,move}`。
## 带有表达式捕获的调试器
每个断点都可以携带一个内存捕获列表,在每次命中时进行评估。表达式支持寄存器、整数文字、`+`/`-`和指针大小的解引用 `[]`,因此复杂布局可以内联解析:
```json
{
"address": "engine.dll+0x2A0F10",
"kind": "hw",
"capture": [
{ "name": "hp", "expression": "[[ecx+0x18]+0x4]", "type": "i32" },
{ "name": "name", "expression": "[ecx+0x40]", "type": "cstring", "size": 32 },
{ "name": "position", "expression": "ecx+0x100", "type": "bytes", "size": 12 }
]
}
```
类型:`bytes`,`cstring`,`u8/i8/u16/i16/u32/i32/u64/i64`,`float`,`double`.
命中日志是分页和非破坏性的 - 环形缓冲区报告`dropped_entries`和`total_hits`,因此代理永远不会错过活动,即使消费者很慢:
```powershell
GET /debug/breakpoint/{id}/log?since_seq=0&limit=200
# -> { entries, returned, next_seq, dropped_entries, total_hits }
```
**触发 → 自动跟踪** - 附加一个跟踪模板到断点 `{id}/trigger`,调试器将在每次命中时启动跟踪,可选地在当前函数返回时自动停止 (`stop_on_return`)。
栈行走通过 **EBP 链 → `StackWalk64`(带有 FPO)→ 可执行页面启发式扫描**,所以破碎/优化的前言仍然会产生调用栈。
## 模型上下文协议(MCP)端点
`POST /mcp` 使用 **JSON-RPC 2.0** 讲话,并将每个 Cortex 路由公开为键入的 MCP 工具。工具从相同的 `/tools` 清单中自动派生 - 不需要保持同步的第二个注册表。
支持的方法:
- `initialize` - 返回 `protocolVersion: "2024-11-05"`,功能,`serverInfo`。
- `tools/list` - 完整的工具目录,以 MCP 工具描述符和 `inputSchema` 表示。
- `tools/call` - 按名称调用工具;端点通过相同的 HTTP 服务器循环,因此路由处理程序保持行为的单一来源。
- `ping` - 存活。
- 批量(JSON 数组)请求受支持。
参数格式:
```json
{
"jsonrpc": "2.0", "id": 42, "method": "tools/call",
"params": {
"name": "memory_read",
"arguments": {
"address": "test_target_x64.exe+0x4000",
"type": "u32"
}
}
}
```
路径占位符( `/debug/breakpoint/{id}/log`)进入 `_path`,查询参数进入 `_query`:
```json
{
"name": "debug_breakpoint__id__log",
"arguments": {
"_path": { "id": "3" },
"_query": { "since_seq": "0", "limit": "50" }
}
}
```
MCP 端点仍然需要 `X-Cortex-Token`;单个令牌验证 REST 和 MCP 接口。
## 网络钩子
Cortex 拦截 `ws2_32` 上的 `recv`、`send`、`WSARecv` 和 `WSASend`,并在环形缓冲区中保留最近 512 个事件,带有 64 字节的十六进制预览:
```powershell
POST /network/capture { "enabled": true }
GET /network/events?limit=100
```
可用于观察与身份验证或遥测服务通信的单人游戏,或逆向工程本地 IPC。
## 会话导出
`POST /session/export` 将自包含存档写入 `<module-dir>/cortex_sessions/session_<UTC-timestamp>/`:
- `session.json` - 模块,断点(带有分页日志,捕获和每个地址以 `module+RVA` 表示),跟踪元数据,项目状态。
- `screenshot.png` - 通过 `mode=auto` 拍摄的快照。
存档可以直接重新加载和在运行之间进行差异比较,这使得错误报告和重现者实际上是可复制的。
## 配置
在DLL旁边创建一个可选的 `cortex.ini`:
```ini
port = 6969
toggle_key = 0x7B
log_console = true
api_token =
```
| 键 | 默认值 | 描述 |
|---|---:|---|
| `port` | `6969` | 本地HTTP端口 |
| `toggle_key` | `0x7B` | 叠加层热键;`0x7B`是F12 |
| `log_console` | `true` | 在初始化期间打开调试控制台 |
| `api_token` | 空 | 固定令牌;为空时,Cortex加载或创建`cortex.token` |
## API概述
## 持久项目
## 操作日志和批次
## 架构
## 安全模型
## 已知限制
## 依赖项
## 贡献
## 适用于AI代理
## 许可证
## API 概述
每条路由都使用 JSON,除非它返回二进制数据,如截图。
权威路由清单始终可从正在运行的 DLL 中获取:
```text
GET http://127.0.0.1:6969/tools
GET http://127.0.0.1:6969/openapi.json
```
| 领域 | 主要路由 |
|---|---|
| 发现 | `/status`, `/health`, `/tools`, `/openapi.json`, `/modules` |
| 内存 | `/memory/read`, `/memory/write`, `/memory/fill`, `/memory/regions`, `/memory/ownership` |
| 扫描 | `/scan/new`, `/scan/next`, `/scan/results/{id}`, `/scan/aob`, `/scan/strings`, `/scan/pointers`, `/scan/pointer_path`, `/scan/intersect`, `/scan/code_caves` |
| 反汇编和分析 | `/disasm`, `/analysis/functions`, `/analysis/cfg`, `/analysis/xrefs`, `/analysis/vtable`, `/analysis/structure`, `/analysis/pe_headers` |
| 调试器 | `/debug/breakpoint`, `/debug/paused`, `/debug/registers`, `/trace/*`, `/watch/page_access` |
| 监视 | `/watch`, `/watch/events`, `/watch/allocations`, `/watch/page_access` |
| 补丁 | `/patch/write`, `/patch/assemble`, `/patch/detour`, `/patch/trampoline`, `/patch/alloc_cave` |
| 持久项目 | `/project`, `/project/address`, `/project/pointer_path`, `/project/resolve/{name}`, `/project/note` |
| 自动化 | `/input/*` (按键、鼠标、序列、文本、记录), `/screenshot?mode=`, `/window/*`, `/prompt/*`, `/call/function`, `/freeze`, `/struct/*` |
| 逆向工程 | `/pointermap/*`, `/struct/infer`, `/ghidra/*`, `/snapshot/*`, `/dissect/*` |
| 网络 | `/network/capture`, `/network/events` |
| 协调 | `/batch/run`, `/events`, `/actions`, `/actions/rollback`, `/session/export` |
| MCP | `POST /mcp` (JSON-RPC 2.0: `initialize`, `tools/list`, `tools/call`, `ping`) |
### 扫描行为
内存扫描使用 `VirtualQuery` 枚举已提交的页面,并以 8 MiB 为单位读取它们。
大型读取失败后,会以 64 KiB 窗口重试,并且相邻块重叠,以确保值和模式不会在块边界处丢失。
注入扫描默认排除 Cortex 注册的模块、临时缓冲区、指针映射和代码洞。
仅在需要聚焦诊断时设置 `exclude_cortex=false`。
外部主机仍然是首选扫描器。
大型分配器竞技场被扫描而不是跳过。
全局 AOB 扫描涵盖已提交的可读图像、映射和私有区域;
提供 `module` 故意将扫描限制在可执行文件或 DLL 中。
## 持久项目
Cortex 在以下路径下为每个目标存储一个项目:
```text
cortex_projects/<ProcessName>.json
```
项目可以包含:
- 命名地址;
- 稳定的指针路径;
- 自由格式的研究笔记;
- 活动冻结;
- 命名结构定义。
项目文件被原子写入,并在 Cortex 初始化时恢复。
这允许代理或开发人员在每次会话后无需重新发现每个地址即可继续工作。
## 操作日志和批次
内存写入、补丁、冻结和其他跟踪的突变记录在操作日志中。使用:
```text
GET /actions
POST /actions/rollback
POST /actions/clear
```
`POST /batch/run` 可以在一个请求中执行多个操作。
事务批次拒绝不支持的不可逆突变,并在后续操作失败时回滚支持的写入。
## 架构
```text
cortex/
|-- CMakeLists.txt
|-- injector/
| `-- main.cpp 独立 DLL 注入器
|-- host/
| `-- main.cpp 外部控制器和扫描器
|-- core/
| |-- dllmain.cpp 初始化和关闭
| |-- config.cpp cortex.ini 解析器和默认值
| |-- log.cpp 调试控制台 + 旋转日志文件
| |-- api/ HTTP 服务器和路由域
| |-- memory/ 安全读取、写入和扫描
| |-- process/ 模块枚举
| |-- debugger/ 断点和执行控制
| |-- disasm/ Zydis 集成
| |-- symbols/ DbgHelp / PDB 符号解析
| |-- analysis/ CFG、xrefs、vtables、结构
| |-- dissect/ 推断结构布局
| |-- patch/ 补丁、汇编、detours、洞
| |-- pointermap/ 持久化跨会话指针路径
| |-- timeline/ 目标检查点和回溯
| |-- ghidra/ 运行时导入/导出桥
| |-- watch/ 数据、页面和分配监视
| |-- project/ 持久化每目标状态
| |-- action/ 突变日志和回滚
| |-- events/ 服务器发送事件流
| |-- hook/ 渲染器和输入钩子
| |-- overlay/ Dear ImGui UI
| |-- capture/ 截图(渲染钩子 + 回退)
| |-- prompt/ 人机交互提示队列
| |-- freeze/ 周期值强制
| |-- struct/ 命名运行时结构
| `-- call/ 保护的本地函数调用
|-- tests/
| `-- core_tests.cpp
`-- third_party/
```
## 安全模型
Cortex 有意将进程内存访问视为特权本地操作:
- 服务器仅监听 `127.0.0.1`;
- 每个非公共路由都需要 `X-Cortex-Token`;
- 令牌比较是恒定时间的;
- 非本地主机和来源值被拒绝;
- POST、PUT 和 PATCH 正文必须使用 `application/json`;
- 响应禁用缓存和 MIME 嗅探。
公共路由仅限于 `/status`、`/health`、`/tools` 和 `/openapi.json`。
## 已知限制
- 仅限 Windows;
- 注入器和 DLL 位数必须与目标匹配;
- 不支持原生 Vulkan 渲染;
- 跨重启的动态地址仍需要签名或指针路径;
- 补丁创建故意拒绝在重写的序言内部进行内部相对分支,而不是发出不安全的网关;
- 任意内存写入、补丁和本地调用都可能导致目标崩溃;
- 受保护或启用反作弊的进程可能会拒绝注入,并且超出了该项目的预期范围。
## 依赖
- [Dear ImGui](https://github.com/ocornut/imgui)
- [MinHook](https://github.com/TsudaKageyu/minhook)
- [cpp-httplib](https://github.com/yhirose/cpp-httplib)
- [nlohmann/json](https://github.com/nlohmann/json)
- [Zydis](https://github.com/zyantific/zydis)
- [stb](https://github.com/nothings/stb)
- [kiero](https://github.com/Rebzzel/kiero)
依赖修订版本在 `CMakeLists.txt` 中固定,以实现可复制的 x86 和 x64 构建。
## 贡献
添加端点时,请保持以下三个位置同步:
1. `core/api/routes_*.cpp` 中的实现;
2. `core/api/server.cpp` 中的注册;
3. `core/api/routes_status.cpp` 中的实时清单。
在提交更改之前,请为两个架构构建和测试。
## 适用于 AI 代理
如果您正在使用 LLM 或自动化代理驱动 Cortex,请参阅 [`agent/agents.md`](agent/agents.md) 以获取 API 假定的连接、身份验证和工作流约定。
## 许可证
在 [MIT License](LICENSE) 下发布。
连接信息
猜你喜欢
暂无推荐服务器