ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

*******隐藏vba中的模块,起到保护vba代码的作用;以及用VBA来提取VBA Stream的演示

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-1-8 17:56 | 显示全部楼层
本帖已被收录到知识树中,索引项:其他专业开发
joforn 发表于 2013-1-8 17:53
早就可以还原了啊,哈哈。

只是最近在分析最复杂的WorkBook流,这个流要比VBA的复杂的多,所以没空玩那 ...

给个提示呀,俺自己写

TA的精华主题

TA的得分主题

发表于 2013-1-8 18:02 | 显示全部楼层
liucqa 发表于 2013-1-8 17:56
给个提示呀,俺自己写

http://msdn.microsoft.com/en-us/library/cc313094%28v=office.12%29.aspx
一切都在这个文档中。

TA的精华主题

TA的得分主题

发表于 2013-1-8 18:03 | 显示全部楼层
我自己一时也说不明白,楼上链接所给的文档说明非常的详细。就是有一点不好,是英文的(我看不懂英文)……

点评

嗯,俺也看不懂,这么些年全靠谷歌翻译过来的...  发表于 2013-1-8 19:31

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-1-9 01:23 | 显示全部楼层
本帖最后由 liucqa 于 2013-1-10 11:33 编辑
joforn 发表于 2013-1-8 18:03
我自己一时也说不明白,楼上链接所给的文档说明非常的详细。就是有一点不好,是英文的(我看不懂英文)……

找了个开源的代码,C写的,看不懂

  1. * @input: stream to read from
  2. * @offset: offset into it for start byte of compresse stream
  3. *
  4. * Decompresses an LZ compressed stream.
  5. *
  6. * Return value: A GByteArray that the caller is responsible for freeing
  7. **/
  8. GByteArray *
  9. gsf_msole_inflate (GsfInput *input, gsf_off_t offset)
  10. {
  11.     GByteArray *res;
  12.     unsigned    i, win_pos, pos = 0;
  13.     unsigned    mask, shift, distance;
  14.     guint8        flag, buffer [VBA_COMPRESSION_WINDOW];
  15.     guint8 const   *tmp;
  16.     guint16        token, len;
  17.     gboolean    clean = TRUE;

  18.     if (gsf_input_seek (input, offset, G_SEEK_SET))
  19.         return NULL;

  20.     res = g_byte_array_new ();

  21.     /* explaination from libole2/ms-ole-vba.c */
  22.     /* The first byte is a flag byte.  Each bit in this byte
  23.      * determines what the next byte is.  If the bit is zero,
  24.      * the next byte is a character.  Otherwise the  next two
  25.      * bytes contain the number of characters to copy from the
  26.      * umcompresed buffer and where to copy them from (offset,
  27.      * length).
  28.      */
  29.     while (NULL != gsf_input_read (input, 1, &flag))
  30.         for (mask = 1; mask < 0x100 ; mask <<= 1)
  31.             if (flag & mask) {
  32.                 if (NULL == (tmp = gsf_input_read (input, 2, NULL)))
  33.                     break;
  34.                 win_pos = pos % VBA_COMPRESSION_WINDOW;
  35.                 if (win_pos <= 0x80) {
  36.                     if (win_pos <= 0x20)
  37.                         shift = (win_pos <= 0x10) ? 12 : 11;
  38.                     else
  39.                         shift = (win_pos <= 0x40) ? 10 : 9;
  40.                 } else {
  41.                     if (win_pos <= 0x200)
  42.                         shift = (win_pos <= 0x100) ? 8 : 7;
  43.                     else if (win_pos <= 0x800)
  44.                         shift = (win_pos <= 0x400) ? 6 : 5;
  45.                     else
  46.                         shift = 4;
  47.                 }

  48.                 token = GSF_LE_GET_GUINT16 (tmp);
  49.                 len = (token & ((1 << shift) - 1)) + 3;
  50.                 distance = token >> shift;
  51.                 clean = TRUE;
  52. /*                fprintf (stderr, "Shift %d, token len %d, distance %d bytes %.2x %.2x\n",
  53.                 shift, len, distance, (token & 0xff), (token >> 8)); */

  54.                 for (i = 0; i < len; i++) {
  55.                     unsigned srcpos = (pos - distance - 1) % VBA_COMPRESSION_WINDOW;
  56.                     guint8 c = buffer [srcpos];
  57.                     buffer [pos++ % VBA_COMPRESSION_WINDOW] = c;
  58.                 }
  59.             } else {
  60.                 if ((pos != 0) && ((pos % VBA_COMPRESSION_WINDOW) == 0) && clean) {
  61.                     (void) gsf_input_read (input, 2, NULL);
  62.                     clean = FALSE;
  63.                     g_byte_array_append (res, buffer, VBA_COMPRESSION_WINDOW);
  64.                     break;
  65.                 }
  66.                 if (NULL != gsf_input_read (input, 1, buffer + (pos % VBA_COMPRESSION_WINDOW)))
  67.                     pos++;
  68.                 clean = TRUE;
  69.             }

  70.     if (pos % VBA_COMPRESSION_WINDOW)
  71.         g_byte_array_append (res, buffer, pos % VBA_COMPRESSION_WINDOW);
  72.     return res;
  73. }
复制代码


TA的精华主题

TA的得分主题

 楼主| 发表于 2013-1-9 23:07 | 显示全部楼层
本帖最后由 liucqa 于 2015-5-5 07:47 编辑
joforn 发表于 2013-1-8 18:03
我自己一时也说不明白,楼上链接所给的文档说明非常的详细。就是有一点不好,是英文的(我看不懂英文)……

俺搞出来了,直接用API就可以解压缩

不过,stream块要先还原成正确的顺序

等俺写个C#代码试试

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-1-10 01:00 | 显示全部楼层
本帖最后由 liucqa 于 2013-1-10 11:32 编辑

先搞个VBA的(看一楼),C#的随后。

TA的精华主题

TA的得分主题

发表于 2013-1-10 11:29 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2013-1-10 11:49 | 显示全部楼层
还没开始学,就发现看都看不懂

TA的精华主题

TA的得分主题

发表于 2013-1-10 12:16 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2013-1-10 12:47 | 显示全部楼层
关注。。。
liucqa 可否公布一下提取vba的vba代码呢?
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-12-23 05:07 , Processed in 0.045207 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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