2011-05-23 06:27:00 yuanmeng001 阅读数 1157

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

    国外技术评论家是怎样看待永中 Office 的?情况究竟怎样?

 

    近日, TopTenRERIEWS 对当今国际流行的主流办公套件 Office 进行比较,对永中 Office 的总评语如下:

         Ultimately, while EIOffice Enterprise is competent at undertaking basic word processing, spreadsheet editing and presentation construction, we found that we prefer more traditional programs for their more advanced features and ease of access. If you’re looking for a word processer with extra features, then EIOffice Enterprise is a great candidate. If you’re in the market for a versatile productivity suite, you might have better luck with some of our other products.

 

    由此,我们不难看出:评论家”比较喜欢”(“ prefer more” )永中 Office 比较先进的特点及易用性的传统程序。他们认为,如果你想寻找一款带有额外特点的文字处理程序,那么,永中 Office( 企业版 ) 是一个极好的候选者( a great candidate )。你如果在通用办公软件包市场上,选择其他 Office 产品也许会有较好的运气。这说明,他们将永中 Office 归入高档 Office 产品之列。

 

    说明:请见“ EI Office Enterprise” 一文, Evermore Software 出版发行。


2017-08-05 21:53:59 qq_20183489 阅读数 6255

本文介绍用Python简单读取*.docx文件信息,一些python-word库就是对这种方法的扩展。

介绍分两部分:

  • Word(*.docx)文件简述
  • Python提取Word信息

Word(*.docx)文件简述

大约在2008年以前,Office产品中Word用.doc文件格式,这种二进制格式很难与其他软件兼容。
为了跟上时代,微软采用类XML格式标准定义其新版Word文件.docx。
.docx实际上是一个zip的压缩文件,比如我们有一个test.docx的文件:
这里写图片描述
其内容如下:
这里写图片描述
改变其后缀名为test.zip,然后解压,会得到如下文件:
这里写图片描述
其中Word文件的正文内容被保持在word/document.xml中,我们可以打开查看:
这里写图片描述

Python提取Word信息

根据Word(.docx)文件格式,我们遵循如下步骤进行正文信息的提取:
1 解压.docx文件
2 用BeautifulSoup解析word/document.xml提取正文信息

具体代码如下:

from zipfile import ZipFile
from bs4 import BeautifulSoup

document=ZipFile('test.docx')
xml=document.read("word/document.xml")
wordObj=BeautifulSoup(xml.decode("utf-8"))
texts=wordObj.findAll("w:t")
for text in texts:
    print(text.text)
2018-12-12 11:00:52 stone0823 阅读数 3349

微软 Office 提供基于 COM 接口的编程。Python 通过 pywin32 可以方便地调用各组件。如果下载和安装 pywin32 有困难,可以到 Sourceforge 的镜像网摘查找合适的版本。

单一账号

import win32com.client as win32

def send_mail():
    outlook = win32.Dispatch('Outlook.Application')

    mail_item = outlook.CreateItem(0) # 0: olMailItem

    mail_item.Recipients.Add('someone@qq.com')
    mail_item.Subject = 'Mail Test'

    mail_item.BodyFormat = 2          # 2: Html format
    mail_item.HTMLBody  = '''
        <H2>Hello, This is a test mail.</H2>
        Hello Guys. 
        '''
    mail_item.Send()

if __name__ == '__main__':
    send_mail()

多账号发送邮件

如果 Outlook 有多个账号,需要选择账号发送邮件,需要在代码中对账号进行判断,代码如下:

