268 lines
7.1 KiB
TypeScript
268 lines
7.1 KiB
TypeScript
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 (
|
||
<>
|
||
<Space style={{ width: "100%" }} direction="vertical">
|
||
<Select
|
||
mode="multiple"
|
||
allowClear
|
||
style={{ width: "100%" }}
|
||
options={formatOptions}
|
||
value={formatValue}
|
||
onChange={handleChange}
|
||
/>
|
||
</Space>
|
||
</>
|
||
);
|
||
};
|
||
|
||
export default function FileHeader() {
|
||
const [data, setData] = useState<any[]>([]);
|
||
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 (
|
||
<BitEnumComponent
|
||
value={text}
|
||
enum={record.enum}
|
||
onChange={(value, options) =>
|
||
handleChangeBitEnum(record, value, options)
|
||
}
|
||
/>
|
||
);
|
||
} else if (record.data_type === "hex") {
|
||
return (
|
||
<span style={{ cursor: "pointer" }}>
|
||
{valueHex ? `0x${text.toString(16).toUpperCase()}` : text}
|
||
</span>
|
||
);
|
||
}
|
||
return <span>{text}</span>;
|
||
},
|
||
onHeaderCell: () => ({
|
||
onClick: () => {
|
||
setValueHex(!valueHex);
|
||
},
|
||
}),
|
||
},
|
||
{
|
||
title: "描述信息",
|
||
dataIndex: "description",
|
||
key: "description",
|
||
minWidth: 200,
|
||
},
|
||
];
|
||
|
||
useEffect(() => {
|
||
invoke(command).then((res) => {
|
||
setData(res as any);
|
||
});
|
||
}, []);
|
||
|
||
return (
|
||
<NodeTableComponent
|
||
dataTemplate={dataTemplate}
|
||
defaultData={data as any}
|
||
columns={columns as any}
|
||
></NodeTableComponent>
|
||
);
|
||
}
|