diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 30f22c2..d29dc5e 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -132,3 +132,10 @@ pub fn command_get_pe_data_optional_header() -> Result Result { + let result = services::file::get_section_header_data()?; + Ok(result) +} \ No newline at end of file diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 729082e..d83f2af 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -16,6 +16,7 @@ pub fn run() { commands::command_get_pe_data_nt_header, commands::command_get_pe_data_file_header, commands::command_get_pe_data_optional_header, + commands::command_get_pe_data_section_headers, commands::set_complete, ]) .run(tauri::generate_context!()) diff --git a/src-tauri/src/pe_parse/pe.rs b/src-tauri/src/pe_parse/pe.rs index ca522b7..a88ef3d 100644 --- a/src-tauri/src/pe_parse/pe.rs +++ b/src-tauri/src/pe_parse/pe.rs @@ -142,15 +142,21 @@ pub trait PE: Deref + DerefMut + Sized { Ok(optional_header_offset) } - // 获取所有节区头数据 - fn get_image_section_headers(&self) -> Result<&[ImageSectionHeader], PEParseError> { - // 1. 获取节区数量 - let number_of_sections = self.get_number_of_sections()?; - // 2. 找到节区头的偏移 + // 获取节区头的偏移 + fn get_section_headers_offset(&self) -> Result { // 节区头偏移在可选头之后,可选头大小是可变的,所以需要计算 let optional_header_size = self.get_size_of_optional_header()?; let file_header_offset = self.get_file_header_offset()?; let section_header_offset = file_header_offset + std::mem::size_of::() + optional_header_size; + Ok(section_header_offset) + } + + // 获取所有节区头数据 + fn get_section_headers(&self) -> Result<&[ImageSectionHeader], PEParseError> { + // 1. 获取节区数量 + let number_of_sections = self.get_number_of_sections()?; + // 2. 获取节区头偏移 + let section_header_offset = self.get_section_headers_offset()?; // 3. 获取节区头数据 unsafe { let ptr = self.as_ptr().wrapping_offset(section_header_offset as isize) as *const ImageSectionHeader; diff --git a/src-tauri/src/services/file.rs b/src-tauri/src/services/file.rs index 0873322..a1d741f 100644 --- a/src-tauri/src/services/file.rs +++ b/src-tauri/src/services/file.rs @@ -1,7 +1,7 @@ use memmap2::*; use serde::Serialize; -use crate::{app_error::AppError, pe_parse::{header::{ImageDosHeader, ImageFileHeader, ImageNTHeaders, ImageNTHeaders32, ImageOptionalHeader}, pe::PE}}; +use crate::{app_error::AppError, pe_parse::{header::{ImageDosHeader, ImageFileHeader, ImageNTHeaders, ImageNTHeaders32, ImageOptionalHeader, ImageSectionHeader}, pe::PE}}; use super::{GLOBAL_FILE_DATA, GLOBAL_IS_64_BIT}; @@ -68,7 +68,6 @@ pub struct ResponseOptionalHeaderData { pub is_64_bit: bool, } - pub fn get_optional_header_data() -> Result { let binding = GLOBAL_FILE_DATA.lock().unwrap(); let file_data = binding.as_ref().unwrap(); @@ -81,4 +80,24 @@ pub fn get_optional_header_data() -> Result, + pub base_offset: usize, +} + +pub fn get_section_header_data() -> Result { + let binding = GLOBAL_FILE_DATA.lock().unwrap(); + let file_data = binding.as_ref().unwrap(); + let section_headers = file_data.get_section_headers()?; + let section_headers_offset = file_data.get_section_headers_offset()?; + let vec_section_headers = section_headers.to_vec(); + let result = ResponseSectionHeaderData { + fields: vec_section_headers, + base_offset: section_headers_offset, + }; + Ok(result) } \ No newline at end of file diff --git a/src/components/NodeTableComponent/NodeTableComponent.tsx b/src/components/NodeTableComponent/NodeTableComponent.tsx index 87ad1c6..2bcf6b5 100644 --- a/src/components/NodeTableComponent/NodeTableComponent.tsx +++ b/src/components/NodeTableComponent/NodeTableComponent.tsx @@ -21,7 +21,7 @@ export interface DataType { offset: number; name: string; size: number; - value: number | number[] | null; + value?: number | number[] | null; description?: string; // 枚举值 key:value => value: description enum?: { @@ -204,7 +204,7 @@ export default function NodeTableComponent(props: NodeTableComponentProps) { const cloneData = cloneDeep(props.dataTemplate); // 2. 遍历resData,更新cloneData for (let key in cloneData) { - if(!resData || !resData.fields){ + if (!resData || !resData.fields) { continue; } @@ -247,23 +247,28 @@ export default function NodeTableComponent(props: NodeTableComponentProps) { cloneData[key].children = children; } // TODO: 字符数组处理 + if (cloneData[key].data_type === "char_array") { + let value: any = resData.fields[key]; + // 将ascii码转换为字符 + let str = ""; + for (let i = 0; i < value.length; i++) { + str += String.fromCharCode(value[i]); + } + cloneData[key].value = str as any; + } } // TODO: 应该从columns中获需要排序的字段,来进行排序 // 如果cloneData的成员中有offset字段,那么需要按照offset排序 let cloneDataArray = Object.values(cloneData); - if (cloneDataArray[0].offset) { + if (cloneDataArray[0] && cloneDataArray[0].offset) { cloneDataArray.sort((a, b) => a.offset - b.offset); } return cloneDataArray; }; - const formatData = useMemo(()=>{ + const formatData = useMemo(() => { return handleData(props.defaultData as any); - - }, [props.defaultData]) - - - + }, [props.defaultData]); // useEffect(() => { // // 请求数据 diff --git a/src/components/SectionHeaders/SectionHeaders.module.scss b/src/components/SectionHeaders/SectionHeaders.module.scss new file mode 100644 index 0000000..9d97a10 --- /dev/null +++ b/src/components/SectionHeaders/SectionHeaders.module.scss @@ -0,0 +1,16 @@ +.NodeTableComponentRootFlex { + min-width: calc(100% - 16px); +} + +.NodeTableComponentTable{ + height: calc(100% - 16px); +} + +.content{ + // 垂直flex + display: flex; + flex-direction: column; +} +.tableItem { + margin-bottom: 24px; +} \ No newline at end of file diff --git a/src/components/SectionHeaders/SectionHeaders.tsx b/src/components/SectionHeaders/SectionHeaders.tsx index d03f01a..d189541 100644 --- a/src/components/SectionHeaders/SectionHeaders.tsx +++ b/src/components/SectionHeaders/SectionHeaders.tsx @@ -1,61 +1,153 @@ import NodeTableComponent, { - DataTemplateInterface, - } from "../NodeTableComponent/NodeTableComponent"; - - export default function SectionHeaders() { - const dataTemplate: DataTemplateInterface = { - + DataTemplateInterface, +} from "../NodeTableComponent/NodeTableComponent"; +import { useEffect, useState } from "react"; +import { invoke } from "@tauri-apps/api/core"; +import styles from "./SectionHeaders.module.scss"; +import { Flex } from "antd"; +const dataTemplate: DataTemplateInterface = { + name: { + name: "name", + offset: 0, + size: 8, + data_type: "char_array", + description: "节区的名称,一般以.开头", + }, + virtual_size: { + name: "virtual_size", + offset: 8, + size: 4, + data_type: "hex", + description: "在内存中的大小,不能为0", + }, + virtual_address: { + name: "virtual_address", + offset: 12, + size: 4, + data_type: "hex", + description: "在内存中的地址(VA)", + }, + size_of_raw_data: { + name: "size_of_raw_data", + offset: 16, + size: 4, + data_type: "hex", + description: "在文件中的大小", + }, + pointer_to_raw_data: { + name: "pointer_to_raw_data", + offset: 20, + size: 4, + data_type: "hex", + description: "在文件中的偏移", + }, + pointer_to_relocations: { + name: "pointer_to_relocations", + offset: 24, + size: 4, + data_type: "hex", + description: "重定位表的偏移", + }, + pointer_to_linenumbers: { + name: "pointer_to_linenumbers", + offset: 28, + size: 4, + data_type: "hex", + description: "行号表的偏移", + }, + number_of_relocations: { + name: "number_of_relocations", + offset: 32, + size: 2, + data_type: "hex", + description: "重定位表的数量", + }, + number_of_linenumbers: { + name: "number_of_linenumbers", + offset: 34, + size: 2, + data_type: "hex", + description: "行号表的数量", + }, + characteristics: { + name: "characteristics", + offset: 36, + size: 4, + data_type: "hex", + description: "属性", + }, +}; +// 节区头大小 +const sectionHeaderSize = 40; +export default function SectionHeaders() { + const [data, setData] = useState([]); - /** - pub name: [u8; 8], - pub virtual_size: u32, - pub virtual_address: u32, - pub size_of_raw_data: u32, - pub pointer_to_raw_data: u32, - pub pointer_to_relocations: u32, - pub pointer_to_linenumbers: u32, - pub number_of_relocations: u16, - pub number_of_linenumbers: u16, - pub characteristics: SectionCharacteristics, - */ - }; - const command = "command_get_pe_data_optional_header"; - const columns = [ - { - title: "节区名(Byte[8])", - dataIndex: "name", - key: "name", - }, - { - title: "虚拟大小", - dataIndex: "offset", - key: "offset", - hexSwitch: true, - }, - { - title: "大小", - dataIndex: "size", - key: "size", - }, - { - title: "值", - dataIndex: "value", - key: "value", - hexSwitch: true, - editable: true, - }, - { - title: "描述信息", - dataIndex: "description", - key: "description", - }, - ]; + const command = "command_get_pe_data_section_headers"; + + const columns = [ + { + title: "字段名", + dataIndex: "name", + key: "name", + }, + { + title: "偏移", + dataIndex: "offset", + key: "offset", + hexSwitch: true, + }, + { + title: "大小", + dataIndex: "size", + key: "size", + }, + { + title: "值", + dataIndex: "value", + key: "value", + hexSwitch: true, + editable: true, + }, + { + title: "描述信息", + dataIndex: "description", + key: "description", + }, + ]; + + const formatDataHandler = (data: any) => { + const { base_offset } = data; return ( - + data?.fields?.map((item: any, index: number) => { + return { + base_offset: base_offset + index * sectionHeaderSize, + fields: { ...item }, + }; + }) || [] ); - } - \ No newline at end of file + }; + + useEffect(() => { + invoke(command).then((res) => { + setData(formatDataHandler(res)); + }); + }, []); + console.log("yhyy", data); + return ( + + {data.map((item, index) => { + return ( +
+ +
+ ); + })} +
+ ); +} diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx index 047bc24..98656c7 100644 --- a/src/pages/MainPage.tsx +++ b/src/pages/MainPage.tsx @@ -9,6 +9,7 @@ import SiderTree from "../components/side_tree/SideTree"; import DosHeader from "../components/DosHeader/DosHeader"; import NtHeader from "../components/NTHeader/NTHeader"; import FileHeader from "../components/FileHeader/FileHeader"; +import SectionHeaders from "../components/SectionHeaders/SectionHeaders"; import OptionalHeader from "../components/OptionalHeader/OptionalHeader"; import { open } from "@tauri-apps/plugin-dialog"; @@ -17,6 +18,7 @@ const SelectNodeMap = { nt_header: , file_header: , optional_header: , + section_header: , }; export default function MainPage() {