def send_mail():
    outlook_app = win32.Dispatch('Outlook.Application')

    # choose sender account
    send_account = None
    for account in outlook_app.Session.Accounts:
        if account.DisplayName == 'sender@hotmail.com':
            send_account = account
            break

    mail_item = outlook_app.CreateItem(0)   # 0: olMailItem

    # mail_item.SendUsingAccount = send_account not working
    # the following statement performs the function instead
    mail_item._oleobj_.Invoke(*(64209, 0, 8, 0, send_account))

    mail_item.Recipients.Add('receipient@qq.com')
    mail_item.Subject = 'Test sending using particular account'
    mail_item.BodyFormat = 2   # 2: Html format
    mail_item.HTMLBody = '''
        <H2>Hello, This is a test mail.</H2>
        Hello Guys. 
        '''

    mail_item.Send()


if __name__ == '__main__':
    send_mail()

这里有点黑魔法,直接设置 mail_item.SendUsingAccount 不会起作用,返回值是 None, 永远从第一个邮箱账号发送邮件,我使用的是 Office 365 版。需要调用 _oleobj_.Invoke() 方法。后面列出了参考链接。

本质上,这种方法是调用 COM 组件,可以查询微软的开发帮助了解相关对象的属性和方法,比如我想知道 Account 的细节,就特意参考了下面这篇帮助:https://docs.microsoft.com/zh-cn/office/vba/api/outlook.account 。COM 编程与语言无关。另外可以在 Outlook 中 ALT + F11,进入 VBE 环境,然后 F2 进入对象浏览器界面查看比如下面的界面显示了 Account 的属性和方法:

关于调试

python 作为动态语言,通过 Debug 获取 COM 对象信息并不是很方便,比如下面代码:

import win32com.client as win32

def print_outlook_accounts():
    outlook_app = win32.Dispatch('Outlook.Application')

    for account in outlook_app.Session.Accounts:
        print (account.DeliveryStore.DisplayName)

if __name__ == '__main__':
    send_mail()

设置断点的调试界面:

我们只知道 account 是一个 COM Object,account 包含的信息很多都是 unknown 的。碰到这种情况,我一般用 C# 或者 VBA 编写代码进行调试。如果我需要详细了解 account 的属性和方法,在 Office 的任何组件中,比如 Excel,写一段下面的代码:

Public Sub Print_Outlook_Accounts()

    ' 工具 -> 引用:添加 Microsoft Outook Object Library 引用
    
    Dim outlookApp As New Outlook.Application
    Dim accounts As Outlook.accounts
    
    Set accounts = outlookApp.Session.accounts
    
    Dim account As Outlook.account
    For Each account In accounts
        Debug.Print account.DisplayName
    Next
End Sub

显示出监视窗口,设置断点,获取 accounts 信息:

在监视窗口添加变量 accounts:

展开:


Item 1 和 Item 2 表示有两个账号,现在我们想看到 Item 2 的账号信息,将 Item 2 展开:


DeliveryStore 属性也包含 account 的信息,可以展开查看。

参考

2019-08-25 12:52:03 gdjlc 阅读数 280

python-docx库可用于创建和编辑Microsoft Word(.docx)文件。
官方文档:https://python-docx.readthedocs.io/en/latest/index.html

备注:
doc是微软的专有的文件格式,docx是Microsoft Office2007之后版本使用,其基于Office Open XML标准的压缩文件格式,比 
doc文件所占用空间更小。docx格式的文件本质上是一个ZIP文件,所以其实也可以把.docx文件直接改成.zip,解压后,里面的 
word/document.xml包含了Word文档的大部分内容,图片文件则保存在word/media里面。
python-docx不支持.doc文件,间接解决方法是在代码里面先把.doc转为.docx。


一、安装包

pip3 install python-docx

二、创建word文档

下面是在官文示例基础上对个别地方稍微修改,并加上函数的使用说明

from docx import Document
from docx.shared import Inches

document = Document()

#添加标题,并设置级别,范围:0 至 9,默认为1
document.add_heading('Document Title', 0)

#添加段落,文本可以包含制表符(\t)、换行符(\n)或回车符(\r)等
p = document.add_paragraph('A plain paragraph having some ')
#在段落后面追加文本,并可设置样式
p.add_run('bold').bold = True
p.add_run(' and some ')
p.add_run('italic.').italic = True

