enkomio/shrun

GitHub: enkomio/shrun

一个用 Rust 编写的最小化 Windows PE 构建器,将原始 shellcode 封装为独立可执行文件以便于调试和分析。

Stars: 13 | Forks: 1

# Shellcode Runner 一个用 Rust 编写的最小化 Windows PE 构建器。它接收原始的 shellcode 文件(或十六进制字符串),并生成一个独立的 `.exe`,将 shellcode 封装在单个 RWX `.text` 节中——准备好加载到你喜欢的调试器中。 专为 shellcode 分析和调试设计。没有外部依赖,没有运行时,除了 `KERNEL32.VirtualAlloc` 之外没有任何导入——只有一个裸 PE 文件,你的字节从 `ImageBase + 0x1000` 开始。 ## 用法 ``` shrun.exe [32|64] ``` | 参数 | 描述 | |----------|-------------| | `input` | 原始 shellcode 二进制文件的路径,**或**十六进制编码的字符串 | | `32\|64` | 输出 PE 的位数。默认:`64` | ## 示例 ### 从二进制文件 ``` # 64-bit PE (默认) .\shrun.exe .\shellcode.bin # 32-bit PE .\shrun.exe .\shellcode.bin 32 ``` 输出: ``` [*] input: C:\Users\user\Desktop\shellcode.bin [*] mode: PE64 (64-bit) [*] payload: 42 bytes [*] output: C:\Users\user\Desktop\shellcode_sh.exe [*] shellcode: 0x0000000180001000 (= BASE_ADDRESS → rcx) [+] done — entry/stub: 0x000000018000102a ``` ### 从十六进制字符串 如果第一个参数不是已存在的文件,它将被解码为十六进制字符串并直接用作 shellcode payload。 ``` # x64: xor rax,rax / inc rax / ret .\shrun.exe 4831c048ffc0c3 64 # x86: xor eax,eax / inc eax / ret .\shrun.exe 31c040c3 32 # 接受 0x 前缀 .\shrun.exe 0x4831c048ffc0c3 ``` 输出: ``` [*] input: [*] mode: PE64 (64-bit) [*] payload: 7 bytes [*] output: C:\Users\user\Desktop\shellcode_sh.exe [*] shellcode: 0x0000000180001000 (= BASE_ADDRESS → rcx) [+] done — entry/stub: 0x0000000180001007 ``` ## 构建 ``` # 64-bit 主机 (Windows 上默认) cargo build --release --target x86_64-pc-windows-msvc # 32-bit 目标 cargo build --release --target i686-pc-windows-msvc ``` ## 功能 - 从头构建最小化的 PE32 或 PE32+ 可执行文件(硬编码头部,无需链接器) - 接受原始二进制文件**或**十六进制字符串作为输入 - 同时支持 **32 位** (PE32 / x86) 和 **64 位** (PE32+ / x86-64) 输出 - 禁用 ASLR — `DllCharacteristics = 0x0000`(无 `DYNAMIC_BASE`) - 禁用 DEP — 无 `NX_COMPAT`,`.text` 节标记为 `RWX` (`0xE0000020`) - Shellcode 放置在 `ImageBase + RVA 0x1000` 处(节起始处,始终页对齐) - 在 shellcode 之后附加一个小型的**位置无关 stub** 并将其设置为入口点;它会将 `ImageBase + 0x1000`(shellcode 地址)作为第一个参数传递,然后跳转到 shellcode - 从 `KERNEL32.DLL` 导入三个函数(导入表位于 `.rdata` 中):`VirtualAlloc`、`LoadLibraryA`、`GetProcAddress` ### PE 布局 ``` File offset 0x000 PE headers (padded to 0x200) File offset 0x200 .text RVA 0x1000 — RWX [shellcode bytes] [stub 17–18 bytes] ← AddressOfEntryPoint File offset 0x200+ .rdata — import table (VirtualAlloc, LoadLibraryA, GetProcAddress) ``` ### Stub 行为 | 步骤 | x64 | x86 | |------|-----|-----| | 恢复 shellcode 地址 | `CALL $+5` / `POP RCX` / `SUB RCX, imm32` | `CALL $+5` / `POP EAX` / `SUB EAX, imm32` | | 作为第一个参数传递 | 值位于 **RCX** | **PUSH EAX** | | 转移控制权 | `JMP rel32` → shellcode | `JMP rel32` → shellcode | 减法常数在构建时计算为 `shellcode_len + 5`,因此无论 payload 大小如何,结果始终为 `ImageBase + RVA_TEXT`。
标签:DNS 反向解析, PE构建, Rust, Shellcode执行器, 可视化界面, 恶意代码调试, 网络流量审计, 通知系统