Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 34 additions & 49 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ windows = { version = "0.54", features = [
libc = "0.2"

# Scripting integration
pyo3 = { version = "0.20", features = ["extension-module"] }
pyo3 = { version = "0.29", features = ["extension-module"] }

# UI/IPC
tauri = { version = "1.5", features = ["api-all"] }
44 changes: 25 additions & 19 deletions bindings/python/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Python bindings for Inspectra
#![allow(non_local_definitions)]

use pyo3::prelude::*;
use pyo3::types::PyList;
use inspectra_core;
use pyo3::types::{PyList, PyModule};

/// Process information exposed to Python
#[pyclass]
Expand Down Expand Up @@ -31,43 +31,49 @@ impl ProcessManager {
}

/// List all processes
fn list_processes(&self, py: Python) -> PyResult<PyObject> {
fn list_processes(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let processes = self
.manager
.list_processes()
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?;

let list = PyList::empty_bound(py);
let list = PyList::empty(py);
for proc in processes {
let py_proc = Py::new(py, ProcessInfo {
pid: proc.pid,
name: proc.name,
path: proc.path.unwrap_or_default(),
})?;
let py_proc = Py::new(
py,
ProcessInfo {
pid: proc.pid,
name: proc.name,
path: proc.path,
},
)?;
list.append(py_proc)?;
}

Ok(list.into())
Ok(list.into_any().unbind())
}

/// Find processes by name
fn find_by_name(&self, py: Python, name: &str) -> PyResult<PyObject> {
fn find_by_name(&self, py: Python<'_>, name: &str) -> PyResult<Py<PyAny>> {
let processes = self
.manager
.find_by_name(name)
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?;

let list = PyList::empty_bound(py);
let list = PyList::empty(py);
for proc in processes {
let py_proc = Py::new(py, ProcessInfo {
pid: proc.pid,
name: proc.name,
path: proc.path.unwrap_or_default(),
})?;
let py_proc = Py::new(
py,
ProcessInfo {
pid: proc.pid,
name: proc.name,
path: proc.path,
},
)?;
list.append(py_proc)?;
}

Ok(list.into())
Ok(list.into_any().unbind())
}
}

Expand Down Expand Up @@ -100,7 +106,7 @@ impl Scanner {

/// Initialize the Inspectra Python module
#[pymodule]
fn inspectra(_py: Python, m: &PyModule) -> PyResult<()> {
fn inspectra(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<ProcessManager>()?;
m.add_class::<ProcessInfo>()?;
m.add_class::<Scanner>()?;
Expand Down
9 changes: 2 additions & 7 deletions core/examples/list_processes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
sorted_processes.sort_by(|a, b| a.name.cmp(&b.name));

// Display
println!("{:<10} {:<30} {}", "PID", "Name", "Path");
println!("{:<10} {:<30} Path", "PID", "Name");
println!("{}", "=".repeat(80));

for proc in sorted_processes.iter().take(20) {
println!(
"{:<10} {:<30} {}",
proc.pid,
proc.name,
proc.path
);
println!("{:<10} {:<30} {}", proc.pid, proc.name, proc.path);
}

println!("\nTotal: {} processes", sorted_processes.len());
Expand Down
23 changes: 15 additions & 8 deletions core/examples/memory_scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
eprintln!("No process found with name: {}", input);
return Ok(());
}
println!("Found {} processes, using first: {} (PID: {})",
procs.len(), procs[0].name, procs[0].pid);
println!(
"Found {} processes, using first: {} (PID: {})",
procs.len(),
procs[0].name,
procs[0].pid
);
manager.attach(procs[0].pid)?
};

Expand All @@ -40,8 +44,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mem = memory::create_memory(handle.as_ref())?;

// Configure scanner
let mut config = ScanConfig::default();
config.data_type = DataType::I32;
let config = ScanConfig {
data_type: DataType::I32,
..Default::default()
};

let mut scanner = Scanner::new(mem, config);

Expand All @@ -60,11 +66,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

if let Ok(value) = value_input.parse::<i32>() {
println!("Scanning for value: {}", value);

let results = scanner.scan(&value.to_le_bytes())?;


let bytes = value.to_le_bytes();
let results = scanner.scan(Some(&bytes), None)?;

println!("Found {} results", results.len());

// Display first 10 results
for (i, result) in results.iter().take(10).enumerate() {
println!(" [{}] Address: 0x{:X}", i, result.address);
Expand Down
7 changes: 3 additions & 4 deletions core/src/debugger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,9 @@ impl CodePatcher {
use crate::types::Protection;

// Allocate executable memory
let address = self.memory.allocate(
shellcode.len(),
Protection::new(true, true, true),
)?;
let address = self
.memory
.allocate(shellcode.len(), Protection::new(true, true, true))?;

// Write shellcode
self.memory.write(address, shellcode)?;
Expand Down
4 changes: 2 additions & 2 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
//! This crate provides the core functionality for process introspection,
//! memory scanning, pointer analysis, and runtime manipulation.

pub mod debugger;
pub mod error;
pub mod memory;
pub mod platform;
pub mod pointer;
pub mod process;
pub mod scanner;
pub mod pointer;
pub mod debugger;
pub mod types;

pub use error::{InspectraError, Result};
Expand Down
Loading
Loading