document.add_heading('Heading, level 1', level=1)
document.add_paragraph('Intense quote', style='Intense Quote')

#添加项目列表(前面一个小圆点)
document.add_paragraph(
    'first item in unordered list', style='List Bullet'
)
document.add_paragraph('second item in unordered list', style='List Bullet')

#添加项目列表(前面数字)
document.add_paragraph('first item in ordered list', style='List Number')
document.add_paragraph('second item in ordered list', style='List Number')

#添加图片
document.add_picture('monty-truth.png', width=Inches(1.25))

records = (
    (3, '101', 'Spam'),
    (7, '422', 'Eggs'),
    (4, '631', 'Spam, spam, eggs, and spam')
)

#添加表格:一行三列
# 表格样式参数可选:
# Normal Table
# Table Grid
# Light Shading、 Light Shading Accent 1 至 Light Shading Accent 6
# Light List、Light List Accent 1 至 Light List Accent 6
# Light Grid、Light Grid Accent 1 至 Light Grid Accent 6
# 太多了其它省略...
table = document.add_table(rows=1, cols=3, style='Light Shading Accent 2')
#获取第一行的单元格列表
hdr_cells = table.rows[0].cells
#下面三行设置上面第一行的三个单元格的文本值
hdr_cells[0].text = 'Qty'
hdr_cells[1].text = 'Id'
hdr_cells[2].text = 'Desc'
for qty, id, desc in records:
    #表格添加行,并返回行所在的单元格列表
    row_cells = table.add_row().cells
    row_cells[0].text = str(qty)
    row_cells[1].text = id
    row_cells[2].text = desc

document.add_page_break()

#保存.docx文档
document.save('demo.docx')

创建的demo.docx内容如下:

三、读取word文档

from docx import Document

doc = Document('demo.docx')

#每一段的内容
for para in doc.paragraphs:
    print(para.text)

#每一段的编号、内容
for i in range(len(doc.paragraphs)):
    print(str(i),  doc.paragraphs[i].text)

#表格
tbs = doc.tables
for tb in tbs:
    #行
    for row in tb.rows:    
        #列    
        for cell in row.cells:
            print(cell.text)
            #也可以用下面方法
            '''text = ''
            for p in cell.paragraphs:
                text += p.text
            print(text)'''

运行结果:

Document Title
A plain paragraph having some bold and some italic.
Heading, level 1
Intense quote
first item in unordered list
second item in unordered list
first item in ordered list
second item in ordered list
Document Title
A plain paragraph having some bold and some italic.
Heading, level 1
Intense quote
first item in unordered list
second item in unordered list
first item in ordered list
second item in ordered list



Qty
Id
Desc
101
Spam
422
Eggs
631
Spam, spam, eggs, and spam
[Finished in 0.2s]
2017-05-11 10:48:16 counsellor 阅读数 3926

【前言】

前天fireeye出了一份最新的关于APT28的报告,提到了最新的0day组合攻击。其中,包括微软Office的两个EPS图形文件的远程代码执行漏洞 ( CVE-2017-0261, CVE-2017-0262 ),和一个本地提权漏洞(CVE-2017-0263 ). 具体细节已经公开. 2015年火眼曾经公开了一个关于EPS的高危漏洞(CVE-2015-2545),让人记忆深刻。

0x01 EPS文件

CVE-2017-0262这个流行样本是名为【Trump’s_Attack_on_Syria_English.docx 】的docx文档,里面嵌入了恶意的eps文件. 个人认为这名字诱惑力很大,在中国的话可以起名为”2017年上海国际车展车模联系名单”,”震撼!女大学生夜跑被..”的头条体。 扯远了,回头。

这个EPS恶意文件通过XOR加密算法做了简单的混淆。解密用的key是0xc45d6491.

