import NodeTableComponent, {
DataTemplateInterface,
} from "../NodeTableComponent/NodeTableComponent";
import { invoke } from "@tauri-apps/api/core";
import { Select, Space } from "antd";
import { useEffect, useMemo, useState } from "react";
// 写一个组件,用于展示位枚举值
interface BitEnumComponentProps {
value: number;
enum: {
[key: number]: {
enum_name: string; // 枚举值名称
description?: string; // 枚举值描述
};
};
onChange?: (value: any, options: any) => void;
}
const BitEnumComponent = (props: BitEnumComponentProps) => {
const formatOptions = useMemo(() => {
const options = Object.entries(props.enum).map(([key, value]) => {
return {
label: value.enum_name,
value: key,
title: value.description,
};
});
return options;
}, [props.enum, props.value]);
const formatValue = useMemo(() => {
const value = [];
for (const key in props.enum) {
if (props.value & parseInt(key)) {
value.push(key);
}
}
return value;
}, [props.value]);
const handleChange = (value: number[], options) => {
// 如果props.onChange存在,那么调用
props.onChange?.(value, options);
// TODO: 做一些自己的事
};
return (
<>
>
);
};
export default function FileHeader() {
const [data, setData] = useState([]);
const [valueHex, setValueHex] = useState(false);
const handleChangeBitEnum = (record: any, value: number[], _options) => {
const { name } = record;
const newData: any = { ...data };
newData.fields[name] = value.reduce(
(prev, cur: any) => prev | parseInt(cur),
0
);
setData(newData);
};
const dataTemplate: DataTemplateInterface = {
machine: {
name: "machine",
description: "目标机器类型,例如 x86 或 x64。",
offset: 0,
size: 2,
value: null,
data_type: "hex",
},
number_of_sections: {
name: "number_of_sections",
description: "节的数量,表示文件中包含的段数量。",
offset: 2,
size: 2,
value: null,
data_type: "hex",
},
time_date_stamp: {
name: "time_date_stamp",
description: "文件的创建时间戳,以自 1970-01-01 的秒数表示。",
offset: 4,
size: 4,
value: null,
data_type: "hex",
},
pointer_to_symbol_table: {
name: "pointer_to_symbol_table",
description: "符号表的文件偏移(通常为 0 表示未使用)。",
offset: 8,
size: 4,
value: null,
data_type: "hex",
},
number_of_symbols: {
name: "number_of_symbols",
description: "符号表中符号的数量(通常为 0 表示未使用)。",
offset: 12,
size: 4,
value: null,
data_type: "hex",
},
size_of_optional_header: {
name: "size_of_optional_header",
description: "可选头的大小,用于进一步描述文件。",
offset: 16,
size: 2,
value: null,
data_type: "hex",
},
characteristics: {
name: "characteristics",
description: "文件特性标志,例如可执行、DLL、移除调试信息等。",
offset: 18,
size: 2,
value: null,
data_type: "bit_enum",
enum: {
0x1: {
enum_name: "RELOCS_STRIPPED",
description: "已从文件中移除重定位信息。",
},
0x2: {
enum_name: "EXECUTABLE_IMAGE",
description: "文件是可执行的(例如,没有未解析的外部引用)。",
},
0x4: {
enum_name: "LINE_NUMS_STRIPPED",
description: "已从文件中移除行号信息。",
},
0x8: {
enum_name: "LOCAL_SYMS_STRIPPED",
description: "已从文件中移除本地符号信息。",
},
0x10: {
enum_name: "AGGRESSIVE_WS_TRIM",
description: "积极地减少工作集。",
},
0x20: {
enum_name: "LARGE_ADDRESS_AWARE",
description: "应用程序可以处理大于 2GB 的地址。",
},
0x80: {
enum_name: "BYTES_REVERSED_LO",
description: "机器字的字节顺序被颠倒(低位字节)。",
},
0x100: {
enum_name: "MACHINE_32BIT",
description: "32 位字长的机器。",
},
0x200: {
enum_name: "DEBUG_STRIPPED",
description: "调试信息已被移到 .DBG 文件中。",
},
0x400: {
enum_name: "REMOVABLE_RUN_FROM_SWAP",
description: "如果映像位于可移动介质上,则复制并从交换文件运行。",
},
0x800: {
enum_name: "NET_RUN_FROM_SWAP",
description: "如果映像位于网络上,则复制并从交换文件运行。",
},
0x1000: {
enum_name: "SYSTEM",
description: "系统文件。",
},
0x2000: {
enum_name: "DLL",
description: "文件是一个 DLL。",
},
0x4000: {
enum_name: "UP_SYSTEM_ONLY",
description: "文件只能在单处理器机器上运行。",
},
0x8000: {
enum_name: "BYTES_REVERSED_HI",
description: "机器字的字节顺序被颠倒(高位字节)。",
},
},
},
};
const command = "command_get_pe_data_file_header";
const columns = [
{
title: "字段名",
dataIndex: "name",
key: "name",
},
{
title: "偏移",
dataIndex: "offset",
key: "offset",
hexSwitch: true,
},
{
title: "大小",
dataIndex: "size",
key: "size",
},
{
title: "值",
dataIndex: "value",
key: "value",
editable: true,
render: (text: any, record: any) => {
if (record.data_type === "bit_enum") {
return (
handleChangeBitEnum(record, value, options)
}
/>
);
} else if (record.data_type === "hex") {
return (
{valueHex ? `0x${text.toString(16).toUpperCase()}` : text}
);
}
return {text};
},
onHeaderCell: () => ({
onClick: () => {
setValueHex(!valueHex);
},
}),
},
{
title: "描述信息",
dataIndex: "description",
key: "description",
minWidth: 200,
},
];
useEffect(() => {
invoke(command).then((res) => {
setData(res as any);
});
}, []);
return (
);
}