german-one/ntenvblock
GitHub: german-one/ntenvblock
一个用于直接只读访问 Windows NT 进程结构(TEB/PEB/进程参数)选定字段的 C header-only 库,无需链接 ntdll 或依赖 Win32 封装。
Stars: 0 | Forks: 0
# ntenvblock
__用于读取 Windows NT 进程结构中选定字段的 C header-only 库。__
## _概述_
__ntenvblock__ 提供对 Windows NT 线程环境块 (TEB)、进程环境块 (PEB) 和 RTL_USER_PROCESS_PARAMETERS 中选定字段的只读访问。
### 预期用例
本库专为 __底层诊断、分析器、调试器和 runtime 基础设施__ 设计,它们需要直接访问 NT 进程元数据,而无需链接 ntdll 或依赖 Win32 wrapper。
## _要求_
- Windows 7 或更高版本
- C11 编译器
- ``
- ``
## _兼容性说明_
本库依赖于未公开的 Windows 内部结构布局。
当前版本中包含的偏移量已在发布时针对受支持的 NT 系列系统进行了验证。
未来的 Windows 版本可能会更改这些布局,并需要更新偏移量定义。如果 Microsoft 更改了内部布局,访问器可能会返回错误的数据;除非结构收缩,否则它们不会导致崩溃。
## _API 参考_
### 访问器
对于每个支持的字段,本库都提供了一个生成的访问器。
模式:
```
get_(const *ptr)
```
示例:
```
DWORD get_last_error(const TEB *ptr)
```
前置条件:
- `ptr` 必须引用有效的 `` 对象。它不需要与底层 NT 结构的自然对齐方式保持一致。
#### 可用访问器
##### 域 TEB
| 访问器 | 返回类型 | 描述 |
| --- | --- | --- |
| get_last_error | DWORD | GetLastError() 的来源 (TEB::LastErrorValue) |
| get_process_id | DWORD | 进程 ID (收窄后的 CLIENT_ID::UniqueProcess);被 GetCurrentProcessId() 使用 |
| get_thread_id | DWORD | 线程 ID (收窄后的 CLIENT_ID::UniqueThread);被 GetCurrentThreadId() 使用 |
##### 域 PEB
| 访问器 | 返回类型 | 描述 |
| --- | --- | --- |
| get_peb_lock | LPCRITICAL_SECTION | 指向 PEB 内部同步对象的指针,历史上 NTDLL 使用它来保护可变 PEB 和进程参数数据的部分内容;此锁的存在和同步语义未被公开记录,并且可能因 Windows 版本而异 |
| get_process_heap | HANDLE | 调用进程默认堆的 HANDLE;GetProcessHeap() 的来源 |
##### 域 RTL_USER_PROCESS_PARAMETERS
| 访问器 | 返回类型 | 描述 |
| --- | --- | --- |
| get_cmd_ln_buf | const WCHAR * | 命令行 (UNICODE_STRING::Buffer);以 null 结尾,因为这与 GetCommandLineW() 返回的指针相同 |
| get_cmd_ln_size | USHORT | 命令行长度(以字节为单位),不包括终止符 (UNICODE_STRING::Length) |
| get_cur_dir_buf | const WCHAR * | 当前目录 (UNICODE_STRING::Buffer) |
| get_cur_dir_size | USHORT | 当前目录长度(以字节为单位),不包括终止符 (UNICODE_STRING::Length) |
| get_env_buf | const WCHAR * | 环境块:以 null 结尾的环境字符串的扁平序列,以一个额外的 null 字符终止 |
| get_env_size | SIZE_T | 环境块大小(以字节为单位),包括最后的终止符;(需要 NT 6.1 或更高版本) |
| get_img_path_buf | const WCHAR * | 可执行文件的完整路径 (UNICODE_STRING::Buffer);类似于将 hModule 设置为 NULL 时的 GetModuleFileNameW() |
| get_img_path_size | USHORT | 可执行文件路径长度(以字节为单位),不包括终止符 (UNICODE_STRING::Length) |
| get_std_err | HANDLE | 标准错误设备的 HANDLE;与 GetStdHandle(STD_ERROR_HANDLE) 相同 |
| get_std_in | HANDLE | 标准输入设备的 HANDLE;与 GetStdHandle(STD_INPUT_HANDLE) 相同 |
| get_std_out | HANDLE | 标准输出设备的 HANDLE;与 GetStdHandle(STD_OUTPUT_HANDLE) 相同 |
### 函数
此外,还提供了三个函数来获取域指针:
| 函数 | 描述 |
| --- | --- |
| `NTENVBLOCK_API const TEB *get_current_teb(void)` | 获取当前的线程环境块。 |
| `NTENVBLOCK_API const PEB *get_current_peb(const TEB *pTeb)` | 获取当前的进程环境块。 |
| `NTENVBLOCK_API const RTL_USER_PROCESS_PARAMETERS *get_current_process_parameters(const PEB *pPeb)` | 获取当前的进程参数。 |
## _安装_
将 `ntenvblock.h` 复制到您的项目中,并在需要的地方包含它:
```
#include "ntenvblock.h"
```
## _示例_
```
#include
#include "ntenvblock.h"
int main(void)
{
const TEB *const pTeb = get_current_teb();
const PEB *const pPeb = get_current_peb(pTeb);
const RTL_USER_PROCESS_PARAMETERS *const pUpp = get_current_process_parameters(pPeb);
wprintf_s(L"* Command Line *\n%s\n", get_cmd_ln_buf(pUpp));
return 0;
}
```
标签:Header-Only, PEB/TEB, Windows底层, 内核结构, 客户端加密, 端点可见性