$ cat word/media/image1.eps
%!PS-Adobe-3.0
%%BoundingBox:   36   36 576 756
%%Page: 1 1
/A3{ token pop exch pop } def 
/A2 <c45d6491> def 
/A4{ 
/A1 exch def 
0 1 A1 length 1 sub 
{ /A5 exch def A1 A5 2 copy get A2 A5 4 mod get xor put } for A1 } def 
<bf7d4bd9[..这个是很长的加密后文本..]b97d44b1> A4 A3 exec quit

简单的方法是安装postscript程序执行这段代码,即可得到解密结果。

0x02 EPS文件解析

问题来了-什么是PostScript?

PostScript是一种用于描述矢量图形的页面描述语言。简单的说,用PostScript语言写成的文件就是PS格式的图片,一般文件后缀用 ps ,简称为PS文件。作为语言,该文件是可以用编辑器打开查看的。

看到“页面描述语言”这个词,可能会联想到HTML等网页标记语言。没错, PostScript的主要作用就是记载需要打印出的各种文字和图形,但它还是 一种简单的编程语言,支持分支、循环等控制结构,以及数组、字典等简单 的数据结构。

运行PostScript

查看PostScript文件需要使用PostScript解释器。最常见的解释器就是 GhostScript。Windows版只需下载 gs871w32.exe安装即可。Linux下一般都包含在发行版中,使用相应的 管理程序自动安装即可,例如Ubuntu下可以这样安装

$ sudo apt-get install ghostscript

安装完成后即可从开始菜单中启动GhostScript(Linux下直接使用 gs 命令启动)。 启动后出现提示符:

GS>

随后,可以直接在提示符下输入命令,也可以先把命令写成*.ps文件, 再用GhostScript运行。也可以在window下运行,安装包请自行search。

0x03 XOR解密代码

笔者这里手贱,用python解混淆,下面祭献出源码:

#!/usr/bin/env python
#-*- coding: utf-8 -*-
#coding=utf-8
import binascii

b = "c45d6491"
a = "bf7d4bd9a13112f4b03407f0e43b0dffa03b0bffb07d55a1f47d17f2a53101f7ab3310b1b73810f7ab3310b1a3310bf3a53100f8a72944f3a13a0dffe47225a0f77d50a1f46d54a1e43901f7e47225a0f67d25a0f77d55a7e43400f8b27d55b1a53900b1a03802b1eb1c5cb1bf7d4bd0f16944f4bc3e0cb1a03802b1eb1c56a7e4381cf2ac7d00f4a27d4bd0f76a44d0f66b44fda13303e5ac7d00f4a27d4bd0f16a44d0f16944fda13303e5ac7d00f4a27d4bd0f06c44a3f16b44f5a13b44be856c55b1856e53b1856955b1ad390de7e43901f7e42644be856c55b1856c55b1f57d17e4a67d00f4a27d25a0f57d54b1a8291fb1a1250de5e42044f8a27d25a3f27d25a0f57d25a5f57d09e4a87d25a4f07d14e4b0340ae5a12f12f0a87d19b1a8320be1e41c56a7e42044f3"

def fuckit(decrypt_key, data):
    length = len(data)
    m_data = []
    for i in range(length):
        m_index = i % len(decrypt_key)
        m_key = decrypt_key[m_index]

        m_data +=  chr(ord(data[i])^ ord(m_key))
    data = "".join(m_data)
    return data


if __name__ == '__main__':
    #with open("postscript.txt", 'r') as fp:
    #    a = fp.read()
    m_b = list(binascii.unhexlify(b) )
    m_a = list(binascii.unhexlify(a) )
    print fuckit(m_b,m_a)

被解密文本如下:

这里写图片描述

0x04 参考

PostScript入门(1)-基本知识 charlee.li

警惕利用CVE-2015-2545漏洞进行的攻击

GMT参考手册

/* 代码不写include的不是好代码,文章不写参考的不是好文章。*/

没有更多推荐了,返回首页