C#学习调用OpenMcdf模块解析ole数据的基本用法(2)

  暂时没有找到OLE文件中\x01Ole10Native流的数据结构,下载了OffVis软件浏览及解析OLE文件。OffVis(Microsoft Office Visualization Tool)是微软官方发布的Office文件格式可视化分析工具,主要用于安全研究、格式解析和文档修复,支持通过树状视图+十六进制联动方式将OLE文件解析为可视化的层级结构。
  使用OffVis打开保存xml文件的OLE文件,双击\x01Ole10Native流所在条目的Data属性,如下图所示,窗口左侧显示OLE文件中Data属性保存的二进制数据,结合大模型给出的从\x01Ole10Native流提取原始数据的示例代码(代码有问题,没法直接运行),对数据流进行分析,开头4个字节应该为流数据大小,接着2个字节不清楚含义,然后就是原始文件名称及路径,这两个字符串都是以00结尾,然后4个字节不清楚含义,再紧跟4个字节,应该是指定后续字符串的字节数(看着也是原始文件临时路径),该字符串后面的4个字节应该是保存的原始文件的字节数,紧接着的就是原始文件的数据。

  根据上述分析,编写了简单的\x01Ole10Native流解析程序,提取原始文件并保存到本地。由于前两个字符串并没有长度说明,只能通过从第7个字节开始查找00结尾的方式读取字符串,也不知道编码方式,暂时写死使用ASCII解码。示例代码及效果如下所示,之前保存到word文档中的xml文件和mp3文件都算小文件,全都可以将原始数据提出来保存,不过由于xml文件的名称不包含中文,可以正常读取和保存,而mp3文件的名称是中文,解析出来的文件名还是乱码,使用Unicode解码也是乱码,只能临时取个其它名字保存。

csharp 复制代码
private string ReadNullTerminatedString(BinaryReader reader, Encoding encoding)
{
    var bytes = new List<byte>();
    byte b;
    while ((b = reader.ReadByte()) != 0)
    {
        bytes.Add(b);
    }
    return encoding.GetString(bytes.ToArray());
}

private void btnReadInfo_Click(object sender, EventArgs e)
{
    RootStorage rs = RootStorage.Open(txtPath.Text, FileMode.Open);
    CfbStream stream;

    if (rs.TryOpenStream("\u0001Ole10Native", out stream))
    {
        byte[] data = new byte[stream.Length]; 
        stream.Read(data, 0, data.Length);

        // 解析Ole10Native流(包含原始文件数据)
        using (MemoryStream ms = new MemoryStream(data))
        using (BinaryReader reader = new BinaryReader(ms))
        {
            // 读取Ole10Native标头
            int nativeDataSize = reader.ReadInt32(); // 原始数据大小
            reader.ReadInt16();//跳过2字节

            // 读取文件名长度和文件名
            string fileName = ReadNullTerminatedString(reader,Encoding.ASCII);
            string filePath = ReadNullTerminatedString(reader, Encoding.ASCII);

            reader.ReadInt32();//跳过4字节

            int filePathLength = reader.ReadInt32();//文件路径长度
            if(filePathLength>0)
            {
                string filePath1= new string(reader.ReadChars(filePathLength));
            }

            int embeddedDataSize=reader.ReadInt32(); // 原始文件大小
            if(embeddedDataSize>0)
            {
                byte[] embeddata=reader.ReadBytes(embeddedDataSize);
                File.WriteAllBytes($"extracted_{fileName}", embeddata);
            }           
        }
    }
}

参考文献:

1https://github.com/ironfede/openmcdf

2https://www.cnblogs.com/dengchj/p/15267390.html

3https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-doc/f7983581-d107-4a1f-b5f7-f3650e777c04

3https://wenku.csdn.net/answer/o7oarkndk8

4https://wenku.csdn.net/answer/13y75gvusr

相关推荐
周杰伦fans14 小时前
8GB显存下模型量化实战指南
人工智能·后端·c#
samble16 小时前
从零搭建灌装监控系统(十二):配置系统,原子写入与容错
c#·wpf·mvvm·modbus·工业控制
流形填表19 小时前
题库去重实战:基于题干指纹的重复题清理
开发语言·c#
开开心心就好1 天前
以图搜图找重复图片,本地工具离线就能用
javascript·智能手机·ffmpeg·c#·ocr·word·音视频
QQ_21696290961 天前
基于C#(Asp.net)电竞陪玩信息管理系统的设计与实现
java·大数据·spring boot·微信小程序·c#·云计算·asp.net
未来之窗软件服务1 天前
C# 截图源码支持自动保存-东方仙盟
c#·仙盟创梦ide·东方仙盟·电脑工具
UIU1142 天前
-7 / 2 在 C 里是 -3,在 Python 里是 -4,谁算错了?
c++·学习·c#
wflynn2 天前
GitHub 今日推荐|REDox:64 位 token 表示结构化数据,内存占用降 70% 支持多格式互转
开源·c#·github
驰骋工作流2 天前
C#/.NET 开源BPM工作流引擎6大常用对比选型分析驰骋BPM驰骋低代码低代码工作流引擎
开源·c#·.net
en.en..2 天前
C语言 fp与fd 区别详解
c#