feat: 增加暂存区
This commit is contained in:
parent
9806c9bacd
commit
8835ca5f26
@ -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(
|
||||||
|
@ -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,
|
||||||
])
|
])
|
||||||
|
@ -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;
|
||||||
}
|
}
|
@ -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>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -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}
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.NodeTableComponentTable{
|
.NodeTableComponentTable{
|
||||||
height: calc(100% - 16px);
|
height: calc(100% - 40px);
|
||||||
}
|
}
|
@ -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>
|
||||||
);
|
);
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user