allow for spaces in path
This commit is contained in:
parent
4ec5535f77
commit
63b65952ba
1 changed files with 54 additions and 1 deletions
55
src/live.rs
55
src/live.rs
|
|
@ -20,6 +20,23 @@ pub struct LiveProcess {
|
|||
executable: Vec<(u64, u64)>, // r-x regions — where valid code/vtable-slot targets must land
|
||||
}
|
||||
|
||||
/// The pathname field of a `/proc/<pid>/maps` line — everything after the fifth whitespace-delimited field.
|
||||
/// It must NOT be read as "whatever follows the last whitespace": a mapped path may contain spaces (Steam's
|
||||
/// default install directory is `.../common/Counter-Strike Global Offensive/...`), and taking the last field
|
||||
/// yields a fragment that fails the leading-`/` test, so the library is silently dropped from the map and
|
||||
/// every lookup for it then reports it as not mapped. Empty for an anonymous mapping.
|
||||
fn maps_path(line: &str) -> &str {
|
||||
let mut rest = line;
|
||||
for _ in 0..5 {
|
||||
rest = rest.trim_start();
|
||||
match rest.find(char::is_whitespace) {
|
||||
Some(i) => rest = &rest[i..],
|
||||
None => return "",
|
||||
}
|
||||
}
|
||||
rest.trim_start()
|
||||
}
|
||||
|
||||
impl LiveProcess {
|
||||
pub fn attach(pid: u32) -> Result<Self> {
|
||||
let maps = std::fs::read_to_string(format!("/proc/{pid}/maps"))
|
||||
|
|
@ -35,7 +52,7 @@ impl LiveProcess {
|
|||
None => continue,
|
||||
};
|
||||
let perms = rest.split(' ').next().unwrap_or("");
|
||||
let path = line.rsplit_once(char::is_whitespace).map_or("", |(_, p)| p);
|
||||
let path = maps_path(line);
|
||||
let Some((start, end)) = range.split_once('-').and_then(|(a, b)| {
|
||||
Some((
|
||||
u64::from_str_radix(a, 16).ok()?,
|
||||
|
|
@ -308,3 +325,39 @@ pub fn call_remote(pid: i32, func: u64, args: &[u64]) -> Result<CallResult> {
|
|||
fn errno() -> i32 {
|
||||
unsafe { *libc::__errno_location() }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::maps_path;
|
||||
|
||||
#[test]
|
||||
fn maps_path_survives_spaces_in_the_mapped_path() {
|
||||
// Steam's default install directory contains spaces; taking the last whitespace-delimited field
|
||||
// yields "Offensive/..." which fails the leading-`/` test, so the library silently vanishes from
|
||||
// the map and the live oracle reports it as not mapped.
|
||||
let spaced = "7f1a2b000000-7f1a2c000000 r-xp 00000000 08:01 12345 \
|
||||
/home/cs2/.steam/SteamApps/common/Counter-Strike Global Offensive/game/csgo/bin/linuxsteamrt64/libserver.so";
|
||||
assert_eq!(
|
||||
maps_path(spaced),
|
||||
"/home/cs2/.steam/SteamApps/common/Counter-Strike Global Offensive/game/csgo/bin/linuxsteamrt64/libserver.so"
|
||||
);
|
||||
|
||||
// The no-space case must be unchanged.
|
||||
let plain = "7f1a2b000000-7f1a2c000000 r-xp 00000000 08:01 12345 /home/snake/game/csgo/bin/linuxsteamrt64/libserver.so";
|
||||
assert_eq!(
|
||||
maps_path(plain),
|
||||
"/home/snake/game/csgo/bin/linuxsteamrt64/libserver.so"
|
||||
);
|
||||
|
||||
// An anonymous mapping has no pathname — it must read as EMPTY, since that is what marks the
|
||||
// writable heap regions the instance scan walks.
|
||||
assert_eq!(
|
||||
maps_path("24557800000-24597800000 rw-p 00000000 00:00 0 "),
|
||||
""
|
||||
);
|
||||
assert_eq!(
|
||||
maps_path("29618000-29639000 rw-p 00000000 00:00 0 [heap]"),
|
||||
"[heap]"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue