feat: 提供了修改功能
This commit is contained in:
parent
bfe54cae1f
commit
d8b49c12d1
1
.gitignore
vendored
1
.gitignore
vendored
@ -22,3 +22,4 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
test_files
|
@ -21,6 +21,10 @@ pub enum AppError {
|
|||||||
/// 初始化打开文件失败
|
/// 初始化打开文件失败
|
||||||
#[error("初始化打开文件失败!: {0}")]
|
#[error("初始化打开文件失败!: {0}")]
|
||||||
InitOpenFileFailed(String),
|
InitOpenFileFailed(String),
|
||||||
|
|
||||||
|
/// 无法修改文件
|
||||||
|
#[error("无法修改文件!: {0}")]
|
||||||
|
CannotModifyFile(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl serde::Serialize for AppError {
|
impl serde::Serialize for AppError {
|
||||||
|
@ -17,14 +17,37 @@ impl AppState {
|
|||||||
/// 初始化打开文件
|
/// 初始化打开文件
|
||||||
pub fn init_open_file(&mut self, file_path: &str) -> Result<(), AppError> {
|
pub fn init_open_file(&mut self, file_path: &str) -> Result<(), AppError> {
|
||||||
self.file_path = Some(file_path.to_string());
|
self.file_path = Some(file_path.to_string());
|
||||||
self.mmap = Some(file::mmap_mut_file(file_path)?);
|
self.mmap = Some(file::mmap_file(file_path)?);
|
||||||
// 读取PE格式来判断是否是64位
|
// 读取PE格式来判断是否是64位
|
||||||
let mmap: &Mmap = self.mmap.as_ref().unwrap();
|
let mmap: &Mmap = self.mmap.as_ref().unwrap();
|
||||||
self.is_64_bit = Some(mmap.is_64_bit()?);
|
self.is_64_bit = Some(mmap.is_64_bit()?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
/// 获取文件内存映射
|
|
||||||
|
/// 获取文件内存映射的引用
|
||||||
pub fn get_mmap_ref(&self) -> Result<&Mmap, AppError> {
|
pub fn get_mmap_ref(&self) -> Result<&Mmap, AppError> {
|
||||||
self.mmap.as_ref().ok_or(AppError::NoFileOpened)
|
self.mmap.as_ref().ok_or(AppError::NoFileOpened)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 设置文件内存映射
|
||||||
|
pub fn set_mmap(&mut self, mmap: Mmap) {
|
||||||
|
self.mmap = Some(mmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 在指定偏移处写入数据,此举会同步修改文件内容
|
||||||
|
pub fn write_data(&mut self, offset: usize, data: &[u8]) -> Result<(), AppError> {
|
||||||
|
// 1. 重新以可读可写打开文件
|
||||||
|
let file_path = self.file_path.as_ref().ok_or(AppError::NoFileOpened)?;
|
||||||
|
let mut rw_mmap = file::mmap_file_rw(file_path)?;
|
||||||
|
// 2. 向内存映射中写入数据
|
||||||
|
rw_mmap[offset..(offset + data.len())].copy_from_slice(data);
|
||||||
|
rw_mmap.flush()?;
|
||||||
|
|
||||||
|
// 3. 重新打开文件
|
||||||
|
self.mmap = Some(file::mmap_file(file_path)?);
|
||||||
|
self.is_64_bit = Some(self.get_mmap_ref()?.is_64_bit()?);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -30,7 +30,7 @@ pub fn set_complete(app: AppHandle) -> Result<(), AppError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 命令,打开文件
|
// 命令,打开文件
|
||||||
#[tauri::command]
|
#[tauri::command(async)]
|
||||||
pub fn command_open_file(
|
pub fn command_open_file(
|
||||||
file_path: &str,
|
file_path: &str,
|
||||||
app_state: State<'_, Mutex<AppState>>,
|
app_state: State<'_, Mutex<AppState>>,
|
||||||
@ -43,7 +43,7 @@ pub fn command_open_file(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command(async)]
|
||||||
pub fn command_get_file_pe_node_tree_data(
|
pub fn command_get_file_pe_node_tree_data(
|
||||||
app_state: State<'_, Mutex<AppState>>,
|
app_state: State<'_, Mutex<AppState>>,
|
||||||
) -> Result<Vec<PeNodeTreeData>, AppError> {
|
) -> Result<Vec<PeNodeTreeData>, AppError> {
|
||||||
@ -100,7 +100,7 @@ pub fn command_get_file_pe_node_tree_data(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 命令,获取DOS头数据
|
// 命令,获取DOS头数据
|
||||||
#[tauri::command]
|
#[tauri::command(async)]
|
||||||
pub fn command_get_pe_data_dos_header(
|
pub fn command_get_pe_data_dos_header(
|
||||||
app_state: State<'_, Mutex<AppState>>,
|
app_state: State<'_, Mutex<AppState>>,
|
||||||
) -> Result<Value, AppError> {
|
) -> Result<Value, AppError> {
|
||||||
@ -114,7 +114,7 @@ pub fn command_get_pe_data_dos_header(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 命令,获取NT头数据
|
// 命令,获取NT头数据
|
||||||
#[tauri::command]
|
#[tauri::command(async)]
|
||||||
pub fn command_get_pe_data_nt_header(
|
pub fn command_get_pe_data_nt_header(
|
||||||
app_state: State<'_, Mutex<AppState>>,
|
app_state: State<'_, Mutex<AppState>>,
|
||||||
) -> Result<Value, AppError> {
|
) -> Result<Value, AppError> {
|
||||||
@ -129,7 +129,7 @@ pub fn command_get_pe_data_nt_header(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 命令,获取文件头数据
|
// 命令,获取文件头数据
|
||||||
#[tauri::command]
|
#[tauri::command(async)]
|
||||||
pub fn command_get_pe_data_file_header(app_state: State<'_, Mutex<AppState>>) -> Result<Value, AppError> {
|
pub fn command_get_pe_data_file_header(app_state: State<'_, Mutex<AppState>>) -> Result<Value, AppError> {
|
||||||
let app_state = app_state.lock().unwrap();
|
let app_state = app_state.lock().unwrap();
|
||||||
let mmap = app_state.get_mmap_ref()?;
|
let mmap = app_state.get_mmap_ref()?;
|
||||||
@ -142,7 +142,7 @@ pub fn command_get_pe_data_file_header(app_state: State<'_, Mutex<AppState>>) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 命令,获取可选头数据
|
// 命令,获取可选头数据
|
||||||
#[tauri::command]
|
#[tauri::command(async)]
|
||||||
pub fn command_get_pe_data_optional_header(app_state: State<'_, Mutex<AppState>>) -> Result<Value, AppError> {
|
pub fn command_get_pe_data_optional_header(app_state: State<'_, Mutex<AppState>>) -> Result<Value, AppError> {
|
||||||
let app_state = app_state.lock().unwrap();
|
let app_state = app_state.lock().unwrap();
|
||||||
let mmap = app_state.get_mmap_ref()?;
|
let mmap = app_state.get_mmap_ref()?;
|
||||||
@ -157,7 +157,7 @@ pub fn command_get_pe_data_optional_header(app_state: State<'_, Mutex<AppState>>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 命令,获取节区头数据
|
// 命令,获取节区头数据
|
||||||
#[tauri::command]
|
#[tauri::command(async)]
|
||||||
pub fn command_get_pe_data_section_headers(app_state: State<'_, Mutex<AppState>>) -> Result<Value, AppError> {
|
pub fn command_get_pe_data_section_headers(app_state: State<'_, Mutex<AppState>>) -> Result<Value, AppError> {
|
||||||
let app_state = app_state.lock().unwrap();
|
let app_state = app_state.lock().unwrap();
|
||||||
let mmap = app_state.get_mmap_ref()?;
|
let mmap = app_state.get_mmap_ref()?;
|
||||||
@ -169,3 +169,15 @@ pub fn command_get_pe_data_section_headers(app_state: State<'_, Mutex<AppState>>
|
|||||||
"base_offset": section_headers_offset,
|
"base_offset": section_headers_offset,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 命令,修改偏移处数据
|
||||||
|
#[tauri::command(async)]
|
||||||
|
pub fn command_write_data(
|
||||||
|
app_state: State<'_, Mutex<AppState>>,
|
||||||
|
offset: usize,
|
||||||
|
data: Vec<u8>,
|
||||||
|
) -> Result<(), AppError> {
|
||||||
|
let mut app_state = app_state.lock().unwrap();
|
||||||
|
app_state.write_data(offset, &data)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -15,6 +15,7 @@ pub fn run() {
|
|||||||
.plugin(tauri_plugin_dialog::init())
|
.plugin(tauri_plugin_dialog::init())
|
||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
|
commands::set_complete,
|
||||||
commands::command_open_file,
|
commands::command_open_file,
|
||||||
commands::command_get_file_pe_node_tree_data,
|
commands::command_get_file_pe_node_tree_data,
|
||||||
commands::command_get_pe_data_dos_header,
|
commands::command_get_pe_data_dos_header,
|
||||||
@ -22,7 +23,7 @@ pub fn run() {
|
|||||||
commands::command_get_pe_data_file_header,
|
commands::command_get_pe_data_file_header,
|
||||||
commands::command_get_pe_data_optional_header,
|
commands::command_get_pe_data_optional_header,
|
||||||
commands::command_get_pe_data_section_headers,
|
commands::command_get_pe_data_section_headers,
|
||||||
commands::set_complete,
|
commands::command_write_data,
|
||||||
])
|
])
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
app.manage(Mutex::new(app_state::AppState::default()));
|
app.manage(Mutex::new(app_state::AppState::default()));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use memmap2::*;
|
use memmap2::*;
|
||||||
|
|
||||||
/// 以只读的方式创建文件映射
|
/// 以只读的方式创建文件映射
|
||||||
pub fn mmap_mut_file(file_path: &str) -> Result<Mmap, std::io::Error> {
|
pub fn mmap_file(file_path: &str) -> Result<Mmap, std::io::Error> {
|
||||||
let file = std::fs::OpenOptions::new().read(true).open(file_path)?;
|
let file = std::fs::OpenOptions::new().read(true).open(file_path)?;
|
||||||
unsafe {
|
unsafe {
|
||||||
MmapOptions::new()
|
MmapOptions::new()
|
||||||
@ -9,3 +9,13 @@ pub fn mmap_mut_file(file_path: &str) -> Result<Mmap, std::io::Error> {
|
|||||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 以读写方式创建文件映射
|
||||||
|
pub fn mmap_file_rw(file_path: &str) -> Result<MmapMut, std::io::Error> {
|
||||||
|
let file = std::fs::OpenOptions::new().read(true).write(true).open(file_path)?;
|
||||||
|
unsafe {
|
||||||
|
MmapOptions::new()
|
||||||
|
.map_mut(&file)
|
||||||
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,73 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import NodeTableComponent, {
|
import NodeTableComponent, {
|
||||||
DataTemplateInterface,
|
DataTemplateInterface,
|
||||||
|
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";
|
||||||
|
interface DosHeaderResponseData {
|
||||||
|
base_offset: number;
|
||||||
|
fields: {
|
||||||
|
[key: string]: number | number[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkEditValue = (item: DataType) => {
|
||||||
|
const { value, data_type, size } = item;
|
||||||
|
if (data_type === "hex") {
|
||||||
|
let numberValue = value as number;
|
||||||
|
if (typeof value === "string") {
|
||||||
|
numberValue = parseInt(value, 10);
|
||||||
|
}
|
||||||
|
// 如果是2位 最大为 0xFFFF 10进制为 65535
|
||||||
|
let maxBit = Math.pow(2, size * 8) - 1;
|
||||||
|
console.log("maxBit", maxBit);
|
||||||
|
if (numberValue > maxBit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatEditValue = (item: DataType) => {
|
||||||
|
const { value, data_type, size } = item;
|
||||||
|
let bufs = [];
|
||||||
|
|
||||||
|
if (data_type === "hex") {
|
||||||
|
let numberValue = value as number;
|
||||||
|
if (typeof value === "string") {
|
||||||
|
numberValue = parseInt(value, 10);
|
||||||
|
}
|
||||||
|
// 转小尾
|
||||||
|
for (let i = 0; i < size; i++) {
|
||||||
|
bufs.push(numberValue & 0xff);
|
||||||
|
numberValue = numberValue >> 8;
|
||||||
|
}
|
||||||
|
console.log("bufs", bufs);
|
||||||
|
return bufs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default function DosHeader() {
|
export default function DosHeader() {
|
||||||
|
const [data, setData] = useState<DosHeaderResponseData>();
|
||||||
const [data, setData] = useState<any[]>([]);
|
const [messageApi, contextHolder] = message.useMessage();
|
||||||
|
const success = () => {
|
||||||
|
messageApi.open({
|
||||||
|
type: "success",
|
||||||
|
content: "修改成功!",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const error = () => {
|
||||||
|
messageApi.open({
|
||||||
|
type: "error",
|
||||||
|
content: "修改失败!",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const dataTemplate: DataTemplateInterface = {
|
const dataTemplate: DataTemplateInterface = {
|
||||||
e_magic: {
|
e_magic: {
|
||||||
name: "e_magic",
|
name: "e_magic",
|
||||||
|
description: "标识文件的魔数,DOS 可执行文件的值通常为 'MZ'。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
@ -18,6 +75,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_cblp: {
|
e_cblp: {
|
||||||
name: "e_cblp",
|
name: "e_cblp",
|
||||||
|
description: "文件最后一页的字节数,指示文件不完整页的大小。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 2,
|
offset: 2,
|
||||||
@ -25,6 +83,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_cp: {
|
e_cp: {
|
||||||
name: "e_cp",
|
name: "e_cp",
|
||||||
|
description: "文件的总页数(每页 512 字节)。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 4,
|
offset: 4,
|
||||||
@ -32,6 +91,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_crlc: {
|
e_crlc: {
|
||||||
name: "e_crlc",
|
name: "e_crlc",
|
||||||
|
description: "重定位表中的条目数。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 6,
|
offset: 6,
|
||||||
@ -39,6 +99,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_cparhdr: {
|
e_cparhdr: {
|
||||||
name: "e_cparhdr",
|
name: "e_cparhdr",
|
||||||
|
description: "文件头部的段数,单位为 16 字节段。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 8,
|
offset: 8,
|
||||||
@ -46,6 +107,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_minalloc: {
|
e_minalloc: {
|
||||||
name: "e_minalloc",
|
name: "e_minalloc",
|
||||||
|
description: "程序需要的最小额外段数。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 10,
|
offset: 10,
|
||||||
@ -53,6 +115,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_maxalloc: {
|
e_maxalloc: {
|
||||||
name: "e_maxalloc",
|
name: "e_maxalloc",
|
||||||
|
description: "程序可以分配的最大额外段数。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 12,
|
offset: 12,
|
||||||
@ -60,6 +123,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_ss: {
|
e_ss: {
|
||||||
name: "e_ss",
|
name: "e_ss",
|
||||||
|
description: "初始的 SS 寄存器值,段偏移地址。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 14,
|
offset: 14,
|
||||||
@ -67,6 +131,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_sp: {
|
e_sp: {
|
||||||
name: "e_sp",
|
name: "e_sp",
|
||||||
|
description: "初始的 SP 寄存器值,栈顶指针。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 16,
|
offset: 16,
|
||||||
@ -74,6 +139,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_csum: {
|
e_csum: {
|
||||||
name: "e_csum",
|
name: "e_csum",
|
||||||
|
description: "校验和(一般为 0)。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 18,
|
offset: 18,
|
||||||
@ -81,6 +147,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_ip: {
|
e_ip: {
|
||||||
name: "e_ip",
|
name: "e_ip",
|
||||||
|
description: "初始的 IP 寄存器值,代码段的入口偏移地址。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 20,
|
offset: 20,
|
||||||
@ -88,6 +155,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_cs: {
|
e_cs: {
|
||||||
name: "e_cs",
|
name: "e_cs",
|
||||||
|
description: "初始的 CS 寄存器值,代码段的段基址。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 22,
|
offset: 22,
|
||||||
@ -95,6 +163,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_lfarlc: {
|
e_lfarlc: {
|
||||||
name: "e_lfarlc",
|
name: "e_lfarlc",
|
||||||
|
description: "重定位表的文件偏移。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 24,
|
offset: 24,
|
||||||
@ -102,6 +171,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_ovno: {
|
e_ovno: {
|
||||||
name: "e_ovno",
|
name: "e_ovno",
|
||||||
|
description: "覆盖号(通常为 0)。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 26,
|
offset: 26,
|
||||||
@ -109,15 +179,16 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_res: {
|
e_res: {
|
||||||
name: "e_res",
|
name: "e_res",
|
||||||
|
description: "保留字段,通常为 0。",
|
||||||
value: null,
|
value: null,
|
||||||
size: 8,
|
size: 8,
|
||||||
offset: 28,
|
offset: 28,
|
||||||
// field_type: "[WORD; 4]",
|
|
||||||
array_element_size: 2,
|
array_element_size: 2,
|
||||||
data_type: "array",
|
data_type: "array",
|
||||||
},
|
},
|
||||||
e_oemid: {
|
e_oemid: {
|
||||||
name: "e_oemid",
|
name: "e_oemid",
|
||||||
|
description: "OEM 标识符。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 36,
|
offset: 36,
|
||||||
@ -125,6 +196,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_oeminfo: {
|
e_oeminfo: {
|
||||||
name: "e_oeminfo",
|
name: "e_oeminfo",
|
||||||
|
description: "OEM 信息。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
offset: 38,
|
offset: 38,
|
||||||
@ -132,6 +204,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_res2: {
|
e_res2: {
|
||||||
name: "e_res2",
|
name: "e_res2",
|
||||||
|
description: "保留字段,通常为 0。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 20,
|
size: 20,
|
||||||
offset: 40,
|
offset: 40,
|
||||||
@ -140,6 +213,7 @@ export default function DosHeader() {
|
|||||||
},
|
},
|
||||||
e_lfanew: {
|
e_lfanew: {
|
||||||
name: "e_lfanew",
|
name: "e_lfanew",
|
||||||
|
description: "PE 文件头的偏移地址。",
|
||||||
value: 0,
|
value: 0,
|
||||||
size: 4,
|
size: 4,
|
||||||
offset: 60,
|
offset: 60,
|
||||||
@ -154,20 +228,20 @@ export default function DosHeader() {
|
|||||||
title: "字段名",
|
title: "字段名",
|
||||||
dataIndex: "name",
|
dataIndex: "name",
|
||||||
key: "name",
|
key: "name",
|
||||||
width: 120
|
width: 120,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "偏移",
|
title: "偏移",
|
||||||
dataIndex: "offset",
|
dataIndex: "offset",
|
||||||
key: "offset",
|
key: "offset",
|
||||||
hexSwitch: true,
|
hexSwitch: true,
|
||||||
width: 80
|
width: 80,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "大小",
|
title: "大小",
|
||||||
dataIndex: "size",
|
dataIndex: "size",
|
||||||
key: "size",
|
key: "size",
|
||||||
width: 80
|
width: 80,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "值",
|
title: "值",
|
||||||
@ -175,28 +249,56 @@ export default function DosHeader() {
|
|||||||
key: "value",
|
key: "value",
|
||||||
hexSwitch: true,
|
hexSwitch: true,
|
||||||
editable: true,
|
editable: true,
|
||||||
minWidth: 200
|
minWidth: 200,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "描述信息",
|
title: "描述信息",
|
||||||
dataIndex: "description",
|
dataIndex: "description",
|
||||||
key: "description",
|
key: "description",
|
||||||
width: 250
|
width: 250,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
useEffect(()=>{
|
const handleSave = (item: DataType) => {
|
||||||
invoke(command).then(res => {
|
console.log("handleSave", item);
|
||||||
console.log("asdfsadf",res);
|
if (!checkEditValue(item)) {
|
||||||
setData(res as any);
|
return;
|
||||||
|
}
|
||||||
|
const bufs = formatEditValue(item);
|
||||||
|
console.log("change value", bufs);
|
||||||
|
invoke("command_write_data", {
|
||||||
|
offset: item.offset,
|
||||||
|
data: bufs,
|
||||||
})
|
})
|
||||||
}, [])
|
.then((res) => {
|
||||||
|
// 提示
|
||||||
|
success();
|
||||||
|
getData();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
error();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
invoke(command).then((res) => {
|
||||||
|
setData(res as any);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeTableComponent
|
<>
|
||||||
dataTemplate={dataTemplate}
|
{contextHolder}
|
||||||
defaultData={data}
|
<NodeTableComponent
|
||||||
columns={columns as any}
|
dataTemplate={dataTemplate}
|
||||||
></NodeTableComponent>
|
defaultData={data}
|
||||||
|
columns={columns as any}
|
||||||
|
onEdit={handleSave}
|
||||||
|
></NodeTableComponent>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ export default function NTHeader() {
|
|||||||
size: 4,
|
size: 4,
|
||||||
value: 0,
|
value: 0,
|
||||||
data_type: "hex",
|
data_type: "hex",
|
||||||
|
description: "PE文件的标志,可执行文件的标志是0x00004550",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const command = "command_get_pe_data_nt_header";
|
const command = "command_get_pe_data_nt_header";
|
||||||
|
@ -54,7 +54,8 @@ interface NodeTableComponentProps {
|
|||||||
dataTemplate: DataTemplateInterface; // 数据模板
|
dataTemplate: DataTemplateInterface; // 数据模板
|
||||||
// command: string; // 请求数据的命令
|
// command: string; // 请求数据的命令
|
||||||
columns: NodeTableColumnInterface<DataType>[];
|
columns: NodeTableColumnInterface<DataType>[];
|
||||||
defaultData?: DataType[];
|
defaultData?: ResponsData;
|
||||||
|
onEdit?: (record: DataType) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EditableRowProps {
|
interface EditableRowProps {
|
||||||
@ -77,7 +78,7 @@ interface EditableCellProps {
|
|||||||
editable: boolean;
|
editable: boolean;
|
||||||
dataIndex: keyof DataType;
|
dataIndex: keyof DataType;
|
||||||
record: DataType;
|
record: DataType;
|
||||||
handleSave: (record: DataType) => void;
|
handleSave?: (record: DataType) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EditableCell: React.FC<React.PropsWithChildren<EditableCellProps>> = ({
|
const EditableCell: React.FC<React.PropsWithChildren<EditableCellProps>> = ({
|
||||||
@ -108,7 +109,7 @@ const EditableCell: React.FC<React.PropsWithChildren<EditableCellProps>> = ({
|
|||||||
try {
|
try {
|
||||||
const values = await form.validateFields();
|
const values = await form.validateFields();
|
||||||
toggleEdit();
|
toggleEdit();
|
||||||
handleSave({ ...record, ...values });
|
handleSave?.({ ...record, ...values });
|
||||||
} catch (errInfo) {
|
} catch (errInfo) {
|
||||||
console.log("Save failed:", errInfo);
|
console.log("Save failed:", errInfo);
|
||||||
}
|
}
|
||||||
@ -151,10 +152,6 @@ export default function NodeTableComponent(props: NodeTableComponentProps) {
|
|||||||
setHexSwitchStatus(newHexSwitchStatus);
|
setHexSwitchStatus(newHexSwitchStatus);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSave = (_row: DataType) => {
|
|
||||||
// TODO: 保存逻辑
|
|
||||||
};
|
|
||||||
|
|
||||||
const hexSwitchRender = (text: string, dataIndex: string) => {
|
const hexSwitchRender = (text: string, dataIndex: string) => {
|
||||||
if (text == null || text == undefined || typeof text !== "number") {
|
if (text == null || text == undefined || typeof text !== "number") {
|
||||||
return text;
|
return text;
|
||||||
@ -180,7 +177,7 @@ export default function NodeTableComponent(props: NodeTableComponentProps) {
|
|||||||
editable: col.editable,
|
editable: col.editable,
|
||||||
dataIndex: col.dataIndex,
|
dataIndex: col.dataIndex,
|
||||||
title: col.title,
|
title: col.title,
|
||||||
handleSave,
|
handleSave: props.onEdit,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (col.hexSwitch) {
|
if (col.hexSwitch) {
|
||||||
|
@ -133,7 +133,6 @@ export default function SectionHeaders() {
|
|||||||
setData(formatDataHandler(res));
|
setData(formatDataHandler(res));
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
console.log("yhyy", data);
|
|
||||||
return (
|
return (
|
||||||
<Flex className={styles.content}>
|
<Flex className={styles.content}>
|
||||||
{data.map((item, index) => {
|
{data.map((item, index) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user