【问题标题】:Binary File Deserialization using PtrToStructure in C#在 C# 中使用 PtrToStructure 进行二进制文件反序列化
【发布时间】:2012-01-04 08:37:59
【问题描述】:

我正在尝试对我公司的一堆遗留二进制数据进行逆向工程,以便将其转换为更持久的格式。不再支持我们用于创建此数据的应用程序。

我发现我可以在一系列结构中描述数据,并且我已经能够使用 Marshal.PtrToStructure 将它们编组到托管环境中,但一个文件除外。

下面我已经包含了我试图解析的结构的示例。原始数据都是顺序的,我正在尝试一步反序列化。

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct DrillTPD
{
    public short Header;
    public short Header2;
    public short Header3;
    public short RecordCount;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 999)]
    public TPDHeader[] Templates;
} 
[StructLayout(LayoutKind.Sequential, Pack = 1, Size=18)]
struct TPDHeader
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
    public string TemplateName;
    public int TPDIndex;
}

TPDIndex 是从文件开头的字节偏移量。如何添加属性以正确反序列化此数据?

[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 76)]
struct TPDParent
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]
    public string TemplateName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)]
    public string Description;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
    public string Field;
    public double Width;
    public double Length;
    public double Thickness;
    public short WL;
    public short XY;
    public short Origin;
    public short Features;
    [MarshalAs(UnmanagedType.ByValArray)]
    public TPDDetail[] Details;
}
[StructLayout(LayoutKind.Sequential, Pack=1, Size=350)]
struct TPDDetail
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 350)]
    public string Text;
}

TPPDarent 中的 TPDDetail 数组由结构中的 Features 定义。如果没有特征,则在 TPDParent 之后不存在 TPDDetail 数据。

如何动态让反序列化器知道TPDDetail数组的大小?

此数据的伪 XML 结构理想情况下应如下所示:

<DrillTPD>
    <TPDHeader>
        <TPDParent>
            <TPDDetail/>
            <TPDDetail/>
            <TPDDetail/>
        </TPDParent>
    </TPDHeader>
    <TPDHeader>
        .....
    </TPDHeader>
</DrillTPD>

最后一条评论:我只使用过 .NET 语言,但我试图了解事物的非托管方面。感谢您降低答案。 :)

【问题讨论】:

    标签: c# .net data-structures reverse-engineering binary-data


    【解决方案1】:

    尝试创建结构层次结构的简单实例,然后将其作为字节保存到文件中。然后,您可以使用十六进制编辑器将您的输出与您认为它会输出的内容进行比较。差异将突出显示它没有按预期工作的地方。

    否则,您正在尝试为您的结构创建完美的定义,它会拒绝工作,直到它是完美的,而对于您拥有的相当复杂的设置,这将很难实现。

    【讨论】:

      【解决方案2】:

      从我的观点来看,如果你有两个类是最干净的 - 一个带有非托管数据的输入类和第二个只包含托管数据的类,它的构造函数将输入类作为参数并相应地标记为序列化 - 如果全部数据被管理,那么数组大小将由框架内部管理。

      【讨论】:

        猜你喜欢
        • 2023-03-10
        • 2020-03-07
        • 2011-06-08
        • 1970-01-01
        • 2015-03-02
        • 2014-01-04
        • 2011-06-21
        • 2018-10-07
        • 1970-01-01
        相关资源
        最近更新 更多