Skip to content
Open
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
7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ categories = ["parser-implementations", "command-line-utilities"]
exclude = ["tests/pocs/blob"]

[workspace]
members = [".", "./src/proc-macros", "./wasm"]
members = [
".",
"./sigscanpro",
"./src/proc-macros",
"./wasm",
]

[features]
default = ["mmap", "derive_pod"]
Expand Down
11 changes: 11 additions & 0 deletions sigscanpro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "sigscanpro"
version = "0.1.0"
authors = ["Casper <[email protected]>"]
edition = "2021"

[lib]
crate-type = ["rlib", "staticlib", "cdylib"]

[dependencies]
pelite = { path = "../" }
4 changes: 4 additions & 0 deletions sigscanpro/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SigScanPro
==========

Wrapper around the pelite pattern scanner.
61 changes: 61 additions & 0 deletions sigscanpro/sigscanpro.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#pragma once

#include <cstdint>

extern "C" {


struct Pattern {
const uint16_t* ptr;
size_t len;
};

struct Pattern PelitePatternParse(const char* string);

void PelitePatternFree(struct Pattern pattern);



struct PeView64 {
const uint8_t* ptr;
size_t len;
uint64_t va;
};

struct PeView64 PeliteView64(const uint8_t* image, uint64_t base_address);

bool PeliteView64Finds(const struct PeView64* view, const char* pat, const char* sect, uint32_t* save_ptr, size_t save_len);



struct PeViewMatches64 {
size_t inner[0x38 / 8];
};

struct PeViewMatches64 PeliteView64Matches(const struct PeView64* view, const Pattern* pat, const char* sect);

bool PeliteView64MatchesNext(struct PeViewMatches64* matches, uint32_t* save_ptr, size_t save_len);



struct PeFile64 {
const uint8_t* ptr;
size_t len;
};

struct PeFile64 PeliteFile64(const uint8_t* ptr, size_t len);

bool PeliteFile64Finds(const struct PeFile64* file, const char* pat, const char* sect, uint32_t* save_ptr, size_t save_len);



struct PeFileMatches64 {
size_t inner[0x30 / 8];
};

struct PeFileMatches64 PeliteFile64Matches(const struct PeFile64* file, const Pattern* pat, const char* sect);

bool PeliteFile64MatchesNext(struct PeFileMatches64* matches, uint32_t* save_ptr, size_t save_len);


}
49 changes: 49 additions & 0 deletions sigscanpro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#![allow(non_snake_case)]

use core::ffi::*;
use core::{mem, slice, ptr};

#[repr(C)]
pub struct Pattern {
ptr: *const u16,
len: usize,
}
impl Pattern {
fn rust(&self) -> &[pelite::pattern::Atom] {
unsafe { slice::from_raw_parts(self.ptr as *const pelite::pattern::Atom, self.len) }
}
}

#[no_mangle]
pub unsafe extern "C" fn PelitePatternParse(string: *const c_char) -> Pattern {
let string = CStr::from_ptr(string);
let string = match string.to_str() {
Ok(string) => string,
Err(err) => {
eprintln!("PelitePatternParse: {}", err);
return Pattern { ptr: ptr::null(), len: 0 };
}
};
let (ptr, len) = match pelite::pattern::parse(string) {
Ok(pattern) => {
let slice = &*Box::into_raw(pattern.into_boxed_slice());
(slice.as_ptr(), slice.len())
}
Err(err) => {
eprintln!("PelitePatternParse: {}", err);
return Pattern { ptr: ptr::null(), len: 0 };
}
};
Pattern { ptr: ptr as *const u16, len }
}

#[no_mangle]
pub unsafe extern "C" fn PelitePatternFree(pat: Pattern) {
if !pat.ptr.is_null() {
let slice = slice::from_raw_parts_mut(pat.ptr as *mut u16, pat.len);
let _ = Box::from_raw(slice);
}
}

pub mod pe64;
pub mod pe32;
179 changes: 179 additions & 0 deletions sigscanpro/src/pe32.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
use super::*;
use pelite::pe32 as pe;
use pelite::pe32::Pe;

#[repr(C)]
pub struct PeView32 {
data: [usize; mem::size_of::<pe::PeView>() / mem::size_of::<usize>()],
}
impl PeView32 {
fn rust(&self) -> pe::PeView {
unsafe { *(self.data.as_ptr() as *const pe::PeView) }
}
}

#[no_mangle]
pub unsafe extern "C" fn PeliteView32(image: *const u8, base_address: u32) -> PeView32 {
let view = pe::PeView::module(image).set_base_address(base_address);
PeView32 { data: mem::transmute(view) }
}

#[no_mangle]
pub unsafe extern "C" fn PeliteView32Finds(view: *const PeView32, pat: *const c_char, sect: *const c_char, save_ptr: *mut u32, save_len: usize) -> bool {
// Parse the pattern
let pat = CStr::from_ptr(pat);
let pat = match pat.to_str() {
Ok(pat) => pat,
Err(err) => {
#[cfg(debug_assertions)]
eprintln!("PelitePatternParse: {}", err);
return false;
}
};
let pat = match pelite::pattern::parse(pat) {
Ok(pat) => pat,
Err(err) => {
#[cfg(debug_assertions)]
eprintln!("PelitePatternParse: {}", err);
return false;
}
};

let view = (*view).rust();

// Find the section by name
let mut range = view.headers().image_range();
if !sect.is_null() {
let sect = CStr::from_ptr(sect).to_bytes();
if let Some(sect) = view.section_headers().by_name(sect) {
range = sect.virtual_range();
}
}

// Find the pattern
let save = slice::from_raw_parts_mut(save_ptr, save_len);
view.scanner().finds(&pat, range, save)
}

