ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 1987|回复: 3

[分享] vbaProject.bin文件解析,从中提取VBA代码过程

[复制链接]

TA的精华主题

TA的得分主题

发表于 2021-11-10 15:33 | 显示全部楼层 |阅读模式
最近有个从xlsm文件中直接提取VBA代码的需求.研究了2日,成功达到目标,现在把研究的过程记录一下,让有同样需求的人少走点弯路,自己也可以加深印象

一开始我搜寻各种资料,了解到xlsm文件,把后缀名改为rar,通过压缩工具打开,可以看到xlsm文件其实就是一堆文件组成的一个压缩包.xl下面有一个vbaProject.bin文件,,我们的vba代码也就保存在里面.
用程序去读vbaProject.bin文件非常容易做到,oject.bin是一个二进制的文件,属于复合文档吧,,他有一定的结构,这方面论坛有的前辈已经讲得很清楚了
https://club.excelhome.net/thread-227502-1-1.html
可以先去上面的链接先看一看复合文档的各种细节.


首先先新建一个xlsm文件,随便建个模块,写一个简单的VBA代码


1.jpg
接下来将这个文件的 vbaProject.bin提取出来...现在开始分析这个二进制文件,在这之前还需要准备一个查看二进制文件的工具,我用的是UltraEdit,还需要[MS-OVBA] 1.pdf,这个是VBA文件格式结构的官方文档,不清楚的就需要上这个文件上查了,同时还有一个查看复合文档的小软件,名字是offvis.exe,,,网上搜去吧,,大于2M传不上来
资料1.rar (1.66 MB, 下载次数: 53)


TA的精华主题

TA的得分主题

 楼主| 发表于 2021-11-10 18:22 | 显示全部楼层
2.jpg
通过OffVis.exe打开vbaProject.bin,可以看到,这个二进制文件分成4个大块,OLESSHeader,FAT,MiniFAT,DirectoryEntries


文件一开头就是OLESSHeader,,一开始可以通过DifatSect1,NumDifatSects,DiFat[109],这三个属性找到所有的DiFat,他是一个4字节的数组,数量可能超过109,超出部分会存在别的地方


通过DiFat又可以找到FAT,FAT同样是4字节的数组,


接下来是DirectoryEntries,他里面存储的是一些相当于目录的地址信息,他固定128个字节.包括位置在哪,名字是什么,大小多大,这样的信息,(根据这个可以找到对应的流,比如说模块的流,代码就存在这些流里面)


接下来是需要通过MiniFatSect1找MiniFAT,这个主要是找长度小于4096的流存在这里面..这些流在二进制文件中可能不是连续的,所以需要把这些流完整连续的找出来..再去偏移算具体在从哪到哪

然后就可以开始去找流了,根据DirectoryEntries中,如果type是2就表示是流,大于4096就以FAT中的数据去寻找具体从哪到哪,,如果小于4096就以MiniFAT中的数据去找具体哪到哪


看论坛前辈们的帖子也就走到这一步,顺利将流提取出来了
流.rar (3.53 KB, 下载次数: 28)

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-11-11 11:36 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
一直到提取流这一步,多看下其他人写的介绍复合文档的帖子就很容易能做到.但是后面该怎么做就没找到什么资料了,,没办法,自己看官方的介绍文档吧,.
3.jpg
20页中有这样的一段介绍,上说VBA代码在Module流中,但是有哪些Module,叫什么名字,在什么位置不知道.这些信息保存在dir流中,而且这个dir是肯定存在的.那第一步先到dir中读这些信息.具体的让我们跳到2.3.4.2(30页)中去看
30页第一段又说The entire stream MUST be compressed as specified in Compression (section 2.4.1).也就是说整段流都被压缩过,压缩的,翻到2.4.1(54页),,这关于这个压缩过程的介绍也太多了..没耐心看下去..但看到这个压缩技术叫run length encoding.OK,网上搜一下,搜到一个解压的API RtlDecompressBuffer  直接用就行.


把整段dir流通过RtlDecompressBuffer解压.发现失败了..返回值是个非0值,正确应该是返回0.翻来覆去查看文档..没看出来问题出在哪
4.jpg
106页有个最简单的例子,,01 03 B0 02 61 45 00,解压缩的话结果是73个61,试了一下,同样不行,,,那就试下用RtlCompressBuffer将73个61压缩看看结果是什么,结果是03 B0 02 61 45 00,原来是不要第1个字节拿去解压缩.


刚好看了下dir流,第1个字节也是1,把第1个01去掉再解压缩,函数返回0(表示成功了)
但这个解压缩后的文件仍是个二进制的文件.隐约能看到Thisworkbook,sheet1,之类的东西,从官方文档30页开始,在介绍dir流,前面都是些无关紧要的东西,一直往下翻
5.jpg
30页翻到50页,这里说count(2字节),代表Module的数量,刚好非常巧.前面ID,SIZE是个固定值,为00 0F 00 00 00 02,,我们直接去找找看(注意是低字节在前,搜索应该搜0F 00 02 00 00 00)
6.jpg
搜到这个地方,往后2个字节是Module的数量,为03 00,倒过过就是0x0003,也就是3个模块.做到这一步,几乎可以肯定,前面做得没错.因为这3个模块是thisworkook,sheet1,模块1


7.jpg
一直翻到46页,这里ID 0x0019,下面4字节是长度,然后是模块的名字


8.jpg
搜19 00,后个4个字节是0C 00 00 00,这个表示的是名字的长度,倒过来,表示十进制的12,也就是名字长度12,往后数12个字节,在VBA中可以能过StrConv转成文字,就是thisworkbook
9.jpg
再往后翻到48页, 在文档中搜31 00 04 00 00 00,就可以定位到TextOffset,这个表示VBA代码在module流中的偏移位置..也就是知道这个偏移量就可以定位到代码了


10.jpg
直接定位到模块1的偏移量,应该是0x00000388,


11.jpg
打开模块1流文件,定位到388(这个388是十六进制),刚好可以看到这个地方以01开始,应该是以run length encoding压缩过..去掉01,通过RtlDecompressBuffer解压,再StrConv可转化成文本
12.jpg


得到以上结果.到这一步,成功达到目的,再试了试试其他文件也都顺利,包括 word的vba代码也都能顺序取到.OK
后面什么模块隐藏,让工程不可查看,,都可以修改这个vbaProject.bin文件做到,难度也不大


流2.rar (3.32 KB, 下载次数: 30)


评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2021-11-12 19:26 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
高大上,看不懂!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-18 03:46 , Processed in 0.038977 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表