i can't seem to make a function that gets the current users SID, only using the ntapi crate (nt functions only), and im hoping to have something functional. May someone please help me get this? thank you.
also, this function hasn't been implemented using just the winapi crate yet, maybe that will be a good start, and to go from there
What have you tried, and how does it fail? Can you show us the code of your best attempt so far, since we can iterate on that to help you fix it and understand why it didn't work.
as for nt functions the i believe NtQueryInformationToken, NtOpenThreadToken, NtOpenProcessToken may be in use, in conclusion, i need the users SID represented as a rust string
I'm curious: do you have a non-suspicious reason to want to use the undocumented internal ntapi rather than the public API? 90% of the time FrobleWidget() is just forwarding to NtFrobleWidget() anyway.
Only time I've seen people wanting to use that is because there's some special ability not exposed in the public API or to avoid (presumably bad) virus scanners.
[package]
name = "cusid"
version = "0.1.0"
edition = "2021"
[dependencies]
grob = "0.1.3"
[target.'cfg(windows)'.dependencies.windows]
version = "0.48"
features = [
"Win32_Foundation",
"Win32_Security",
"Win32_System_Threading",
]
main.rs
use grob::{RvIsError, winapi_small_binary};
use windows::Win32::Foundation::HANDLE;
use windows::Win32::Security::{GetTokenInformation, SID, TokenUser, TOKEN_QUERY, TOKEN_USER};
use windows::Win32::System::Threading::{GetCurrentProcess, OpenProcessToken};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let h = unsafe { GetCurrentProcess() };
println!("h = {:?}", h);
let mut h_token: HANDLE = Default::default();
let rv = unsafe { OpenProcessToken(h, TOKEN_QUERY, &mut h_token) };
println!("rv = {:?}", rv);
println!("h_token = {:?}", h_token);
let _gti = winapi_small_binary(
|argument| {
let rv = unsafe {
GetTokenInformation(
h_token,
TokenUser,
Some(argument.pointer()),
*argument.size(),
argument.size(),
)
};
RvIsError::new(rv)
},
|frozen_buffer| {
if let Some(fbp) = frozen_buffer.pointer() {
let tup = fbp as *const TOKEN_USER;
let attributes = unsafe{(*tup).User.Attributes};
println!("attributes = {}", attributes);
let psid = unsafe{(*tup).User.Sid.0} as *const SID;
println!("psid = {:?}", psid);
let revision = unsafe{(*psid).Revision};
println!("revision = {:?}", revision);
let identifier_authority = unsafe{(*psid).IdentifierAuthority};
println!("identifier_authority = {:?}", identifier_authority);
let sub_authority_count = unsafe{(*psid).SubAuthorityCount};
println!("sub_authority_count = {:?}", sub_authority_count);
let mut sub_authority = unsafe{(*psid).SubAuthority.as_ptr()};
for _ in 0..sub_authority_count {
println!("sub_authority = {:?}", unsafe{*sub_authority});
sub_authority = unsafe{sub_authority.add(1)};
}
}
// The SID could be converted to a string then returned from this closure making it
// available to the rest of the program.
Ok(())
},
)?;
Ok(())
}