diff --git a/package.json b/package.json index fce6e55..27331dd 100644 --- a/package.json +++ b/package.json @@ -16,11 +16,13 @@ "@tauri-apps/plugin-shell": "^2", "antd": "^5.22.3", "lodash-es": "^4.17.21", + "moment": "^2.30.1", "react": "^18.0.0", "react-dom": "^18.0.0" }, "devDependencies": { "@tauri-apps/cli": "^2", + "@types/antd": "^1.0.4", "@types/lodash-es": "^4.17.12", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3b597ac..8ff0fae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,10 +22,13 @@ importers: version: 2.0.1 antd: specifier: ^5.22.3 - version: 5.22.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 5.22.3(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lodash-es: specifier: ^4.17.21 version: 4.17.21 + moment: + specifier: ^2.30.1 + version: 2.30.1 react: specifier: ^18.0.0 version: 18.3.1 @@ -36,6 +39,9 @@ importers: '@tauri-apps/cli': specifier: ^2 version: 2.1.0 + '@types/antd': + specifier: ^1.0.4 + version: 1.0.4(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/lodash-es': specifier: ^4.17.12 version: 4.17.12 @@ -659,6 +665,10 @@ packages: '@tauri-apps/plugin-shell@2.0.1': resolution: {integrity: sha512-akU1b77sw3qHiynrK0s930y8zKmcdrSD60htjH+mFZqv5WaakZA/XxHR3/sF1nNv9Mgmt/Shls37HwnOr00aSw==} + '@types/antd@1.0.4': + resolution: {integrity: sha512-gp4PGQckP1kNjj2H6juhjKIVwkpXwCIyIvOlwp2DC6geuhVpDHEEB5gwH4hJabVgBAFtrjBPJ58VIRV9VV9W2g==} + deprecated: This is a stub types definition. antd provides its own type definitions, so you do not need this installed. + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -825,6 +835,9 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1704,6 +1717,16 @@ snapshots: dependencies: '@tauri-apps/api': 2.1.1 + '@types/antd@1.0.4(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + antd: 5.22.3(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + transitivePeerDependencies: + - date-fns + - luxon + - moment + - react + - react-dom + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.26.3 @@ -1755,7 +1778,7 @@ snapshots: transitivePeerDependencies: - supports-color - antd@5.22.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + antd@5.22.3(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@ant-design/colors': 7.1.0 '@ant-design/cssinjs': 1.22.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1787,7 +1810,7 @@ snapshots: rc-motion: 2.9.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rc-notification: 5.6.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rc-pagination: 4.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-picker: 4.8.3(dayjs@1.11.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-picker: 4.8.3(dayjs@1.11.13)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rc-progress: 4.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rc-rate: 2.13.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rc-resize-observer: 1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1934,6 +1957,8 @@ snapshots: picomatch: 2.3.1 optional: true + moment@2.30.1: {} + ms@2.1.3: {} nanoid@3.3.8: {} @@ -2104,7 +2129,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - rc-picker@4.8.3(dayjs@1.11.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + rc-picker@4.8.3(dayjs@1.11.13)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@babel/runtime': 7.26.0 '@rc-component/trigger': 2.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2116,6 +2141,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) optionalDependencies: dayjs: 1.11.13 + moment: 2.30.1 rc-progress@4.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: diff --git a/src-tauri/src/app_state.rs b/src-tauri/src/app_state.rs index 3b85be3..7ddec0b 100644 --- a/src-tauri/src/app_state.rs +++ b/src-tauri/src/app_state.rs @@ -173,7 +173,7 @@ impl AppState { import_module.module_name_rva = origin_item.name; import_module.timestamp = origin_item.time_date_stamp; // 2. 获取函数表 - let mut functions: Vec = Vec::new(); + let mut functions: Vec = Vec::new(); // 获取函数表的FOA let mut base_offset = mmap.rva_to_foa(origin_item.original_first_thunk)? as usize; // 循环解析函数表 @@ -222,10 +222,11 @@ impl AppState { CStr::from_ptr(ptr).to_str()?.to_string() }; import_function_table.function_name = function_name; - functions.push(ImportFunctionTableItem::Named(import_function_table)); + functions.push(import_function_table); } false => { - functions.push(ImportFunctionTableItem::Ordinal(import_function_table)); + import_function_table.function_type = ImportFunctionTableItem::Ordinal; + functions.push(import_function_table); } } // 下一个 @@ -242,7 +243,7 @@ impl AppState { #[derive(Debug, Default, Clone, Serialize)] pub struct ImportModuleTable { pub module_name: String, // 模块名称 - pub functions: Vec, // 这里要另一个结构体来描述 + pub functions: Vec, // 这里要另一个结构体来描述 pub timestamp: u32, // 时间戳 pub forwarder_chain: u32, // 转发链 pub module_name_rva: u32, // dll名称的RVA @@ -251,12 +252,13 @@ pub struct ImportModuleTable { } // 因为导入查找表可能是函数名、也可能是序号 所以用枚举包一下最好 -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Default)] pub enum ImportFunctionTableItem { // 命名的导入函数 - Named(ImportFunctionTable), + #[default] + Named, // 序号表示的 - Ordinal(ImportFunctionTable), + Ordinal, } #[derive(Debug, Default, Clone, Serialize)] @@ -264,4 +266,5 @@ pub struct ImportFunctionTable { pub function_name: String, // 函数名称 pub function_address: u32, // 函数地址 IAT pub function_hint: u16, // 函数提示 + pub function_type: ImportFunctionTableItem } diff --git a/src/App.tsx b/src/App.tsx index fddd5d5..5331483 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,10 @@ // import MainLayout from "./layouts/MainLayout"; import MainPage from "./pages/MainPage"; - +import moment from "moment"; import "./App.css"; +// 初始化moment地区 +moment.locale("zh-cn"); + function App() { return ( diff --git a/src/components/ImportDirectory/ImportDirectory.module.scss b/src/components/ImportDirectory/ImportDirectory.module.scss new file mode 100644 index 0000000..926e5cf --- /dev/null +++ b/src/components/ImportDirectory/ImportDirectory.module.scss @@ -0,0 +1,7 @@ +.moduleContainer{ + flex-direction: column; +} + +.functionContainer{ + +} \ No newline at end of file diff --git a/src/components/ImportDirectory/ImportDirectory.tsx b/src/components/ImportDirectory/ImportDirectory.tsx index 62a7dad..37df242 100644 --- a/src/components/ImportDirectory/ImportDirectory.tsx +++ b/src/components/ImportDirectory/ImportDirectory.tsx @@ -1,10 +1,178 @@ import { invoke } from "@tauri-apps/api/core"; -import { useEffect } from "react"; +import { useCallback, useEffect, useMemo, useState } from "react"; +import styles from "./ImportDirectory.module.scss"; +import moment from "moment"; +import { Flex, Table } from "antd"; +import Title from "antd/es/typography/Title"; + +interface ModuleProps { + module_name: String; + timestamp: number; + forwarder_chain: number; + module_name_rva: number; + functions: FunctionProps[]; +} +interface FunctionProps { + function_name: string; + function_address: number; + function_hint: number; + function_type: "Named" | "Ordinal"; +} + +interface ImportModuleComponentProps { + moduleList: ModuleProps[]; +} + +interface ModuleFuntionsComponentProps { + functionList: FunctionProps[]; +} + +const ImportModuleComponent: React.FC = (props) => { + const { moduleList } = props; + const [selectedRowKey, setSelectedRowKey] = useState([]); + const handleRowSelection = (selectedRowKeys: any) => { + setSelectedRowKey(selectedRowKeys); + }; + + const columns = [ + { + title: "模块名称", + dataIndex: "module_name", + key: "module_name", + }, + { + title: "导入函数数量", + render: (_text: any, record: any) => { + console.log("record", record); + return record.functions.length; + }, + }, + { + title: "时间戳", + dataIndex: "timestamp", + key: "timestamp", + render: (text: number) => { + return moment(text).format("YYYY-MM-DD HH:mm:ss"); + }, + }, + { + title: "转发链", + dataIndex: "forwarder_chain", + key: "forwarder_chain", + }, + { + title: "模块名称的RVA", + dataIndex: "module_name_rva", + key: "module_name_rva", + render: (text: number) => { + return "0x" + text.toString(16).toUpperCase(); + }, + }, + ]; + + const select_functions = useMemo(() => { + return moduleList.find((module) => module.module_name === selectedRowKey[0]) + ?.functions; + }, [selectedRowKey]); + + return ( + +
+ 导入模块 + { + return { + onClick: (event) => { + handleRowSelection([record.module_name]); + }, + }; + }} + bordered + dataSource={moduleList} + rowKey="module_name" + pagination={false} + /> + +
+ 导入模块 + +
+ + ); +}; + +const ModuleFuntionsComponent: React.FC = ( + props +) => { + const { functionList } = props; + console.log("functionList", functionList); + const columns = [ + { + title: "序号", + render:(_text,_record,index)=>`${index+1}`, + rowScope: 'row', + }, + { + title: "函数名称", + dataIndex: "function_name", + key: "function_name", + }, + { + title: "函数地址", + dataIndex: "function_address", + key: "function_address", + render: (text: number) => { + return "0x" + text.toString(16).toUpperCase(); + }, + }, + { + title: "函数提示", + dataIndex: "function_hint", + key: "function_hint", + }, + { + title: "函数类型", + dataIndex: "function_type", + key: "function_type", + render: (text: string) => { + console.log("text", text); + return text == "Named" ? "命名" : "序数"; + }, + }, + ]; + + return ( + +
+ + ); +}; + export default function ImportDirectory() { + const [data, setData] = useState([]); + const getData = () => { invoke("command_get_pe_data_import_directory") .then((res) => { - console.log("res", res); + const { fields } = res as any; + setData(fields); }) .catch((err) => { console.log("err", err); @@ -15,5 +183,9 @@ export default function ImportDirectory() { getData(); }, []); - return
ImportDirectory
; + return ( +
+ +
+ ); }