feat: 增加节区、关闭文件

This commit is contained in:
2024-12-12 20:58:47 +08:00
parent d8b49c12d1
commit 7346f40592
11 changed files with 585 additions and 29 deletions

View File

@@ -260,17 +260,16 @@ export default function DosHeader() {
];
const handleSave = (item: DataType) => {
console.log("handleSave", item);
if (!checkEditValue(item)) {
return;
}
const bufs = formatEditValue(item);
console.log("change value", bufs);
console.log("bufs", bufs, item);
invoke("command_write_data", {
offset: item.offset,
data: bufs,
})
.then((res) => {
.then((_res) => {
// 提示
success();
getData();

View File

@@ -218,6 +218,8 @@ export default function NodeTableComponent(props: NodeTableComponentProps) {
size: cloneData[key].array_element_size,
value: resData.fields[key][i],
key: `${key}[${i}]`,
data_type: "hex",
array_field: `${key}`
};
array.push(item);
}

View File

@@ -1,16 +1,24 @@
.NodeTableComponentRootFlex {
min-width: calc(100% - 16px);
min-width: calc(100% - 16px);
}
.NodeTableComponentTable{
height: calc(100% - 16px);
.NodeTableComponentTable {
height: calc(100% - 16px);
}
.content{
// 垂直flex
display: flex;
flex-direction: column;
.content {
// 垂直flex
display: flex;
flex-direction: column;
}
.tableItem {
margin-bottom: 24px;
}
margin-bottom: 24px;
}
.optionContainer {
display: flex;
margin-bottom: 16px;
}
.optionItem {
margin-right: 16px;
}

View File

@@ -1,10 +1,21 @@
import NodeTableComponent, {
DataTemplateInterface,
} from "../NodeTableComponent/NodeTableComponent";
import { useEffect, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { invoke } from "@tauri-apps/api/core";
import styles from "./SectionHeaders.module.scss";
import { Flex } from "antd";
import {
Flex,
Button,
Modal,
Form,
Input,
InputNumber,
Select,
message,
} from "antd";
import { PlusOutlined, EditOutlined } from "@ant-design/icons";
const dataTemplate: DataTemplateInterface = {
name: {
name: "name",
@@ -77,11 +88,163 @@ const dataTemplate: DataTemplateInterface = {
description: "属性",
},
};
// 节区属性
const sectionCharacteristics = [
{
value: 0x80000000,
label: "可写",
},
{
value: 0x40000000,
label: "可读",
},
{
value: 0x20000000,
label: "可执行",
},
{
value: 0x02000000,
label: "可丢弃",
},
{
value: 0x04000000,
label: "不可缓存",
},
{
value: 0x08000000,
label: "不可分页",
},
{
value: 0x10000000,
label: "可共享",
},
{
value: 0x01000000,
label: "包含扩展重定位",
},
{
value: 0x00000020,
label: "包含可执行代码",
},
{
value: 0x00000040,
label: "包含已初始化数据",
},
{
value: 0x00000080,
label: "包含未初始化数据",
},
{
value: 0x00000200,
label: "包含注释或信息",
},
{
value: 0x00000800,
label: "将不会成为镜像的一部分",
},
{
value: 0x00001000,
label: "包含 COMDAT 数据",
},
{
value: 0x00100000,
label: "数据对齐到 1 字节边界",
},
{
value: 0x00200000,
label: "数据对齐到 2 字节边界",
},
{
value: 0x00300000,
label: "数据对齐到 4 字节边界",
},
{
value: 0x00400000,
label: "数据对齐到 8 字节边界",
},
{
value: 0x00500000,
label: "数据对齐到 16 字节边界",
},
{
value: 0x00600000,
label: "数据对齐到 32 字节边界",
},
{
value: 0x00700000,
label: "数据对齐到 64 字节边界",
},
{
value: 0x00800000,
label: "数据对齐到 128 字节边界",
},
{
value: 0x00900000,
label: "数据对齐到 256 字节边界",
},
{
value: 0x00A00000,
label: "数据对齐到 512 字节边界",
},
{
value: 0x00B00000,
label: "数据对齐到 1024 字节边界",
},
{
value: 0x00C00000,
label: "数据对齐到 2048 字节边界",
},
{
value: 0x00D00000,
label: "数据对齐到 4096 字节边界",
},
{
value: 0x00E00000,
label: "数据对齐到 8192 字节边界",
},
{
value: 0x00F00000,
label: "数据对齐掩码",
},
{
value: 0x00000001,
label: "预留DSECT 类型",
},
{
value: 0x00000002,
label: "预留:不加载",
},
{
value: 0x00000004,
label: "预留:组节区",
},
{
value: 0x00000008,
label: "预留:不填充节区",
},
{
value: 0x00000010,
label: "预留COPY 类型",
},
{
value: 0x00000100,
label: "预留:其他链接信息",
},
{
value: 0x00000400,
label: "预留:覆盖节区",
},
];
// 节区头大小
const sectionHeaderSize = 40;
export default function SectionHeaders() {
const [data, setData] = useState([]);
const [addSectionVisible, setAddSectionVisible] = useState(false);
const [addSectionLoading, setAddSectionLoading] = useState(false);
const [addSectionForm] = Form.useForm();
const command = "command_get_pe_data_section_headers";
@@ -128,13 +291,129 @@ export default function SectionHeaders() {
);
};
useEffect(() => {
const requestAddSection = async (
sectionName: string,
sectionSize: number,
sectionCharacteristics: number
) =>
invoke("command_add_section", {
sectionName,
sectionSize,
sectionCharacteristics,
});
const AddSectionModel = useMemo(() => {
const handelOk = () => {
const { name, size, characteristics } = addSectionForm.getFieldsValue();
console.log(
"send",
name,
size,
characteristics.reduce((a, b) => a + b)
);
setAddSectionLoading(true);
requestAddSection(
name,
size,
characteristics.reduce((a, b) => a + b)
)
.then((_res) => {
requestData();
setAddSectionLoading(false);
setAddSectionVisible(false);
})
.catch((_err) => {
setAddSectionLoading(false);
});
};
return (
<Modal
title="添加节"
open={addSectionVisible}
onOk={handelOk}
loading={addSectionLoading}
onCancel={() => setAddSectionVisible(false)}
>
<Form
form={addSectionForm}
name="control-hooks"
onFinish={(values) => {
console.log(values);
}}
style={{ maxWidth: 600 }}
>
<Form.Item
name="name"
label="节区名"
rules={[{ required: true, type: "string", max: 8 }]}
>
<Input />
</Form.Item>
<Form.Item
name="size"
label="大小"
rules={[{ required: true, type: "number" }]}
>
<InputNumber min={0} />
</Form.Item>
<Form.Item
name="characteristics"
label="属性"
rules={[{ required: true }]}
>
<Select
mode="multiple"
style={{ width: "100%" }}
placeholder="Please select"
>
{sectionCharacteristics.map((item) => {
return (
<Select.Option value={item.value}>
{item.label}-0x{item.value.toString(16).toUpperCase()}
</Select.Option>
);
})}
</Select>
</Form.Item>
</Form>
</Modal>
);
}, [addSectionVisible, addSectionLoading]);
const requestData = () => {
invoke(command).then((res) => {
setData(formatDataHandler(res));
});
};
useEffect(() => {
requestData();
}, []);
return (
<Flex className={styles.content}>
{AddSectionModel}
<Flex className={styles.optionContainer}>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={() => setAddSectionVisible(true)}
className={styles.optionItem}
>
</Button>
<Button
type="primary"
icon={<EditOutlined />}
className={styles.optionItem}
onClick={() => {
message.info("还没有实现!");
}}
>
</Button>
</Flex>
{data.map((item, index) => {
return (
<div className={styles.tableItem}>

View File

@@ -4,7 +4,7 @@ import { Layout, Flex, Button, Empty } from "antd";
import { listen } from "@tauri-apps/api/event";
import { invoke } from "@tauri-apps/api/core";
const { Content } = Layout;
import { SaveOutlined, FolderOpenFilled } from "@ant-design/icons";
import { CloseOutlined, FolderOpenFilled } from "@ant-design/icons";
import SiderTree from "../components/side_tree/SideTree";
import DosHeader from "../components/DosHeader/DosHeader";
import NtHeader from "../components/NTHeader/NTHeader";
@@ -36,6 +36,14 @@ export default function MainPage() {
}
};
const closeFile = async () => {
invoke("command_close_file").then(() => {
setFilePath("");
setTreeData([]);
setSelectedKey("");
});
};
const changeFile = (filePath: string) => {
invoke("command_open_file", { filePath }).then(() => {
invoke("command_get_file_pe_node_tree_data").then((res) => {
@@ -74,20 +82,27 @@ export default function MainPage() {
style={{
marginRight: "10px",
}}
type="dashed"
type="primary"
color="primary"
onClick={openFile}
icon={<FolderOpenFilled></FolderOpenFilled>}
>
</Button>
<Button type="primary" icon={<SaveOutlined></SaveOutlined>}>
{/* 关闭文件 */}
<Button
danger
type="dashed"
color="danger"
icon={<CloseOutlined></CloseOutlined>}
onClick={closeFile}
>
</Button>
</Flex>
<Flex className={styles.mainContent}>
<Flex className={styles.sider}>
<SiderTree
treeData={treeData}
defaultSelectedKey={treeData[0]?.key || ""}
onSelect={onSelect}
@@ -97,9 +112,12 @@ export default function MainPage() {
{selectedKey && SelectNodeMap[selectedKey] ? (
SelectNodeMap[selectedKey]
) : (
<Empty style={{
alignSelf: "center",
}} description={"请选择一个节点"} />
<Empty
style={{
alignSelf: "center",
}}
description={"请选择一个节点"}
/>
)}
</Content>
</Flex>