use registry::{Hive, Security};
use std::convert::TryInto;
use utfx::U16CString;
use winapi::um::processthreadsapi::GetCurrentProcess;
use winapi::um::winnt::TOKEN_ADJUST_PRIVILEGES;
use winapi::{
shared::ntdef::LUID,
um::{
processthreadsapi::OpenProcessToken,
securitybaseapi::AdjustTokenPrivileges,
winbase::LookupPrivilegeValueW,
winnt::LUID_AND_ATTRIBUTES,
winnt::{HANDLE, SE_BACKUP_NAME, SE_PRIVILEGE_ENABLED, SE_RESTORE_NAME, TOKEN_PRIVILEGES},
},
};
fn main() -> Result<(), std::io::Error> {
let mut token = std::ptr::null_mut();
let r = unsafe { OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &mut token) };
if r == 0 {
return Err(std::io::Error::last_os_error());
}
set_privilege(token, SE_RESTORE_NAME)?;
set_privilege(token, SE_BACKUP_NAME)?;
let hive_key = Hive::load_file(
r"C:\Users\Default\NTUSER.DAT",
Security::Read | Security::Write,
)
.unwrap();
let keys: Vec<_> = hive_key.keys().map(|k| k.unwrap().to_string()).collect();
println!("{:?}", keys);
Ok(())
}
fn set_privilege(handle: HANDLE, name: &str) -> Result<(), std::io::Error> {
let mut luid: LUID = LUID {
LowPart: 0,
HighPart: 0,
};
let name: U16CString = name.try_into().unwrap();
let r = unsafe { LookupPrivilegeValueW(std::ptr::null(), name.as_ptr(), &mut luid) };
if r == 0 {
return Err(std::io::Error::last_os_error());
}
let mut privilege = TOKEN_PRIVILEGES {
PrivilegeCount: 1,
Privileges: [LUID_AND_ATTRIBUTES {
Luid: luid,
Attributes: SE_PRIVILEGE_ENABLED,
}],
};
let r = unsafe {
AdjustTokenPrivileges(
handle,
false as i32,
&mut privilege,
std::mem::size_of::<TOKEN_PRIVILEGES>() as u32,
std::ptr::null_mut(),
std::ptr::null_mut(),
)
};
if r == 0 {
return Err(std::io::Error::last_os_error());
}
Ok(())
}