Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recommendations read directly from the hard disk #126

Open
Web-Coke opened this issue Apr 28, 2024 · 0 comments
Open

Recommendations read directly from the hard disk #126

Web-Coke opened this issue Apr 28, 2024 · 0 comments

Comments

@Web-Coke
Copy link

Web-Coke commented Apr 28, 2024

Ugly implementation

Read

New dependencies:

[dependencies.hex]
version = "0.4.3"

Code:

\\ diskname = "\\\\.\\C:";
pub fn from_disk(diskname: impl AsRef<Path>) -> Result<Self> {
    let f = diskname.as_ref();
    let n = [f.to_str().unwrap(), "\\$MFT"].join("");
    let mft_fh = File::open(f).map_err(|e| Error::failed_to_open_file(f, e))?;
    let size = metadata(Path::new(&n))?.len();
    let mut data = BufReader::with_capacity(4096, mft_fh);
    let mut signature = [0u8; 0x38];
    let offset: u64;
    data.read_exact(&mut signature)?;
    if signature[0..4] == [235u8, 82u8, 144u8, 78u8] {
        signature.reverse();
        let sector_bytes = u64::from_str_radix(&hex::encode(&signature[42..43]), 16).unwrap();
        let sector_sizes = u64::from_str_radix(&hex::encode(&signature[43..45]), 16).unwrap();
        let start_number = u64::from_str_radix(&hex::encode(&signature[0..8]), 16).unwrap();
        //offset: The MFT is at the starting position of the hard disk
        offset = sector_bytes * sector_sizes * start_number;
        data.seek(SeekFrom::Start(offset))?;
        data.stream_position()?;
    } else {
        offset = 0;
        println!("Disk signature error")
    }
    Self::from_read_seek(data, size, offset)
}

Privileges

New dependencies:

[dependencies.windows]
version = "0.56.0"

Code:

use crate::err::{Error, Result};

use std::{mem::size_of_val, ptr};
use windows::{
    core::*,
    Win32::{Foundation::*, Security::*, System::Threading::*},
};

fn lookup_priv_id(name: PCSTR) -> Result<LUID> {
    let mut priv_id = LUID::default();
    match unsafe { LookupPrivilegeValueA(PCSTR::null(), name, &mut priv_id) } {
        Ok(_) => return Ok(priv_id),
        Err(_) => {
            return Err(Error::LookupPrivilegeValueFailed {
                value: unsafe { GetLastError() },
            });
        }
    };
}

pub fn get_privileges() -> Result<bool> {
    let my_token = {
        let mut token = HANDLE::default();
        match unsafe {
            OpenProcessToken(
                GetCurrentProcess(),
                TOKEN_ADJUST_PRIVILEGES,
                ptr::from_mut(&mut token),
            )
        } {
            Ok(_) => token,
            Err(_) => {
                return Err(Error::GetSelfProcessTokenFailed {
                    value: unsafe { GetLastError() },
                });
            }
        }
    };

    let mut backup_token_privs = TOKEN_PRIVILEGES {
        PrivilegeCount: 1,
        Privileges: [LUID_AND_ATTRIBUTES {
            Luid: lookup_priv_id(s!("SeBackupPrivilege"))?,
            Attributes: SE_PRIVILEGE_ENABLED,
        }],
    };
    let mut restore_token_privs = TOKEN_PRIVILEGES {
        PrivilegeCount: 1,
        Privileges: [LUID_AND_ATTRIBUTES {
            Luid: lookup_priv_id(s!("SeRestorePrivilege"))?,
            Attributes: SE_PRIVILEGE_ENABLED,
        }],
    };
    let mut success;
    let mut value;
    success = match unsafe {
        AdjustTokenPrivileges(
            my_token,
            false,
            Some(ptr::from_mut(&mut backup_token_privs)),
            size_of_val(&backup_token_privs) as u32,
            Some(ptr::null_mut()),
            Some(ptr::null_mut()),
        )
    } {
        Ok(_) => 1,
        Err(_) => 0,
    };
    value = unsafe { GetLastError() };
    if success == 0 {
        return Err(Error::AdjustTokenPrivilegesFailed { value });
    } else if value != ERROR_SUCCESS {
        return Ok(false);
    }

    success = match unsafe {
        AdjustTokenPrivileges(
            my_token,
            false,
            Some(ptr::from_mut(&mut restore_token_privs)),
            size_of_val(&restore_token_privs) as u32,
            Some(ptr::null_mut()),
            Some(ptr::null_mut()),
        )
    } {
        Ok(_) => 1,
        Err(_) => 0,
    };
    value = unsafe { GetLastError() };
    if success == 0 {
        return Err(Error::AdjustTokenPrivilegesFailed {
            value: unsafe { GetLastError() },
        });
    } else if value != ERROR_SUCCESS {
        return Ok(false);
    }
    Ok(true)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant