feat: 增加暂存区

This commit is contained in:
381848900@qq.com 2024-12-15 17:29:20 +08:00
parent 9806c9bacd
commit 8835ca5f26
8 changed files with 233 additions and 200 deletions

View File

@ -1,7 +1,7 @@
use std::sync::Mutex; use std::sync::Mutex;
use crate::{app_error::AppError, app_state::AppState, pe_parse::pe::ReadOnlyPE}; use crate::{app_error::AppError, app_state::AppState, pe_parse::pe::ReadOnlyPE};
use serde::Serialize; use serde::{Deserialize, Serialize};
use serde_json::{json, Value}; use serde_json::{json, Value};
use tauri::{AppHandle, Manager, State}; use tauri::{AppHandle, Manager, State};
@ -209,6 +209,25 @@ pub fn command_write_data(
Ok(()) Ok(())
} }
#[tauri::command(async)]
pub fn command_write_data_list(
app_state: State<'_, Mutex<AppState>>,
data_list: Vec<EditData>,
) -> Result<(), AppError> {
let mut app_state = app_state.lock().unwrap();
for edit_data in data_list {
app_state.write_data(edit_data.offset, &edit_data.data)?;
}
Ok(())
}
#[derive(Serialize, Deserialize)]
pub struct EditData{
offset: usize,
data: Vec<u8>,
}
// 命令,添加节 // 命令,添加节
#[tauri::command(async)] #[tauri::command(async)]
pub fn command_add_section( pub fn command_add_section(

View File

@ -26,6 +26,7 @@ pub fn run() {
commands::command_get_pe_data_section_headers, commands::command_get_pe_data_section_headers,
commands::command_get_pe_data_import_directory, commands::command_get_pe_data_import_directory,
commands::command_write_data, commands::command_write_data,
commands::command_write_data_list,
commands::command_add_section, commands::command_add_section,
commands::command_test, commands::command_test,
]) ])

View File

@ -1,8 +1,9 @@
.root {
margin: 8px;
margin-top: 0; .optionalContent{
height: 100%; margin-bottom: 12px;
background-color: white; justify-content: end;
border-radius: 5px; }
padding: 16px; .optionalItem{
margin-left: 16px;
} }

View File

@ -4,7 +4,166 @@ import NodeTableComponent, {
DataType, DataType,
} from "../NodeTableComponent/NodeTableComponent"; } from "../NodeTableComponent/NodeTableComponent";
import { invoke } from "@tauri-apps/api/core"; import { invoke } from "@tauri-apps/api/core";
import { message } from "antd"; import { Button, Flex, message } from "antd";
import styles from './DosHeader.module.scss'
const dataTemplate: DataTemplateInterface = {
e_magic: {
name: "e_magic",
description: "标识文件的魔数DOS 可执行文件的值通常为 'MZ'。",
value: 0,
size: 2,
offset: 0,
data_type: "hex",
},
e_cblp: {
name: "e_cblp",
description: "文件最后一页的字节数,指示文件不完整页的大小。",
value: 0,
size: 2,
offset: 2,
data_type: "hex",
},
e_cp: {
name: "e_cp",
description: "文件的总页数(每页 512 字节)。",
value: 0,
size: 2,
offset: 4,
data_type: "hex",
},
e_crlc: {
name: "e_crlc",
description: "重定位表中的条目数。",
value: 0,
size: 2,
offset: 6,
data_type: "hex",
},
e_cparhdr: {
name: "e_cparhdr",
description: "文件头部的段数,单位为 16 字节段。",
value: 0,
size: 2,
offset: 8,
data_type: "hex",
},
e_minalloc: {
name: "e_minalloc",
description: "程序需要的最小额外段数。",
value: 0,
size: 2,
offset: 10,
data_type: "hex",
},
e_maxalloc: {
name: "e_maxalloc",
description: "程序可以分配的最大额外段数。",
value: 0,
size: 2,
offset: 12,
data_type: "hex",
},
e_ss: {
name: "e_ss",
description: "初始的 SS 寄存器值,段偏移地址。",
value: 0,
size: 2,
offset: 14,
data_type: "hex",
},
e_sp: {
name: "e_sp",
description: "初始的 SP 寄存器值,栈顶指针。",
value: 0,
size: 2,
offset: 16,
data_type: "hex",
},
e_csum: {
name: "e_csum",
description: "校验和(一般为 0。",
value: 0,
size: 2,
offset: 18,
data_type: "hex",
},
e_ip: {
name: "e_ip",
description: "初始的 IP 寄存器值,代码段的入口偏移地址。",
value: 0,
size: 2,
offset: 20,
data_type: "hex",
},
e_cs: {
name: "e_cs",
description: "初始的 CS 寄存器值,代码段的段基址。",
value: 0,
size: 2,
offset: 22,
data_type: "hex",
},
e_lfarlc: {
name: "e_lfarlc",
description: "重定位表的文件偏移。",
value: 0,
size: 2,
offset: 24,
data_type: "hex",
},
e_ovno: {
name: "e_ovno",
description: "覆盖号(通常为 0。",
value: 0,
size: 2,
offset: 26,
data_type: "hex",
},
e_res: {
name: "e_res",
description: "保留字段,通常为 0。",
value: null,
size: 8,
offset: 28,
array_element_size: 2,
data_type: "array",
},
e_oemid: {
name: "e_oemid",
description: "OEM 标识符。",
value: 0,
size: 2,
offset: 36,
data_type: "hex",
},
e_oeminfo: {
name: "e_oeminfo",
description: "OEM 信息。",
value: 0,
size: 2,
offset: 38,
data_type: "hex",
},
e_res2: {
name: "e_res2",
description: "保留字段,通常为 0。",
value: 0,
size: 20,
offset: 40,
data_type: "array",
array_element_size: 2,
},
e_lfanew: {
name: "e_lfanew",
description: "PE 文件头的偏移地址。",
value: 0,
size: 4,
offset: 60,
data_type: "hex",
},
};
interface DosHeaderResponseData { interface DosHeaderResponseData {
base_offset: number; base_offset: number;
fields: { fields: {
@ -50,176 +209,7 @@ const formatEditValue = (item: DataType) => {
export default function DosHeader() { export default function DosHeader() {
const [data, setData] = useState<DosHeaderResponseData>(); const [data, setData] = useState<DosHeaderResponseData>();
const [messageApi, contextHolder] = message.useMessage(); const [editValues, setEditValues] = useState([]);
const success = () => {
messageApi.open({
type: "success",
content: "修改成功!",
});
};
const error = () => {
messageApi.open({
type: "error",
content: "修改失败!",
});
};
const dataTemplate: DataTemplateInterface = {
e_magic: {
name: "e_magic",
description: "标识文件的魔数DOS 可执行文件的值通常为 'MZ'。",
value: 0,
size: 2,
offset: 0,
data_type: "hex",
},
e_cblp: {
name: "e_cblp",
description: "文件最后一页的字节数,指示文件不完整页的大小。",
value: 0,
size: 2,
offset: 2,
data_type: "hex",
},
e_cp: {
name: "e_cp",
description: "文件的总页数(每页 512 字节)。",
value: 0,
size: 2,
offset: 4,
data_type: "hex",
},
e_crlc: {
name: "e_crlc",
description: "重定位表中的条目数。",
value: 0,
size: 2,
offset: 6,
data_type: "hex",
},
e_cparhdr: {
name: "e_cparhdr",
description: "文件头部的段数,单位为 16 字节段。",
value: 0,
size: 2,
offset: 8,
data_type: "hex",
},
e_minalloc: {
name: "e_minalloc",
description: "程序需要的最小额外段数。",
value: 0,
size: 2,
offset: 10,
data_type: "hex",
},
e_maxalloc: {
name: "e_maxalloc",
description: "程序可以分配的最大额外段数。",
value: 0,
size: 2,
offset: 12,
data_type: "hex",
},
e_ss: {
name: "e_ss",
description: "初始的 SS 寄存器值,段偏移地址。",
value: 0,
size: 2,
offset: 14,
data_type: "hex",
},
e_sp: {
name: "e_sp",
description: "初始的 SP 寄存器值,栈顶指针。",
value: 0,
size: 2,
offset: 16,
data_type: "hex",
},
e_csum: {
name: "e_csum",
description: "校验和(一般为 0。",
value: 0,
size: 2,
offset: 18,
data_type: "hex",
},
e_ip: {
name: "e_ip",
description: "初始的 IP 寄存器值,代码段的入口偏移地址。",
value: 0,
size: 2,
offset: 20,
data_type: "hex",
},
e_cs: {
name: "e_cs",
description: "初始的 CS 寄存器值,代码段的段基址。",
value: 0,
size: 2,
offset: 22,
data_type: "hex",
},
e_lfarlc: {
name: "e_lfarlc",
description: "重定位表的文件偏移。",
value: 0,
size: 2,
offset: 24,
data_type: "hex",
},
e_ovno: {
name: "e_ovno",
description: "覆盖号(通常为 0。",
value: 0,
size: 2,
offset: 26,
data_type: "hex",
},
e_res: {
name: "e_res",
description: "保留字段,通常为 0。",
value: null,
size: 8,
offset: 28,
array_element_size: 2,
data_type: "array",
},
e_oemid: {
name: "e_oemid",
description: "OEM 标识符。",
value: 0,
size: 2,
offset: 36,
data_type: "hex",
},
e_oeminfo: {
name: "e_oeminfo",
description: "OEM 信息。",
value: 0,
size: 2,
offset: 38,
data_type: "hex",
},
e_res2: {
name: "e_res2",
description: "保留字段,通常为 0。",
value: 0,
size: 20,
offset: 40,
data_type: "array",
array_element_size: 2,
},
e_lfanew: {
name: "e_lfanew",
description: "PE 文件头的偏移地址。",
value: 0,
size: 4,
offset: 60,
data_type: "hex",
},
};
const command = "command_get_pe_data_dos_header"; const command = "command_get_pe_data_dos_header";
@ -259,24 +249,34 @@ export default function DosHeader() {
}, },
]; ];
const handleSave = (item: DataType) => { const handleEdit = (item: DataType) => {
if (!checkEditValue(item)) { if (!checkEditValue(item)) {
return; return;
} }
const bufs = formatEditValue(item); const formatEditData: any = {};
console.log("bufs", bufs, item); formatEditData.offset = item.offset;
invoke("command_write_data", { formatEditData.data = formatEditValue(item);
offset: item.offset, console.log("formatEditData", formatEditData);
data: bufs, const newEditValues = [...editValues, formatEditData];
setEditValues(newEditValues);
// 需要同步修改data
const newData = { ...data };
newData.fields[item.name] = item.value;
setData(newData);
}
const handleSave = () => {
const command = "command_write_data_list";
invoke(command, { dataList: editValues }).then((res) => {
message.success("保存成功");
// 刷新数据
getData();
// 清空编辑数据
setEditValues([]);
}).catch((err) => {
message.error(`保存失败: ${err}`);
}) })
.then((_res) => {
// 提示
success();
getData();
})
.catch(() => {
error();
});
}; };
const getData = () => { const getData = () => {
@ -291,12 +291,25 @@ export default function DosHeader() {
return ( return (
<> <>
{contextHolder} <Flex className={styles.optionalContent}>
<Button className={styles.optionalItem}
disabled={editValues.length === 0}
type="primary" onClick={handleSave}></Button>
<Button className={styles.optionalItem}
disabled={editValues.length === 0}
danger onClick={()=>{
// 清空编辑数据
setEditValues([]);
// 重新获取数据
getData();
}}></Button>
</Flex>
<NodeTableComponent <NodeTableComponent
dataTemplate={dataTemplate} dataTemplate={dataTemplate}
defaultData={data} defaultData={data}
columns={columns as any} columns={columns as any}
onEdit={handleSave} onEdit={handleEdit}
></NodeTableComponent> ></NodeTableComponent>
</> </>
); );

View File

@ -116,7 +116,6 @@ const ModuleFuntionsComponent: React.FC<ModuleFuntionsComponentProps> = (
props props
) => { ) => {
const { functionList } = props; const { functionList } = props;
console.log("functionList", functionList);
const columns = [ const columns = [
{ {
title: "序号", title: "序号",
@ -155,7 +154,7 @@ const ModuleFuntionsComponent: React.FC<ModuleFuntionsComponentProps> = (
return ( return (
<Flex className={styles.functionContainer}> <Flex className={styles.functionContainer}>
<Table <Table
columns={columns} columns={columns as any}
dataSource={functionList} dataSource={functionList}
rowKey="function_name" rowKey="function_name"
pagination={false} pagination={false}

View File

@ -3,5 +3,5 @@
} }
.NodeTableComponentTable{ .NodeTableComponentTable{
height: calc(100% - 16px); height: calc(100% - 40px);
} }

View File

@ -288,7 +288,6 @@ export default function NodeTableComponent(props: NodeTableComponentProps) {
rowKey={"name"} rowKey={"name"}
bordered bordered
size="small" size="small"
sticky={{ offsetHeader: -16 }}
/> />
</Flex> </Flex>
); );

View File

@ -26,10 +26,11 @@
.content{ .content{
background-color: white; background-color: white;
display: flex; display: flex;
justify-content: center; justify-content: start;
border-radius: 5px; border-radius: 5px;
overflow: scroll; overflow: scroll;
padding: 16px; padding: 16px;
flex-direction: column;
} }
.mainContent { .mainContent {