1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#![allow(missing_docs)]

use crate::{
    types::{ListEntry, UnicodeString},
    FaitheError,
};
use windows::{
    core::PCWSTR,
    Win32::{
        Foundation::{HANDLE, HWND},
        System::{Console, LibraryLoader::GetModuleHandleA, Threading},
        UI::WindowsAndMessaging::{MessageBoxW, MESSAGEBOX_STYLE},
    },
};

/// Returns a handle to the current process.
pub const fn get_current_process() -> HANDLE {
    HANDLE(usize::MAX as isize)
}

pub fn get_current_module() -> HANDLE {
    unsafe { HANDLE(GetModuleHandleA(None).unwrap_or_default().0) }
}

/// Returns the id of the current process.
pub fn get_current_process_id() -> u32 {
    unsafe { Threading::GetCurrentProcessId() }
}

/// Allocates console windows ig.
pub fn alloc_console() -> crate::Result<()> {
    if unsafe { Console::AllocConsole().0 == 0 } {
        Err(FaitheError::last_error())
    } else {
        Ok(())
    }
}

/// Frees console.
pub fn free_console() -> crate::Result<()> {
    if unsafe { Console::FreeConsole().0 == 0 } {
        Err(FaitheError::last_error())
    } else {
        Ok(())
    }
}

/// Creates new message box.
pub fn message_box(
    hwnd: Option<HWND>,
    text: impl AsRef<str>,
    caption: impl AsRef<str>,
    style: MESSAGEBOX_STYLE,
) -> crate::Result<()> {
    if unsafe {
        MessageBoxW(
            hwnd,
            PCWSTR(
                format!("{}\x00", text.as_ref())
                    .encode_utf16()
                    .collect::<Vec<_>>()
                    .as_mut_ptr(),
            ),
            PCWSTR(
                format!("{}\x00", caption.as_ref())
                    .encode_utf16()
                    .collect::<Vec<_>>()
                    .as_mut_ptr(),
            ),
            style,
        )
        .0 == 0
    } {
        Err(FaitheError::last_error())
    } else {
        Ok(())
    }
}

/// Process Environmental Block.
#[repr(C)]
pub struct Peb {
    _pad0x2: [u8; 0x2],
    /// If process is being debugged.
    pub being_debugged: bool,
    pad0x10: [u8; 0xD],
    /// Base address of loaded image.
    pub image_base_address: *const (),
    /// Ldr data
    pub ldr_data: &'static PebLdrData,
}

#[repr(C)]
pub struct LdrDataTableEntry {
    _pad0x10: [u8; 0x10],
    pub in_memory_order_links: ListEntry,
    _pad0x30: [u8; 0x10],
    pub dll_base: *mut (),
    pub entry_point: *mut (),
    pub image_size: u32,
    pub full_dll_name: UnicodeString,
    pub base_dll_name: UnicodeString,
}

#[repr(C)]
pub struct PebLdrData {
    pub len: u32,
    _pad0x20: [u8; 0x1C],
    pub in_memory_order_links: ListEntry,
}

/// Returns an address of PEB(Process Environmental Block).
#[cfg(feature = "nightly")]
#[inline(always)]
pub fn get_peb() -> &'static Peb {
    use super::get_teb;

    get_teb().process_environmental_block
}