PDF文件解析与PDF恶代分析中的一些坑

一、简介

最近在做文档类的恶代检测,写个总结。

本篇文章负责介绍pdf文档的格式以及恶代分析中需要注意的问题以及相应工具推荐。希望能给各位做恶代分析时提供一些帮助。

后序会更新一些其他文档格式解析与恶代分析内容等,欢迎各位关注。

PDF文件解析与PDF恶代分析中的一些坑

二、PDF文件格式介绍

PDF(便携式文件格式,Portable Document Format)是由Adobe Systems于1993年基于文件交换所发展出的一种文件格式。Adobe公司素有“漏洞之王”的美誉,所以学习PDF文件格式对研究分析漏洞具有极大帮助。PDF格式较为复杂,本文以研究漏洞的目的分析PDF格式,探寻如何找出并分析PDF中存在的恶意代码,而并非做一个详细的PDF parser解析器,因此会省略对不相关关键字的介绍,请各位留意。

PDF的结构可以从文件结构和逻辑结构两个方面来理解。PDF的文件结构指的是其文件物理组织方式,逻辑结构则指的是其内容的逻辑组织方式。

1. PDF的文件结构

PDF文件格式包含以下4个部分:

  • 文件头——指明了该文件所遵从的PDF规范的版本号,它出现在PDF文件的第一行。
  • 文件体——又称对象集合,PDF文件的主要部分,由一系列对象组成。
  • 交叉引用表——对对象进行随机存取而设立的一个间接对象的地址索引表。(实际以偏移+索引的方式储存对象地址,下文会提及)
  • 文件尾——声明了交叉引用表的地址,即指明了文件体的根对象(Catalog),从而能够找到PDF文件中各个对象体的位置,达到随机访问。另外还保存了PDF文件的加密等安全信息。

2. PDF文件格式图示:

PDF文件的逻辑结构

3. PDF文件的逻辑结构

本段主要介绍PDF文件体的读取方式。

作为一种结构化的文件格式,一个PDF文档是由一些称为“对象”的模块组成的。每个对象都有数字标号,这样的话可以这些对象就可以被其他的对象所引用。这些对象不需要按照顺序出现在PDF文档里面,出现的顺序可以是任意的,比如一个PDF文件有3页,第3页可以出现在第1页以前,对象按照顺序出现唯一的好处就是能够增加文件的可读性,对象的信息以偏移+索引的形式保存在交叉引用表内。

文件尾说明了根对象的对象号,并且说明交叉引用表的位置,通过对交叉引用表的查询可以找到目录对象(Catalog)。这个目录对象是该PDF文档的根对象,包含PDF文档的大纲(outline)和页面组对象(pages)引用。大纲对象是指PDF文件的书签树;页面组对象(pages)包含该文件的页面数,各个页面对象(page)的对象号。

4. PDF的层级结构图示:

PDF的层级结构图示

页面(page)对象为PDF中最重要的对象,包含如何显示该页面的信息,例如使用的字体,包含的内容(文字,图片等),页面的大小。里面的信息可以直接给出,当然里面的子项更多的是对其他对象的引用,真正的信息存放在其他对象里面。页面中包含的信息是包含在一个称为流(stream)的对象里,这个流的长度(字节数)必须直接给出或指向另外一个对象(包含一个整数值,表明这个流的长度)。

可见stream流对象我们恶代分析需要获取的重点。

5. 页面信息图示:

页面信息图示

理解了上面的内容之后,我们可以得出针对恶代分析的PDF文件的大致解析思路:

针对恶代分析的PDF文件的大致解析思路

当然,也可以采取针对PDF层级结构的文档解析方式,见仁见智,因人而异。

三、以二进制文本解析Pdf文档结构

PDF文件是一种文本和二进制混排的格式,但是Adobe更愿意让人把它当成二进制的文件,所以,PDF文件可以直接拖入16进制编辑器中打开。前面我们介绍了PDF的文件结构以及逻辑结构,现在我们在16进制编辑器中打开PDF文件,更直白的展示PDF的关键字段以及文件结构。

 
 
  1. %PDF-1.6 #文件头+版本号,16进制读取文件0x25 0x50 0x44 0x46开头即证明是pdf文件 
  2. %çóÏÓ    #下面就是很多的Object对象 
  3. 2 0 obj  #Object对象,其中2是Obj顺序号,0是Obj的版本号,obj也是对象开始的标志 
  4. <<       #<<>>之间为Object对象的字典内容,包含关键字 
  5. [/ICCBased 3 0 R] 
  6. >> 
  7. Endobj   #Object结束关键字 
  8. 7 0 obj 
  9. << 
  10. /Filter 
  11. /FlateDecode   #流对象的压缩方式为/FlateDecode   
  12. /Length 148    #流对象的长度 
  13. >> 
  14. Stream         #流对象 
  15. #文件内容信息,注:此处为直观从而手动填写的 
  16. Endstream      #流对象结束标志 
  17. Endobj 
  18. 8 0 obj 
  19. << 
  20. /Contents 7 0 R              #页面内容对象的对象号为7 
  21. /MediaBox [0 0 595.2 841.68] #页面显示大小,以像素为单位 
  22. /PageIndex 1 
  23. /Parent 1 0 R               #其父对象号为1以及Pages对象 
  24. /Resources                  #该页包含的资源 
  25. <</Font <</F4 4 0 R >>      #字体的类型 
  26. /Shading <<>> 
  27. /XObject <<>>               #外部对象 
  28. /ColorSpace <</CS1 2 0 R>>  
  29. >> 
  30. /Type /Page 
  31. >> 
  32. Endobj 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在C语言实现PDF文件解析的过程可以包括以下几个步骤: 1. 首先,需要定义一些辅助函数,比如用于判断对象类型的函数。其,引用给出的示例代码是一个判断是否为图像对象的函数,而引用给出的示例代码是一个判断是否为字体描述符对象的函数。 2. 接下来,需要定义保存字体的函数。其,引用给出的示例代码是一个保存字体的函数,其包括了一些用于处理字体数据的变量和操作,比如定义一个缓冲区用于保存字体数据。 3. 在解析PDF文件之前,需要打开文件并读取其内容。可以使用C语言文件操作函数来实现这一步骤。 4. 接下来,需要解析PDF文件的结构。这包括解析PDF的头部信息、交叉引用表和对象流等。可以使用C语言的字符串处理函数和正则表达式来实现这一步骤。 5. 解析文件结构后,需要提取所需的数据,比如文本、图像和字体等。可以使用前面定义的辅助函数来判断对象类型,并使用相应的函数来提取数据。 6. 最后,需要进行清理工作,比如释放内存和关闭文件等。 需要注意的是,以上只是一个大致的框架,具体的实现可能会因为不同的PDF文件格式和解析需求而有所不同。在实际的开发,还需要考虑异常处理、内存管理和性能优化等方面的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [c++ mupdf 提取pdf文件里面图片](https://blog.csdn.net/u011269801/article/details/123951280)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值