JustasMasiulis/lazy_importer

GitHub: JustasMasiulis/lazy_importer

一个仅头文件的C++库,通过在运行时手动解析DLL导出表来调用函数,从而避免在可执行文件中留下导入痕迹,常用于提高逆向工程难度。

Stars: 1911 | Forks: 235

# lazy importer [![](https://img.shields.io/badge/version-2.1.0-green.svg)]() 一个简单易用的仅头文件 (header only) 库,旨在让逆向工程师的日子更难过。 ## 小示例 ``` LI_FN(OutputDebugStringA)("hello world"); LI_FN(VirtualProtect).in(LI_MODULE("kernel32.dll").cached()); ``` [编译第一行时的 IDA 输出](#example-output) ## 功能特性 - 不会在内存中留下任何字符串。 - 不分配任何内存。 - 可以轻松内联。 - 不会在可执行文件中留下任何导入。 - 生成极小的汇编代码。 - 非缓存函数不会在数据段中留下任何内容。 - 每次编译时哈希值都会随机化,以击败基本的哈希数据库攻击。 ## 文档 - `LI_FN(function_pointer) -> lazy_function` - `LI_FN_DEF(function_type) -> lazy_function` - `LI_MODULE(module_name) -> lazy_module` - `safe` 表示当函数无法成功完成任务时,将返回 0,而不是表现出未定义的行为。 - `cached` 表示结果仅在第一次调用时计算,随后被重用。 - `forwarded` 表示将正确解析导出转发。 #### **`lazy_module`**
函数 safe cached
尝试查找给定的模块并返回其地址
get<T = void*>() -> T :x: :x:
safe<T = void*>() -> T :white_check_mark: :x:
cached<T = void*>() -> T :x: :white_check_mark:
safe_cached<T = void*>() -> T :white_check_mark: :white_check_mark:
尝试使用给定的 LDR_DATA_TABLE_ENTRY 指针查找给定的模块
in<T = void*, Ldr>(Ldr ldr_entry) -> T :white_check_mark: :x:
in_cached<T = void*, Ldr>(Ldr ldr_entry) -> T :white_check_mark: :white_check_mark:
#### **`lazy_function`**
函数 safe cached forwarded
使用给定的参数调用已解析的导出函数
operator()(...) -> result_of<F, ...> :x: :x: :x:
尝试在所有已加载的模块中解析导出并返回函数地址
get<T = F>() -> T :x: :x: :x:
safe<T = F>() -> T :white_check_mark: :x: :x:
cached<T = F>() -> T :x: :white_check_mark: :x:
safe_cached<T = F>() -> T :white_check_mark: :white_check_mark: :x:
forwarded<T = F>() -> T :x: :x: :white_check_mark:
forwarded_safe<T = F>() -> T :white_check_mark: :x: :white_check_mark:
forwarded_cached<T = F>() -> T :x: :white_check_mark: :white_check_mark:
forwarded_safe_cached<T = F>() -> T :white_check_mark: :white_check_mark: :white_check_mark:
尝试在给定的模块中解析导出并返回函数地址
in<T = F, A>(A module_address) -> T :x: :x: :x:
in_safe<T = F, A>(A module_address) -> T :white_check_mark: :x: :x:
in_cached<T = F, A>(A module_address) -> T :x: :white_check_mark: :x:
in_safe_cached<T = F, A>(A module_address) -> T :white_check_mark: :white_check_mark: :x:
尝试在 ntdll 中解析导出并返回函数地址
nt<T = F>() -> T :x: :x: :x:
nt_safe<T = F>() -> T :white_check_mark: :x: :x:
nt_cached<T = F>() -> T :x: :white_check_mark: :x:
nt_safe_cached<T = F>() -> T :white_check_mark: :white_check_mark: :x:
#### 额外配置 | `#define` | 效果 | | ----------------------------------------- | --------------------------------------------------------------------------------------- | | `LAZY_IMPORTER_NO_FORCEINLINE` | 禁用强制内联 | | `LAZY_IMPORTER_CASE_INSENSITIVE` | 启用不区分大小写的比较。解析转发导出时可能需要此项。 | | `LAZY_IMPORTER_CACHE_OPERATOR_PARENS` | 在 lazy_function 的 `operator()` 中使用 `cached()` 代替 `get()` | | `LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS` | 在 `get()` 中使用 `forwarded()`。警告:不适用于 `nt()` 和 `in()`。 | | `LAZY_IMPORTER_HARDENED_MODULE_CHECKS` | 向模块枚举添加额外的健全性检查。 | | `LAZY_IMPORTER_NO_CPP_FORWARD` | 移除对 `` C++ 头文件的依赖。 | ## 示例输出 ``` for ( i = *(_QWORD **)(*(_QWORD *)(__readgsqword(0x60u) + 24) + 16i64); ; i = (_QWORD *)*i ) { v1 = i[6]; v2 = *(unsigned int *)(*(signed int *)(v1 + 60) + v1 + 136); v3 = (_DWORD *)(v2 + v1); if ( v2 + v1 != v1 ) { LODWORD(v4) = v3[6]; if ( (_DWORD)v4 ) break; } LABEL_8: ; } while ( 1 ) { v4 = (unsigned int)(v4 - 1); v5 = -2128831035; v6 = (char *)(v1 + *(unsigned int *)((unsigned int)v3[8] + 4 * v4 + v1)); v7 = *v6; v8 = (signed __int64)(v6 + 1); if ( v7 ) { do { ++v8; v5 = 16777619 * (v5 ^ v7); v7 = *(_BYTE *)(v8 - 1); } while ( v7 ); if ( v5 == -973690651 ) break; } if ( !(_DWORD)v4 ) goto LABEL_8; } ((void (__fastcall *)(const char *))(v1 + *(unsigned int *)(v1 + (unsigned int)v3[7] + 4i64 * *(unsigned __int16 *)(v1 + (unsigned int)v3[9] + 2 * v4))))("hello world"); ``` ## 支持过本项目的人员 我想感谢那些联系我并捐款支持我及我的项目的人们 * [@DefCon42](https://github.com/DefCon42) * [@Mecanik](https://github.com/Mecanik)
标签:API 哈希, C++, DNS 反向解析, Hook 防护, Obfuscation, PEB 遍历, Red Team, Windows 内核, XML 请求, 中高交互蜜罐, 代码混淆, 免杀技术, 动态链接库导入, 反逆向工程, 头文件库, 字符串加密, 安全开发, 恶意软件开发, 数据擦除, 暴力破解检测, 游戏安全, 私有化部署, 端点可见性, 系统底层编程, 防御规避, 隐蔽加载