Skip to content

Commit de75b81

Browse files
committed
feat nodejs inject mem
1 parent c036b4f commit de75b81

2 files changed

Lines changed: 72 additions & 43 deletions

File tree

rasp/librasp/src/manager.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ impl RASPManager {
528528
.exe_path
529529
.clone()
530530
.ok_or(anyhow!("process exe path not found: {}", pid))?;
531-
let inspect_port = get_inspect_port(pid);
531+
let inspect_port = get_inspect_port(&process_info);
532532
if inspect_port != 0 {
533533
match nodejs_attach(pid, &environ, &process_exe_file, Some(inspect_port)) {
534534
Ok(result) => {Ok(result)}

rasp/librasp/src/nodejs.rs

Lines changed: 71 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ use anyhow::{anyhow, Result};
99
use log::*;
1010
use regex::Regex;
1111
use wait_timeout::ChildExt;
12+
use std::fs::File;
13+
use std::io::BufReader;
14+
use std::io::BufRead;
1215

1316
const NODEJS_INSPECT_PORT_MIN:u16 = 19230;
1417
const NODEJS_INSPECT_PORT_MAX:u16 = 19235;
@@ -42,23 +45,30 @@ fn parse_port_from_address(address: &str) -> Option<u16> {
4245
}
4346

4447
pub fn get_process_listening_port(pid: i32) -> u16 {
45-
let tcp_path = format!("/proc/{}/net/tcp", pid);
4648

4749
// frist get ipv4 listen port
48-
if let Ok(content) = std::fs::read_to_string(tcp_path) {
49-
50-
for line in content.lines().skip(1) {
51-
let parts: Vec<&str> = line.split_whitespace().collect();
52-
if parts.len() >= 3 {
53-
let local_address = parts[1];
54-
let status = parts[3];
50+
let file_path = format!("/proc/{}/net/tcp", pid);
51+
let file = match File::open(&file_path) {
52+
Ok(f) => f,
53+
Err(_) => return 0,
54+
};
55+
let reader = BufReader::new(file);
56+
57+
for line in reader.lines().skip(1) {
58+
let line = match line {
59+
Ok(l) => l,
60+
Err(_) => return 0,
61+
};
62+
let parts: Vec<&str> = line.split_whitespace().collect();
63+
if parts.len() >= 4 {
64+
let local_address = parts[1];
5565

56-
if status == "0A" {
57-
if let Some(port) = parse_port_from_address(local_address) {
58-
if (NODEJS_INSPECT_PORT_MIN..= NODEJS_INSPECT_PORT_MAX).contains(&port) {
59-
info!("Found IPv4 listen port {} for pid {}", port, pid);
60-
return port;
61-
}
66+
let status = parts[3];
67+
if status == "0A" {
68+
if let Some(port) = parse_port_from_address(local_address) {
69+
if (NODEJS_INSPECT_PORT_MIN..= NODEJS_INSPECT_PORT_MAX).contains(&port) {
70+
info!("Found IPv4 listen port {} for pid {}", port, pid);
71+
return port;
6272
}
6373
}
6474
}
@@ -67,20 +77,26 @@ pub fn get_process_listening_port(pid: i32) -> u16 {
6777

6878
// get ipv6 listen port
6979
let tcp6_path = format!("/proc/{}/net/tcp6", pid);
70-
if let Ok(content) = std::fs::read_to_string(tcp6_path) {
71-
72-
for line in content.lines().skip(1) {
73-
let parts: Vec<&str> = line.split_whitespace().collect();
74-
if parts.len() >= 3 {
75-
let local_address = parts[1];
76-
let status = parts[3];
80+
let file = match File::open(&tcp6_path) {
81+
Ok(f) => f,
82+
Err(_) => return 0,
83+
};
84+
let reader = BufReader::new(file);
85+
for line in reader.lines().skip(1) {
86+
let line = match line {
87+
Ok(l) => l,
88+
Err(_) => return 0,
89+
};
90+
let parts: Vec<&str> = line.split_whitespace().collect();
91+
if parts.len() >= 4 {
92+
let local_address = parts[1];
93+
let status = parts[3];
7794

78-
if status == "0A" {
79-
if let Some(port) = parse_port_from_address(local_address) {
80-
if (16680..= NODEJS_INSPECT_PORT_MAX).contains(&port) {
81-
info!("Found IPv6 listen port {} for pid {}", port, pid);
82-
return port;
83-
}
95+
if status == "0A" {
96+
if let Some(port) = parse_port_from_address(local_address) {
97+
if (NODEJS_INSPECT_PORT_MIN..= NODEJS_INSPECT_PORT_MAX).contains(&port) {
98+
info!("Found IPv6 listen port {} for pid {}", port, pid);
99+
return port;
84100
}
85101
}
86102
}
@@ -91,31 +107,44 @@ pub fn get_process_listening_port(pid: i32) -> u16 {
91107
}
92108

93109

94-
pub fn get_inspect_port(pid: i32) -> u16 {
110+
pub fn get_inspect_port(process_info: &ProcessInfo) -> u16 {
111+
let process = match procfs::process::Process::new(process_info.pid) {
112+
Ok(p) => p,
113+
Err(_) => {return 0;}
114+
};
115+
95116
let re = regex::Regex::new(r"inspect(?:-brk|-port)?=(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3}:)?(\d+)")
96117
.expect("Invalid regex pattern");
97118

98-
let cmdline = std::fs::read_to_string(format!("/proc/{}/cmdline", pid)).unwrap_or_default();
99-
119+
120+
let cmdline = process_info.cmdline.clone().unwrap_or(String::new());
121+
100122
if let Some(captures) = re.captures(&cmdline) {
101123
if let Some(port) = captures.get(1) {
102124
info!("inspect port: {}", port.as_str());
103125
return port.as_str().parse().unwrap_or(0);
104126
}
105127
}
106-
107-
let environ = std::fs::read_to_string(format!("/proc/{}/environ", pid)).unwrap_or_default();
108-
let options = environ.split('\0').find(|element| element.starts_with("NODE_OPTIONS="));
109-
110-
if let Some(options) = options {
111-
if let Some(captures) = re.captures(options) {
112-
if let Some(port) = captures.get(1) {
113-
info!("inspect port: {}", port.as_str());
114-
return port.as_str().parse().unwrap_or(0);
128+
let env = match process.environ() {
129+
Ok(env) => env,
130+
Err(_) => {return 0;}
131+
};
132+
133+
match env.get(&std::ffi::OsString::from("NODE_OPTIONS")) {
134+
Some(v) => match v.clone().into_string() {
135+
Ok(s) => {
136+
if let Some(captures) = re.captures(s.as_str()) {
137+
if let Some(port) = captures.get(1) {
138+
info!("inspect port: {}", port.as_str());
139+
return port.as_str().parse().unwrap_or(0);
140+
}
141+
}
115142
}
116-
}
117-
}
118-
143+
Err(_) => {}
144+
},
145+
None => {}
146+
};
147+
119148
0
120149
}
121150

0 commit comments

Comments
 (0)