#[cfg(target_arch = "x86_64")]
pub const IS_64BIT: bool = true;
#[cfg(target_arch = "x86")]
pub const IS_64BIT: bool = false;
pub const PTR_SIZE: usize = core::mem::size_of::<usize>();
#[cfg(target_arch = "x86_64")]
pub mod segment {
use core::arch::asm;
#[inline(always)]
pub unsafe fn read_gs_qword(offset: u32) -> u64 {
let value: u64;
unsafe {
asm!(
"mov {}, gs:[{:e}]",
out(reg) value,
in(reg) offset,
options(nostack, preserves_flags, readonly)
);
}
value
}
#[inline(always)]
pub unsafe fn read_gs_dword(offset: u32) -> u32 {
let value: u32;
unsafe {
asm!(
"mov {:e}, gs:[{:e}]",
out(reg) value,
in(reg) offset,
options(nostack, preserves_flags, readonly)
);
}
value
}
#[inline(always)]
pub unsafe fn get_teb() -> *mut u8 {
unsafe { read_gs_qword(0x30) as *mut u8 }
}
#[inline(always)]
pub unsafe fn get_peb() -> *mut u8 {
unsafe { read_gs_qword(0x60) as *mut u8 }
}
#[inline(always)]
pub unsafe fn get_current_tid() -> u32 {
unsafe { read_gs_qword(0x48) as u32 }
}
#[inline(always)]
pub unsafe fn get_current_pid() -> u32 {
unsafe { read_gs_qword(0x40) as u32 }
}
}
#[cfg(target_arch = "x86")]
pub mod segment {
use core::arch::asm;
#[inline(always)]
pub unsafe fn read_fs_dword(offset: u32) -> u32 {
let value: u32;
unsafe {
asm!(
"mov {:e}, fs:[{:e}]",
out(reg) value,
in(reg) offset,
options(nostack, preserves_flags, readonly)
);
}
value
}
#[inline(always)]
pub unsafe fn get_teb() -> *mut u8 {
unsafe { read_fs_dword(0x18) as *mut u8 }
}
#[inline(always)]
pub unsafe fn get_peb() -> *mut u8 {
unsafe { read_fs_dword(0x30) as *mut u8 }
}
#[inline(always)]
pub unsafe fn get_current_tid() -> u32 {
unsafe { read_fs_dword(0x24) }
}
#[inline(always)]
pub unsafe fn get_current_pid() -> u32 {
unsafe { read_fs_dword(0x20) }
}
}
#[cfg(target_arch = "x86_64")]
pub type NativePtr = u64;
#[cfg(target_arch = "x86")]
pub type NativePtr = u32;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_teb_not_null() {
let teb = unsafe { segment::get_teb() };
assert!(!teb.is_null());
}
#[test]
fn test_get_peb_not_null() {
let peb = unsafe { segment::get_peb() };
assert!(!peb.is_null());
}
#[test]
fn test_pid_tid_nonzero() {
let pid = unsafe { segment::get_current_pid() };
let tid = unsafe { segment::get_current_tid() };
assert!(pid > 0);
assert!(tid > 0);
}
}