Skip to content

Envars listing addition + Macos process filtering enhanced.#7

Open
forensicxlab wants to merge 4 commits intomemflow:mainfrom
forensicxlab:main
Open

Envars listing addition + Macos process filtering enhanced.#7
forensicxlab wants to merge 4 commits intomemflow:mainfrom
forensicxlab:main

Conversation

@forensicxlab
Copy link
Copy Markdown

@forensicxlab forensicxlab commented Feb 27, 2026

This PR implements the process environment APIs (envar_list_callback, environment_block_address, envar_list_from_address) across all native backends and aligns behavior between platforms.

Windows: Envars are collected via sysinfo (Process::environ()) and parsed.
Linux: Envars are collected from /proc/<pid>/environ and parsed.
MacOs: Envars are collected by calling sysctl(KERN_PROCARGS2) and parsed.

It is linked to memflow PR and memflow-rawmem PR and memflow-win32

To build this PR for testing (Linux/MacOs/Windows)

cd /TEST/PATH/
git clone https://github.com/forensicxlab/memflow-native.git
git clone https://github.com/forensicxlab/memflow.git
cd memflow-native

Uncomment the following lines in Cargo.toml

memflow = { version = "0.2", features = ["plugins", "goblin"] } <- Comment
#memflow = { path = "../memflow/memflow" } <- Uncomment

Testing on MacOs/Linux

Module listing (Now working on latest MacOS)

cd /TEST/PATH/memflow
MEMFLOW_PLUGIN_PATH=/TEST/PATH/memflow-native/target/debug \
cargo run --example module_list -- --os native --process module_list

Envars

cd /TEST/PATH/memflow
MEMFLOW_PLUGIN_PATH=FULL/PATH/TO/memflow-native/target/debug \
cargo run --example envars_list -- --os native --process envars_list --envar PATH

Testing on windows 11 latest (PowerShell)

Envars

cd /TEST/PATH/memflow
cmd /c "set \"MEMFLOW_PLUGIN_PATH=FULL\PATH\TO\memflow-native\target\release\" && cd /d FULL\PATH\TO\memflow\memflow && cargo run --example envars_list -- -o native -p explorer.exe -e PATH"

Fixes / enhancements

  • Fixed pidinfo call to use the target PID correctly (pidinfo(pid, 0)), instead of mixing caller/target args.
  • Reworked process arg parsing into reusable helpers (read_procargs2 / parse_procargs2) and used that for consistent path/command_line extraction.
  • Removed fixed shared scratch buffer from MacOs; buffer size now follows KERN_ARGMAX.
  • Decoupled process selection from task-port acquisition: MacProcess::try_new no longer hard-fails if task_for_pid is denied; it creates a process with deferred port acquisition.

For module enumeration I added a small improvement to get more results: kept dyld-based module enumeration as primary path which is working well. But we can also perform a fallback to region-based enumeration (PROC_PIDREGIONPATHINFO) when dyld/task-port path fails. This worked well for process protected like GUI processes (Finder, Dock, loginwindow), where dyld/task-port path is unavailable.

First contribution to this project, happy to follow your guidance on the implementation / things to correct.

@forensicxlab forensicxlab changed the title Envars listing addition. Envars listing addition + Macos process filtering enhanced. Feb 27, 2026
Copy link
Copy Markdown
Member

@ko1N ko1N left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! I'm not too sure about the newly introduced dependency. I think using raw OS apis gives us more control over how we handle things.

Comment thread src/windows/process.rs
})
}

fn process_exists(&self) -> bool {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should introduce a new crate here. using NtQueryInformationProcess is totally fine and does not require a new dependency.

Comment thread src/windows/process.rs

fn collect_envars(&self) -> Result<Vec<EnvVarInfo>> {
let pid = Pid::from_u32(self.info.pid);
let mut system = System::new_with_specifics(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be able to do this with plain windows apis as well? This would give us much more control here.

Comment thread src/windows/process.rs
memflow::os::util::module_section_list_callback(&mut self.virt_mem, info, callback)
}

fn envar_list_callback(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be possible that we emit a feature flag based on the memflow plugin abi version. This we could check at compile time via #cfg[...] and allow the plugin to work (without this feature) with the current stable plugin abi version.

@ko1N
Copy link
Copy Markdown
Member

ko1N commented Apr 24, 2026

I added 8b2a617 to main. With this change you should be able to use cfg attrs to gate the new functions behind specific features, so we can build the plugin for multiple memflow versions.

You should be able to use it like so:

#[cfg(memflow_plugin_api = "2")]
fn envar_list_callback(
...

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

Successfully merging this pull request may close these issues.

2 participants