Skip to content

Commit

Permalink
Add process module to talpid-windows
Browse files Browse the repository at this point in the history
  • Loading branch information
dlon committed Oct 20, 2023
1 parent 155795f commit 4c51384
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 203 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions mullvad-daemon/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ ctrlc = "3.0"
windows-service = "0.6.0"
winapi = { version = "0.3", features = ["winnt", "excpt"] }
dirs = "5.0.1"
talpid-windows = { path = "../talpid-windows" }

[target.'cfg(windows)'.dependencies.windows-sys]
workspace = true
Expand Down
96 changes: 6 additions & 90 deletions mullvad-daemon/src/exception_logging/win.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
use mullvad_paths::log_dir;
use std::{
borrow::Cow,
ffi::{c_char, c_void, CStr},
ffi::c_void,
fmt::Write,
fs, io, mem,
fs, io,
os::windows::io::AsRawHandle,
path::{Path, PathBuf},
ptr,
};
use talpid_types::ErrorExt;
use talpid_windows::process::{ModuleEntry, ProcessSnapshot};
use winapi::{
um::winnt::{CONTEXT_CONTROL, CONTEXT_INTEGER, CONTEXT_SEGMENTS},
vc::excpt::EXCEPTION_EXECUTE_HANDLER,
};
use windows_sys::Win32::{
Foundation::{CloseHandle, BOOL, ERROR_NO_MORE_FILES, HANDLE, INVALID_HANDLE_VALUE},
Foundation::{BOOL, HANDLE},
System::{
Diagnostics::{
Debug::{SetUnhandledExceptionFilter, CONTEXT, EXCEPTION_POINTERS, EXCEPTION_RECORD},
ToolHelp::{
CreateToolhelp32Snapshot, Module32First, Module32Next, MODULEENTRY32,
TH32CS_SNAPMODULE,
},
ToolHelp::TH32CS_SNAPMODULE,
},
Threading::{GetCurrentProcess, GetCurrentProcessId, GetCurrentThreadId},
},
Expand Down Expand Up @@ -291,7 +289,7 @@ fn get_context_info(context: &CONTEXT) -> String {
}

/// Return module info for the current process and given memory address.
fn find_address_module(address: *mut c_void) -> io::Result<Option<ModuleInfo>> {
fn find_address_module(address: *mut c_void) -> io::Result<Option<ModuleEntry>> {
let snap = ProcessSnapshot::new(TH32CS_SNAPMODULE, 0)?;

for module in snap.modules() {
Expand All @@ -306,85 +304,3 @@ fn find_address_module(address: *mut c_void) -> io::Result<Option<ModuleInfo>> {

Ok(None)
}

struct ModuleInfo {
name: String,
base_address: *const u8,
size: usize,
}

struct ProcessSnapshot {
handle: HANDLE,
}

impl ProcessSnapshot {
fn new(flags: u32, process_id: u32) -> io::Result<ProcessSnapshot> {
let snap = unsafe { CreateToolhelp32Snapshot(flags, process_id) };

if snap == INVALID_HANDLE_VALUE {
Err(io::Error::last_os_error())
} else {
Ok(ProcessSnapshot { handle: snap })
}
}

fn handle(&self) -> HANDLE {
self.handle
}

fn modules(&self) -> ProcessSnapshotModules<'_> {
let mut entry: MODULEENTRY32 = unsafe { mem::zeroed() };
entry.dwSize = mem::size_of::<MODULEENTRY32>() as u32;

ProcessSnapshotModules {
snapshot: self,
iter_started: false,
temp_entry: entry,
}
}
}

impl Drop for ProcessSnapshot {
fn drop(&mut self) {
unsafe {
CloseHandle(self.handle);
}
}
}

struct ProcessSnapshotModules<'a> {
snapshot: &'a ProcessSnapshot,
iter_started: bool,
temp_entry: MODULEENTRY32,
}

impl Iterator for ProcessSnapshotModules<'_> {
type Item = io::Result<ModuleInfo>;

fn next(&mut self) -> Option<io::Result<ModuleInfo>> {
if self.iter_started {
if unsafe { Module32Next(self.snapshot.handle(), &mut self.temp_entry) } == 0 {
let last_error = io::Error::last_os_error();

return if last_error.raw_os_error().unwrap() as u32 == ERROR_NO_MORE_FILES {
None
} else {
Some(Err(last_error))
};
}
} else {
if unsafe { Module32First(self.snapshot.handle(), &mut self.temp_entry) } == 0 {
return Some(Err(io::Error::last_os_error()));
}
self.iter_started = true;
}

let cstr_ref = &self.temp_entry.szModule[0];
let cstr = unsafe { CStr::from_ptr(cstr_ref as *const u8 as *const c_char) };
Some(Ok(ModuleInfo {
name: cstr.to_string_lossy().into_owned(),
base_address: self.temp_entry.modBaseAddr,
size: self.temp_entry.modBaseSize as usize,
}))
}
}
6 changes: 3 additions & 3 deletions talpid-core/src/split_tunnel/windows/driver.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::windows::{
get_device_path, get_process_creation_time, get_process_device_path, open_process,
ProcessAccess, ProcessSnapshot,
ProcessAccess,
};
use bitflags::bitflags;
use memoffset::offset_of;
Expand All @@ -22,7 +22,7 @@ use std::{
time::Duration,
};
use talpid_types::ErrorExt;
use talpid_windows::{io::Overlapped, sync::Event};
use talpid_windows::{io::Overlapped, process::ProcessSnapshot, sync::Event};
use windows_sys::Win32::{
Foundation::{
ERROR_ACCESS_DENIED, ERROR_FILE_NOT_FOUND, ERROR_INVALID_PARAMETER, ERROR_IO_PENDING,
Expand Down Expand Up @@ -486,7 +486,7 @@ fn build_process_tree() -> io::Result<Vec<ProcessInfo>> {
let mut process_info = HashMap::new();

let snap = ProcessSnapshot::new(TH32CS_SNAPPROCESS, 0)?;
for entry in snap.entries() {
for entry in snap.processes() {
let entry = entry?;

let process = match open_process(ProcessAccess::QueryLimitedInformation, false, entry.pid) {
Expand Down
89 changes: 1 addition & 88 deletions talpid-core/src/split_tunnel/windows/windows.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// TODO: The snapshot code could be combined with the mostly-identical code in
// the windows_exception_logging module.

use std::{
ffi::{OsStr, OsString},
fs, io, iter, mem,
Expand All @@ -12,99 +9,15 @@ use std::{
ptr,
};
use windows_sys::Win32::{
Foundation::{
CloseHandle, ERROR_INSUFFICIENT_BUFFER, ERROR_NO_MORE_FILES, FILETIME, HANDLE,
INVALID_HANDLE_VALUE,
},
Foundation::{CloseHandle, ERROR_INSUFFICIENT_BUFFER, FILETIME, HANDLE},
Storage::FileSystem::{GetFinalPathNameByHandleW, QueryDosDeviceW},
System::{
Diagnostics::ToolHelp::{
CreateToolhelp32Snapshot, Process32FirstW, Process32NextW, PROCESSENTRY32W,
},
ProcessStatus::GetProcessImageFileNameW,
Threading::{GetProcessTimes, OpenProcess, PROCESS_QUERY_LIMITED_INFORMATION},
WindowsProgramming::VOLUME_NAME_NT,
},
};

pub struct ProcessSnapshot {
handle: HANDLE,
}

impl ProcessSnapshot {
pub fn new(flags: u32, process_id: u32) -> io::Result<ProcessSnapshot> {
let snap = unsafe { CreateToolhelp32Snapshot(flags, process_id) };

if snap == INVALID_HANDLE_VALUE {
Err(io::Error::last_os_error())
} else {
Ok(ProcessSnapshot { handle: snap })
}
}

pub fn handle(&self) -> HANDLE {
self.handle
}

pub fn entries(&self) -> ProcessSnapshotEntries<'_> {
let mut entry: PROCESSENTRY32W = unsafe { mem::zeroed() };
entry.dwSize = mem::size_of::<PROCESSENTRY32W>() as u32;

ProcessSnapshotEntries {
snapshot: self,
iter_started: false,
temp_entry: entry,
}
}
}

impl Drop for ProcessSnapshot {
fn drop(&mut self) {
unsafe {
CloseHandle(self.handle);
}
}
}

pub struct ProcessEntry {
pub pid: u32,
pub parent_pid: u32,
}

pub struct ProcessSnapshotEntries<'a> {
snapshot: &'a ProcessSnapshot,
iter_started: bool,
temp_entry: PROCESSENTRY32W,
}

impl Iterator for ProcessSnapshotEntries<'_> {
type Item = io::Result<ProcessEntry>;

fn next(&mut self) -> Option<io::Result<ProcessEntry>> {
if self.iter_started {
if unsafe { Process32NextW(self.snapshot.handle(), &mut self.temp_entry) } == 0 {
let last_error = io::Error::last_os_error();

return if last_error.raw_os_error().unwrap() as u32 == ERROR_NO_MORE_FILES {
None
} else {
Some(Err(last_error))
};
}
} else {
if unsafe { Process32FirstW(self.snapshot.handle(), &mut self.temp_entry) } == 0 {
return Some(Err(io::Error::last_os_error()));
}
self.iter_started = true;
}

Some(Ok(ProcessEntry {
pid: self.temp_entry.th32ProcessID,
parent_pid: self.temp_entry.th32ParentProcessID,
}))
}
}

/// Obtains a device path without resolving links or mount points.
pub fn get_device_path<T: AsRef<Path>>(path: T) -> Result<OsString, io::Error> {
// Preferentially, use GetFinalPathNameByHandleW. If the file does not exist
Expand Down
3 changes: 3 additions & 0 deletions talpid-windows/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ pub mod net;

/// Synchronization
pub mod sync;

/// Processes
pub mod process;
Loading

0 comments on commit 4c51384

Please sign in to comment.