Skip to content

Commit 0cab1b9

Browse files
committed
Merge branch 'master' of github.com:thevurv/Autorun-ng
2 parents 20cb4e9 + 7b139b4 commit 0cab1b9

File tree

5 files changed

+125
-7
lines changed

5 files changed

+125
-7
lines changed

packages/autorun-scan/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,10 @@ description.workspace = true
77

88
[dependencies]
99
autorun-log = { path = "../autorun-log" }
10+
11+
[target.'cfg(windows)'.dependencies]
12+
windows = { version = "0.62.2", features = [
13+
"Win32_Foundation",
14+
"Win32_System_Diagnostics_ToolHelp",
15+
"Win32_System_Threading"
16+
] }

packages/autorun-scan/src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,19 @@ macro_rules! sig {
1919
Some($val as u8)
2020
};
2121
}
22+
23+
// Ghidra-style byte strings (e.g. "48 8B ?? ?? ?? 89")
24+
pub fn sig_byte_string(s: &str) -> &[Option<u8>] {
25+
let bytes: Vec<Option<u8>> = s
26+
.split_whitespace()
27+
.map(|b| {
28+
if b == "??" || b == "?" {
29+
None
30+
} else {
31+
Some(u8::from_str_radix(b, 16).expect("Invalid byte in signature"))
32+
}
33+
})
34+
.collect();
35+
36+
Box::leak(bytes.into_boxed_slice())
37+
}

packages/autorun-scan/src/raw/linux.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn parse_perms(perms: &str) -> Permissions {
1616
}
1717
}
1818

19-
pub fn scan(signature: &[Option<u8>]) -> Result<Option<usize>, std::io::Error> {
19+
pub fn scan(signature: &[Option<u8>], target_module: Option<&str>) -> Result<Option<usize>, std::io::Error> {
2020
let maps = std::fs::read_to_string("/proc/self/maps")?;
2121
let mut mem = std::fs::File::open("/proc/self/mem")?;
2222

@@ -35,7 +35,15 @@ pub fn scan(signature: &[Option<u8>]) -> Result<Option<usize>, std::io::Error> {
3535
let _offset = entries[2];
3636
let _dev = entries[3];
3737
let _inode = entries[4];
38-
let _path = entries.get(5); // Optional
38+
let path = entries.get(5); // Optional
39+
40+
if let Some(target_module) = target_module {
41+
let module_path = path.unwrap_or(&"");
42+
let module_name = module_path.rsplit('/').next().unwrap_or("");
43+
if module_name != target_module {
44+
continue;
45+
}
46+
}
3947

4048
if !perms.read || !perms.exec {
4149
continue;
Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,87 @@
1-
pub fn scan(signature: &[Option<u8>]) -> Result<Option<usize>, std::io::Error> {
2-
todo!("Unimplemented on windows");
1+
pub struct Module {
2+
pub base_address: usize,
3+
pub size: usize,
4+
pub name: String,
5+
}
6+
7+
fn get_module_list() -> Result<Vec<Module>, std::io::Error> {
8+
use windows::Win32::Foundation::HANDLE;
9+
use windows::Win32::System::Diagnostics::ToolHelp::{
10+
CreateToolhelp32Snapshot, MODULEENTRY32, Module32First, Module32Next, TH32CS_SNAPMODULE, TH32CS_SNAPMODULE32,
11+
};
12+
13+
let snapshot: HANDLE = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, 0).unwrap() };
14+
if snapshot.is_invalid() {
15+
Err(std::io::Error::last_os_error())
16+
} else {
17+
let mut modules = Vec::new();
18+
let mut module_entry = MODULEENTRY32 {
19+
dwSize: std::mem::size_of::<MODULEENTRY32>() as u32,
20+
..Default::default()
21+
};
22+
23+
let mut success = unsafe { Module32First(snapshot, &mut module_entry).is_ok() };
24+
while success {
25+
let name = String::from_utf8(
26+
module_entry
27+
.szModule
28+
.iter()
29+
.take_while(|&&c| c != 0)
30+
.map(|&c| c as u8)
31+
.collect(),
32+
)
33+
.unwrap_or_default();
34+
35+
modules.push(Module {
36+
base_address: module_entry.modBaseAddr as usize,
37+
size: module_entry.modBaseSize as usize,
38+
name,
39+
});
40+
41+
success = unsafe { Module32Next(snapshot, &mut module_entry).is_ok() };
42+
}
43+
44+
Ok(modules)
45+
}
46+
}
47+
48+
fn find_signature(haystack: &[u8], needle: &[Option<u8>]) -> Option<usize> {
49+
if needle.is_empty() {
50+
return Some(0);
51+
}
52+
53+
for i in 0..=(haystack.len() - needle.len()) {
54+
let mut found = true;
55+
for (j, &byte_opt) in needle.iter().enumerate() {
56+
if let Some(byte) = byte_opt {
57+
if haystack[i + j] != byte {
58+
found = false;
59+
break;
60+
}
61+
}
62+
}
63+
if found {
64+
return Some(i);
65+
}
66+
}
67+
68+
None
69+
}
70+
71+
pub fn scan(signature: &[Option<u8>], target_module: Option<&str>) -> Result<Option<usize>, std::io::Error> {
72+
let modules = get_module_list()?;
73+
for module in modules {
74+
// If no target module specified, scan all modules
75+
let target_module = target_module.unwrap_or(&module.name);
76+
if module.name.eq_ignore_ascii_case(target_module) {
77+
unsafe {
78+
let module_bytes = std::slice::from_raw_parts(module.base_address as *const u8, module.size);
79+
if let Some(offset) = find_signature(module_bytes, signature) {
80+
return Ok(Some(module.base_address + offset));
81+
}
82+
}
83+
}
84+
}
85+
86+
Ok(None)
387
}

services/autorun-lib/src/hooks/the_fn.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ pub fn init() -> anyhow::Result<()> {
1818
// 0x48, 0x8b, 0x05, ?, ?, ?, ?, 0x55, 0x48, 0x89, 0xe5, 0x5d, 0x48, 0x8b, 0x00
1919
// ])?;
2020
// Alternative scan for different signature
21-
let scan_result = autorun_scan::scan(autorun_scan::sig![
22-
0x55, 0x48, 0x89, 0xe5, 0x41, 0x55, 0x41, 0x54, 0x49, 0x89, 0xfc, 0x53, 0x48, 0x83, 0xec, ?, 0x48, 0x8b, 0x77, ?
23-
])?;
21+
let scan_result = autorun_scan::scan(
22+
autorun_scan::sig![
23+
0x55, 0x48, 0x89, 0xe5, 0x41, 0x55, 0x41, 0x54, 0x49, 0x89, 0xfc, 0x53, 0x48, 0x83, 0xec, ?, 0x48, 0x8b, 0x77, ?
24+
],
25+
None,
26+
)?;
2427
if let Some(addr) = scan_result {
2528
let fn_start_addr = addr;
2629
// let fn_start_addr = addr - 33;

0 commit comments

Comments
 (0)