最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

rust - How to convert a u32 pid to windows-rs HANDLE - Stack Overflow

programmeradmin0浏览0评论

I'm trying to make the NtOpenProcess syscall in rust using the windows-rs crate. I've got the following code but cannot figure out how to convert a u32 pid to a HANDLE type, which is needed for the struct.

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
        );
    }

    // ...
}

When compiling I get the following errors:

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

So the question is; how to I convert this to valid code?

Edit: Using the ntapi crate it does seem to be possible to obtain a valid CLIENT_ID using a u32 PID. However, I would really like to use a single package for all windows interaction (the windows-rs one, as this one is maintained by Microsoft).

use ntapi::ntapi_base::CLIENT_ID;

let cid: CLIENT_ID = CLIENT_ID {
        UniqueProcess: pid as _,
        UniqueThread: 0 as _
};

I'm trying to make the NtOpenProcess syscall in rust using the windows-rs crate. I've got the following code but cannot figure out how to convert a u32 pid to a HANDLE type, which is needed for the struct.

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
        );
    }

    // ...
}

When compiling I get the following errors:

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

So the question is; how to I convert this to valid code?

Edit: Using the ntapi crate it does seem to be possible to obtain a valid CLIENT_ID using a u32 PID. However, I would really like to use a single package for all windows interaction (the windows-rs one, as this one is maintained by Microsoft).

use ntapi::ntapi_base::CLIENT_ID;

let cid: CLIENT_ID = CLIENT_ID {
        UniqueProcess: pid as _,
        UniqueThread: 0 as _
};
Share Improve this question edited Nov 20, 2024 at 8:34 Tom Stock asked Nov 19, 2024 at 17:07 Tom StockTom Stock 1,2982 gold badges15 silver badges29 bronze badges 5
  • how to get process handle from process id? – kmdreko Commented Nov 19, 2024 at 17:15
  • 2 The truth of the matter is that PIDs are useless in isolation. Wherever you got the PID from change it to return a process HANDLE instead. – IInspectable Commented Nov 19, 2024 at 17:19
  • Do you have a suggestion on how to obtain a HANDLE? Currently I'm retrieving the PID by creating a snapshot with CreateToolhelp32Snapshot and iterating over the snapshot handle with Process32Next function, filtering on the process name. This does not seem to have any way of getting the HANDLE of the process. The goal is not to use the OpenProcess winapi function, and instead use the NtOpenProcess syscall. – Tom Stock Commented Nov 20, 2024 at 8:30
  • 1 I'm curious, why do you want to avoid OpenProcess()? – Anton Tykhyy Commented Nov 20, 2024 at 9:11
  • To get both familiar with the winapi and the ntapi :) – Tom Stock Commented Nov 20, 2024 at 9:23
Add a comment  | 

2 Answers 2

Reset to default 1

You are getting type mismatches because windows::Win32::System::WindowsProgramming::CLIENT_ID is auto-generated from winternl.h, an oddball include file in Windows SDK that should not be used to work with ntdll-level APIs like NtOpenProcess() that are not part of Windows API. If you use NtOpenProcess(), you need to use corresponding struct definitions. If you don't want to pull in the whole ntapi crate, just define your own struct CLIENT_ID. Since you're invoking NtOpenProcess() with a "soft" syscall macro anyway, it should not make any difference in terms of compatibility, portability etc.

PS: a bit of wording clarification: a PID and a HANDLE are completely different things and cannot be 'converted' to each other. HANDLE is a userspace handle to the kernel process object and a PID is a property of said object. You get the PID by handle with GetProcessId(), and you get a handle by creating a new process or opening an existing process, whether with OpenProcess() or NtOpenProcess().

The answer from Anton Tykhyy works splendidly; though in the meantime I have found another way to solve this problem, by casting to a c_void type as shown below:

let cid: CLIENT_ID = CLIENT_ID {
    UniqueProcess: HANDLE(pid as *mut core::ffi::c_void),
    UniqueThread: HANDLE(0 as *mut core::ffi::c_void)
};

发布评论

评论列表(0)

  1. 暂无评论