chore(release): prepare public source release
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
//! Core behavior tests for PE analysis helpers.
|
||||
|
||||
use petools::{
|
||||
ApiCategory, CallsiteQuery, IoctlMethod, IoctlScanOptions, analyze_callsites,
|
||||
categorize_import, decode_ioctl, scan_strings,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn categorizes_common_windows_imports() {
|
||||
assert_eq!(
|
||||
categorize_import("kernel32.dll", "CreateFileW"),
|
||||
ApiCategory::Filesystem
|
||||
);
|
||||
assert_eq!(
|
||||
categorize_import("advapi32.dll", "RegOpenKeyExW"),
|
||||
ApiCategory::Registry
|
||||
);
|
||||
assert_eq!(
|
||||
categorize_import("ntdll.dll", "NtDeviceIoControlFile"),
|
||||
ApiCategory::DeviceIo
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolves_iat_call_targets_from_objdump_comments() {
|
||||
let query = CallsiteQuery::apis(["CreateFileW"]);
|
||||
let imports = [("0x140072010", "kernel32.dll", "CreateFileW")];
|
||||
let disassembly = "140001098:\tcallq\t*0x70f72(%rip) # 0x140072010\n";
|
||||
let report = analyze_callsites(disassembly, &imports, &query);
|
||||
assert_eq!(report.callsites.len(), 1);
|
||||
assert_eq!(report.callsites[0].api, "CreateFileW");
|
||||
assert_eq!(report.callsites[0].address, 0x1400_01098);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decodes_ctl_code_fields() {
|
||||
let decoded = decode_ioctl(0x0022_2003).expect("ioctl");
|
||||
assert_eq!(decoded.device_type, 0x22);
|
||||
assert_eq!(decoded.function, 0x800);
|
||||
assert_eq!(decoded.method, IoctlMethod::Neither);
|
||||
assert_eq!(decoded.access_name, "FILE_ANY_ACCESS");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scans_ascii_and_utf16_strings() {
|
||||
let mut bytes = b"\0DeviceIoControl\0\0".to_vec();
|
||||
bytes.extend("IoctlName".encode_utf16().flat_map(u16::to_le_bytes));
|
||||
let strings = scan_strings(&bytes, 5);
|
||||
assert!(strings.iter().any(|item| item.value == "DeviceIoControl"));
|
||||
assert!(strings.iter().any(|item| item.value == "IoctlName"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn utf16le_scan_reports_only_maximal_non_overlapping_runs() {
|
||||
let bytes: Vec<u8> = "LongDeviceName"
|
||||
.encode_utf16()
|
||||
.flat_map(u16::to_le_bytes)
|
||||
.collect();
|
||||
let strings = scan_strings(&bytes, 5);
|
||||
let utf16_hits: Vec<_> = strings
|
||||
.iter()
|
||||
.filter(|item| item.encoding == "utf16le")
|
||||
.collect();
|
||||
|
||||
assert_eq!(utf16_hits.len(), 1);
|
||||
assert_eq!(utf16_hits[0].offset, 0);
|
||||
assert_eq!(utf16_hits[0].value, "LongDeviceName");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn filters_probable_ioctl_candidates() {
|
||||
let options = IoctlScanOptions::default();
|
||||
assert!(options.is_probable_code(0x0022_2000));
|
||||
assert!(!options.is_probable_code(0x0000_0001));
|
||||
}
|
||||
Reference in New Issue
Block a user