diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index b19531a..20c01d3 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -887,6 +887,7 @@ version = "0.1.0" dependencies = [ "bitflags 2.6.0", "memmap2", + "pe_parse", "serde", "serde_json", "sysinfo", @@ -2459,6 +2460,16 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" +[[package]] +name = "pe_parse" +version = "0.1.0" +dependencies = [ + "bitflags 2.6.0", + "memmap2", + "serde", + "thiserror 2.0.4", +] + [[package]] name = "percent-encoding" version = "2.3.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index f378f9b..4b61f21 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -27,6 +27,7 @@ tauri = {version = "2", features = [] } tauri-plugin-dialog = "2" tauri-plugin-shell = "2" thiserror = "2.0.4" +pe_parse = { path = "./pe_parse", features = ["memmap2_impl"] } [dependencies.windows] version = "0.58.0" @@ -37,4 +38,4 @@ features = [ "Win32_System_Threading", "Win32_UI_WindowsAndMessaging", "Win32_System_ProcessStatus" -] +] \ No newline at end of file diff --git a/src-tauri/pe_parse/.gitignore b/src-tauri/pe_parse/.gitignore new file mode 100644 index 0000000..b21bd68 --- /dev/null +++ b/src-tauri/pe_parse/.gitignore @@ -0,0 +1,7 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ + +# Generated by Tauri +# will have schema files for capabilities auto-completion +/gen/schemas diff --git a/src-tauri/pe_parse/Cargo.lock b/src-tauri/pe_parse/Cargo.lock new file mode 100644 index 0000000..cc30ac0 --- /dev/null +++ b/src-tauri/pe_parse/Cargo.lock @@ -0,0 +1,112 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] + +[[package]] +name = "libc" +version = "0.2.168" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" + +[[package]] +name = "memmap2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +dependencies = [ + "libc", +] + +[[package]] +name = "pe_parse" +version = "0.1.0" +dependencies = [ + "bitflags", + "memmap2", + "serde", + "thiserror", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serde" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93605438cbd668185516ab499d589afb7ee1859ea3d5fc8f6b0755e1c7443767" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d8749b4531af2117677a5fcd12b1348a3fe2b81e36e61ffeac5c4aa3273e36" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" diff --git a/src-tauri/pe_parse/Cargo.toml b/src-tauri/pe_parse/Cargo.toml new file mode 100644 index 0000000..d7af2f4 --- /dev/null +++ b/src-tauri/pe_parse/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "pe_parse" +version = "0.1.0" +edition = "2021" + +[dependencies] +bitflags = {version = "2.6.0", features = ["serde"] } +memmap2 = "0.9.5" +serde = {version = "1", features = ["derive"] } +thiserror = "2.0.4" + +[features] +default = [] # 默认不启用任何特性 +memmap2_impl = [] # 定义一个 feature,并启用第三方库 \ No newline at end of file diff --git a/src-tauri/src/pe_parse/error.rs b/src-tauri/pe_parse/src/error.rs similarity index 100% rename from src-tauri/src/pe_parse/error.rs rename to src-tauri/pe_parse/src/error.rs diff --git a/src-tauri/src/pe_parse/header.rs b/src-tauri/pe_parse/src/header.rs similarity index 100% rename from src-tauri/src/pe_parse/header.rs rename to src-tauri/pe_parse/src/header.rs diff --git a/src-tauri/pe_parse/src/lib.rs b/src-tauri/pe_parse/src/lib.rs new file mode 100644 index 0000000..5793e6e --- /dev/null +++ b/src-tauri/pe_parse/src/lib.rs @@ -0,0 +1,16 @@ +pub mod error; +pub mod header; +pub mod pe; +pub mod types; + +#[cfg(feature = "memmap2_impl")] +mod third_party { + use memmap2::{MmapMut, Mmap}; + use crate::pe::{MutablePE, ReadOnlyPE}; + // 为文件映射实现PE结构 + impl ReadOnlyPE for Mmap {} + + impl ReadOnlyPE for MmapMut {} + // 为可变文件映射实现可操作PE结构 + impl MutablePE for MmapMut {} +} diff --git a/src-tauri/src/pe_parse/pe.rs b/src-tauri/pe_parse/src/pe.rs similarity index 100% rename from src-tauri/src/pe_parse/pe.rs rename to src-tauri/pe_parse/src/pe.rs diff --git a/src-tauri/src/pe_parse/types.rs b/src-tauri/pe_parse/src/types.rs similarity index 100% rename from src-tauri/src/pe_parse/types.rs rename to src-tauri/pe_parse/src/types.rs diff --git a/src-tauri/src/app_error.rs b/src-tauri/src/app_error.rs index 33d25f5..9be0a9a 100644 --- a/src-tauri/src/app_error.rs +++ b/src-tauri/src/app_error.rs @@ -1,6 +1,6 @@ use thiserror; -use crate::pe_parse::error::{ +use pe_parse::error::{ MutablePEError, PEParseError, }; diff --git a/src-tauri/src/app_state.rs b/src-tauri/src/app_state.rs index 0b343a0..44f2fb0 100644 --- a/src-tauri/src/app_state.rs +++ b/src-tauri/src/app_state.rs @@ -1,13 +1,13 @@ use crate::app_error::AppError; -use crate::pe_parse::header::{ +use crate::services::file::expand_file_size; +use memmap2::Mmap; +use pe_parse::header::{ ImageDirectoryEntry, ImageImportDescriptor, ImageSectionHeader, ImportLookupTable32, ImportLookupTable64, SectionCharacteristics, }; -use crate::pe_parse::pe::MutablePE; -use crate::services::file::expand_file_size; -use crate::{pe_parse::pe::ReadOnlyPE, services::file}; -use memmap2::Mmap; +use pe_parse::pe::{MutablePE, ReadOnlyPE}; use serde::Serialize; +use crate::services::file; use std::ffi::CStr; use std::mem::{self}; @@ -221,7 +221,8 @@ impl AppState { }; import_function_table.function_name = function_name; } else { - let function_ordianl = import_lookup_table as u32 & ImportLookupTable32::IMPORT_BY_ORDINAL_MASK.bits(); + let function_ordianl = import_lookup_table as u32 + & ImportLookupTable32::IMPORT_BY_ORDINAL_MASK.bits(); import_function_table.function_hint = function_ordianl as u16; import_function_table.function_type = ImportFunctionTableItem::Ordinal; } diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index e2f094d..2d5f5c6 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -1,6 +1,7 @@ use std::sync::Mutex; -use crate::{app_error::AppError, app_state::AppState, pe_parse::pe::ReadOnlyPE}; +use crate::{app_error::AppError, app_state::AppState}; +use pe_parse::pe::ReadOnlyPE; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use tauri::{AppHandle, Manager, State}; @@ -128,7 +129,7 @@ pub fn command_get_pe_data_nt_header( ) -> Result { let app_state = app_state.lock().unwrap(); let mmap = app_state.get_mmap_ref()?; - let nt_header: crate::pe_parse::header::ImageNTHeader = mmap.get_nt_header()?; + let nt_header: pe_parse::header::ImageNTHeader = mmap.get_nt_header()?; let nt_offset = mmap.get_nt_headers_offset()?; Ok(json! ({ "fields": nt_header, @@ -222,12 +223,11 @@ pub fn command_write_data_list( } #[derive(Serialize, Deserialize)] -pub struct EditData{ +pub struct EditData { offset: usize, data: Vec, } - // 命令,添加节 #[tauri::command(async)] pub fn command_add_section( diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 0569147..fb36151 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -5,7 +5,6 @@ use tauri::Manager; // Learn more about Tauri commands at https://tauri.app/develop/calling-rust/ pub mod app_error; pub mod commands; -pub mod pe_parse; pub mod services; pub mod app_state; diff --git a/src-tauri/src/pe_parse/mod.rs b/src-tauri/src/pe_parse/mod.rs deleted file mode 100644 index 404d0fd..0000000 --- a/src-tauri/src/pe_parse/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod error; -pub mod header; -pub mod pe; -pub mod types; diff --git a/src-tauri/src/services/mod.rs b/src-tauri/src/services/mod.rs index c22ebee..7341f9c 100644 --- a/src-tauri/src/services/mod.rs +++ b/src-tauri/src/services/mod.rs @@ -1,14 +1,3 @@ -use memmap2::{MmapMut, Mmap}; -use crate::pe_parse::pe::{ - ReadOnlyPE, - MutablePE -}; pub mod file; pub mod win_proc; -// 为文件映射实现PE结构 -impl ReadOnlyPE for Mmap {} - -impl ReadOnlyPE for MmapMut {} -// 为可变文件映射实现可操作PE结构 -impl MutablePE for MmapMut {} diff --git a/src-tauri/src/services/win_proc.rs b/src-tauri/src/services/win_proc.rs index 80fd1e6..461287d 100644 --- a/src-tauri/src/services/win_proc.rs +++ b/src-tauri/src/services/win_proc.rs @@ -1,9 +1,12 @@ -use std::{alloc::{alloc, Layout}, io::{Seek, Write}}; - -use crate::{ - app_error::AppError, - pe_parse::{header::ImageDosHeader, pe::ReadOnlyPE}, +use std::{ + alloc::{alloc, Layout}, + io::{Seek, Write}, }; + +use crate::app_error::AppError; + +use pe_parse::{header::ImageDosHeader, pe::ReadOnlyPE}; + use memmap2::Mmap; use sysinfo::{self, System}; use windows::{ @@ -15,7 +18,7 @@ use windows::{ ProcessStatus::EnumProcessModules, Threading::{ OpenProcess, QueryFullProcessImageNameW, PROCESS_ACCESS_RIGHTS, PROCESS_ALL_ACCESS, - PROCESS_NAME_WIN32, + PROCESS_NAME_WIN32, }, }, }, @@ -81,11 +84,11 @@ pub fn dump_process(pid: u32, save_file_path: &str) -> Result<(), AppError> { // 3.2.2 读取PE头 let nt_header = mmap.get_nt_header()?; let nt_header_size = match nt_header { - crate::pe_parse::header::ImageNTHeader::NTHeader32(_) => { - std::mem::size_of::() as u64 + pe_parse::header::ImageNTHeader::NTHeader32(_) => { + std::mem::size_of::() as u64 } - crate::pe_parse::header::ImageNTHeader::NTHeader64(_) => { - std::mem::size_of::() as u64 + pe_parse::header::ImageNTHeader::NTHeader64(_) => { + std::mem::size_of::() as u64 } }; let nt_header_offset = dos_header.e_lfanew; @@ -110,7 +113,7 @@ pub fn dump_process(pid: u32, save_file_path: &str) -> Result<(), AppError> { // 节区头 let sections_num = mmap.get_section_headers()?.len(); let section_header_offset = mmap.get_section_headers_offset()?; - let section_header_size = std::mem::size_of::() + let section_header_size = std::mem::size_of::() as u64 * sections_num as u64; save_file.seek(std::io::SeekFrom::Start(section_header_offset as u64))?;