// type RustPeViewMatches<'a, 'pat> = pe::scanner::Matches<'pat, pe::PeView<'a>>;
// type RustPeFileMatches<'a, 'pat> = pe::scanner::Matches<'pat, pe::PeFile<'a>>;

#[repr(C)]
pub struct PeViewMatches32 {
data: [usize; mem::size_of::<pe::scanner::Matches<pe::PeView>>() / mem::size_of::<usize>()],
}
impl PeViewMatches32 {
fn rust<'a>(&mut self) -> &mut pe::scanner::Matches<'a, pe::PeView> {
unsafe { &mut *(self.data.as_mut_ptr() as *mut pe::scanner::Matches<'a, pe::PeView>) }
}
}

#[no_mangle]
pub unsafe extern "C" fn PeliteView32Matches(view: *const PeView32, pat: *const Pattern, sect: *const c_char) -> PeViewMatches32 {
let view = (*view).rust();
let pat = (*pat).rust();
let mut range = view.headers().image_range();
if !sect.is_null() {
if let Ok(sect) = CStr::from_ptr(sect).to_str() {
if let Some(sect) = view.section_headers().by_name(sect) {
range = sect.virtual_range();
}
}
}
let matches = view.scanner().matches(pat, range);
PeViewMatches32 { data: mem::transmute(matches) }
}

#[no_mangle]
pub unsafe extern "C" fn PeliteView32MatchesNext(matches: *mut PeViewMatches32, save_ptr: *mut u32, save_len: usize) -> bool {
let matches = (*matches).rust();
let save = slice::from_raw_parts_mut(save_ptr, save_len);
matches.next(save)
}

#[repr(C)]
pub struct PeFile32 {
data: [usize; mem::size_of::<pe::PeFile>() / mem::size_of::<usize>()],
}
impl PeFile32 {
fn rust(&self) -> pe::PeFile {
unsafe { *(self.data.as_ptr() as *const pe::PeFile) }
}
}

#[no_mangle]
pub unsafe extern "C" fn PeliteFile32(ptr: *const u8, len: usize) -> PeFile32 {
let bytes = slice::from_raw_parts(ptr, len);
let file = pe::PeFile::from_bytes(bytes).unwrap();
PeFile32 { data: mem::transmute(file) }
}

#[no_mangle]
pub unsafe extern "C" fn PeliteFile32Finds(file: *const PeFile32, pat: *const c_char, sect: *const c_char, save_ptr: *mut u32, save_len: usize) -> bool {
// Parse the pattern
let pat = CStr::from_ptr(pat);
let pat = match pat.to_str() {
Ok(pat) => pat,
Err(err) => {
#[cfg(debug_assertions)]
eprintln!("PelitePatternParse: {}", err);
return false;
}
};
let pat = match pelite::pattern::parse(pat) {
Ok(pat) => pat,
Err(err) => {
#[cfg(debug_assertions)]
eprintln!("PelitePatternParse: {}", err);
return false;
}
};

let file = (*file).rust();

// Find the section by name
let mut range = file.headers().image_range();
if !sect.is_null() {
let sect = CStr::from_ptr(sect).to_bytes();
if let Some(sect) = file.section_headers().by_name(sect) {
range = sect.virtual_range();
}
}

// Find the pattern
let save = slice::from_raw_parts_mut(save_ptr, save_len);
file.scanner().finds(&pat, range, save)
}

#[repr(C)]
pub struct PeFileMatches32 {
data: [usize; mem::size_of::<pe::scanner::Matches<pe::PeFile>>() / mem::size_of::<usize>()],
}
impl PeFileMatches32 {
fn rust(&mut self) -> &mut pe::scanner::Matches<pe::PeFile> {
unsafe { &mut *(self.data.as_mut_ptr() as *mut pe::scanner::Matches<pe::PeFile>) }
}
}

#[no_mangle]
pub unsafe extern "C" fn PeliteFile32Matches(file: *const PeFile32, pat: *const Pattern, sect: *const c_char) -> PeFileMatches32 {
let file = (*file).rust();
let pat = (*pat).rust();
let mut range = file.headers().image_range();
if !sect.is_null() {
if let Ok(sect) = CStr::from_ptr(sect).to_str() {
if let Some(sect) = file.section_headers().by_name(sect) {
range = sect.virtual_range();
}
}
}
let matches = file.scanner().matches(pat, range);
PeFileMatches32 { data: mem::transmute(matches) }
}

#[no_mangle]
pub unsafe extern "C" fn PeliteFile32MatchesNext(matches: *mut PeFileMatches32, save_ptr: *mut u32, save_len: usize) -> bool {
let matches = (*matches).rust();
let save = slice::from_raw_parts_mut(save_ptr, save_len);
matches.next(save)
}
Loading
Loading