如何将 u32 pid 转换为 windows-rs HANDLE

问题描述 投票:0回答:1

我正在尝试使用

NtOpenProcess
板条箱在 Rust 中进行
windows-rs
系统调用。我有以下代码,但无法弄清楚如何将
u32
pid 转换为
HANDLE
类型,这是结构所需的。

use windows::Wdk::Foundation::{
    OBJECT_ATTRIBUTES,
};
use windows::Win32::Foundation::{
    HANDLE,
};
use windows::Win32::System::WindowsProgramming::{
    CLIENT_ID,
};
use windows::Win32::System::Threading::{
    PROCESS_ALL_ACCESS,
};

fn some_func() {
    // ...

    let pid: u32 = 1402; // Obtained somewhere else (not relevant to the question how)
    let mut handle: HANDLE = HANDLE::default();
    let oa = OBJECT_ATTRIBUTES::default();
    let cid: CLIENT_ID = CLIENT_ID {
            UniqueProcess: pid,
            UniqueThread: 0
        };
    unsafe {
        // This part is out of scope for the question; assume this macro will work
        syscall!(
            "NtOpenProcess",
            &mut handle,
            PROCESS_ALL_ACCESS,
            &oa,
            &cid
        );
    }

    // ...
}

编译时出现以下错误:

error[E0308]: mismatched types
  --> src/main.rs:67:28
   |
67 |             UniqueProcess: pid,
   |                            ^^^ expected `HANDLE`, found `u32`

error[E0308]: mismatched types
  --> src/main.rs:68:27
   |
68 |             UniqueThread: 0
   |                           ^ expected `HANDLE`, found integer

所以问题是;如何将其转换为有效的代码?

编辑: 使用

ntapi
板条箱似乎确实可以使用
CLIENT_ID
PID 获得有效的
u32
。但是,我真的很想对所有 Windows 交互使用单个包(
windows-rs
包,因为这个包是由 Microsoft 维护的)。

use ntapi::ntapi_base::CLIENT_ID;

let cid: CLIENT_ID = CLIENT_ID {
        UniqueProcess: pid as _,
        UniqueThread: 0 as _
};
rust ntdll windows-rs
1个回答
0
投票

您会遇到类型不匹配的情况,因为

windows::Win32::System::WindowsProgramming::CLIENT_ID
是从 Winternl.h 自动生成的,winternl.h 是 Windows SDK 中的一个奇怪的包含文件,不应该用于与 ntdll 级 API(例如
NtOpenProcess()
)一起使用,这些 API 属于 Windows API。如果使用
NtOpenProcess()
,则需要使用相应的结构体定义。如果您不想引入整个
ntapi
箱子,只需定义您自己的
struct CLIENT_ID
即可。由于无论如何您都使用“软”系统调用宏调用
NtOpenProcess()
,因此它在兼容性、可移植性等方面不应该产生任何差异。

PS:一些措辞澄清:PID 和

HANDLE
是完全不同的东西,不能相互“转换”。
HANDLE
是内核进程对象的用户空间句柄,PID 是该对象的属性。您可以使用
GetProcessId()
通过句柄获取 PID,并且可以通过创建新进程或打开现有进程来获取句柄,无论是使用
OpenProcess()
还是
NtOpenProcess()

© www.soinside.com 2019 - 2024. All rights reserved.