-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Made the project installable with pip
- Loading branch information
Showing
6 changed files
with
227 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
# Created by .ignore support plugin (hsz.mobi) | ||
### Python template | ||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
env/ | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
|
||
# PyInstaller | ||
# Usually these files are written by a python script from a template | ||
# before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
*.manifest | ||
*.spec | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit test / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*,cover | ||
.hypothesis/ | ||
|
||
# Translations | ||
*.mo | ||
*.pot | ||
|
||
# Django stuff: | ||
*.log | ||
local_settings.py | ||
|
||
# Flask stuff: | ||
instance/ | ||
.webassets-cache | ||
|
||
# Scrapy stuff: | ||
.scrapy | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
target/ | ||
|
||
# IPython Notebook | ||
.ipynb_checkpoints | ||
|
||
# pyenv | ||
.python-version | ||
|
||
# celery beat schedule file | ||
celerybeat-schedule | ||
|
||
# dotenv | ||
.env | ||
|
||
# virtualenv | ||
venv/ | ||
ENV/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
|
||
# Rope project settings | ||
.ropeproject |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,9 +18,12 @@ def decode(x): | |
def decode(x): | ||
return x | ||
|
||
__author__ = 'Vesselin Bontchev <[email protected]>' | ||
__description__ = 'A VBA p-code disassembler' | ||
__license__ = 'GPL' | ||
__VERSION__ = '1.2.2' | ||
__uri__ = 'https://github.com/bontchev/pcodedmp' | ||
__VERSION__ = '1.2.3' | ||
__author__ = 'Vesselin Bontchev' | ||
__email__ = '[email protected]' | ||
|
||
def hexdump(buffer, length=16): | ||
theHex = lambda data: ' '.join('{:02X}'.format(ord(i)) for i in data) | ||
|
@@ -850,16 +853,18 @@ def disasmArg(indirectTable, identifiers, argOffset, endian, vbaVer, is64bit): | |
argName = 'ByRef ' + argName | ||
if (argOpts & 0x0200): | ||
argName = 'Optional ' + argName | ||
if ((flags & 0x0040) == 0): | ||
argName = 'ParamArray ' + argName + '()' | ||
# TODO - ParamArray arguments aren't disassebled properly | ||
#if ((flags & 0x0040) == 0): | ||
# argName = 'ParamArray ' + argName + '()' | ||
if (flags & 0x0020): | ||
argName += ' As ' | ||
argTypeName = '' | ||
if ((argType & 0xFFFF0000) == 0xFFFF0000): | ||
if (argType & 0xFFFF0000): | ||
argTypeID = argType & 0x000000FF | ||
argTypeName = getTypeName(argTypeID) | ||
else: | ||
argTypeName = getName(indirectTable, identifiers, argType + 6, endian, vbaVer, is64bit) | ||
# TODO - Custom type arguments aren't disassembled properly | ||
#else: | ||
# argTypeName = getName(indirectTable, identifiers, argType + 6, endian, vbaVer, is64bit) | ||
argName += argTypeName | ||
return argName | ||
|
||
|
@@ -917,7 +922,7 @@ def disasmFunc(indirectTable, declarationTable, identifiers, dword, opType, endi | |
funcDecl += ' Lib "' + libName + '" ' | ||
argList = [] | ||
while ((argOffset != 0xFFFFFFFF) and (argOffset != 0) and (argOffset + 26 < len(indirectTable))): | ||
argName = disasmArg(indirectTable,identifiers, argOffset, endian, vbaVer, is64bit) | ||
argName = disasmArg(indirectTable, identifiers, argOffset, endian, vbaVer, is64bit) | ||
argList.append(argName) | ||
argOffset = getDWord(indirectTable, argOffset + 20, endian) | ||
funcDecl += '(' + ', '.join(argList) + ')' | ||
|
@@ -1070,7 +1075,7 @@ def pcodeDump(moduleData, vbaProjectData, dirData, identifiers, is64bit, verbose | |
if (verbose): | ||
print('Internal Office version: 0x{:04X}.'.format(version)) | ||
# Office 2010 is 0x0097; Office 2013 is 0x00A3; | ||
# Office 2016 PC 32-bt is 0x00B2, 64-bit is 0x00D7, Mac is 0x00D9 | ||
# Office 2016 PC 32-bit is 0x00B2, 64-bit is 0x00D7, Mac is 0x00D9 | ||
if (version >= 0x6B): | ||
if (version >= 0x97): | ||
vbaVer = 7 | ||
|
@@ -1170,7 +1175,6 @@ def processProject(vbaParser, verbose, disasmOnly): | |
i += 1 | ||
print('') | ||
print('_VBA_PROJECT parsing done.') | ||
if (not disasmOnly): | ||
print('-' * 79) | ||
print('Module streams:') | ||
for module in codeModules: | ||
|
@@ -1185,6 +1189,7 @@ def processFile(fileName, verbose, disasmOnly): | |
# TODO: | ||
# - Handle VBA3 documents | ||
print('Processing file: {}'.format(fileName)) | ||
vbaParser = None | ||
try: | ||
vbaParser = VBA_Parser(fileName) | ||
if (vbaParser.ole_file is None): | ||
|
@@ -1194,9 +1199,10 @@ def processFile(fileName, verbose, disasmOnly): | |
processProject(vbaParser, verbose, disasmOnly) | ||
except Exception as e: | ||
print('Error: {}.'.format(e), file=sys.stderr) | ||
vbaParser.close() | ||
if (vbaParser): | ||
vbaParser.close() | ||
|
||
if __name__ == '__main__': | ||
def main(): | ||
parser = argparse.ArgumentParser(description='Dumps the p-code of VBA-containing documents.') | ||
parser.add_argument('-v', '--version', action='version', | ||
version='%(prog)s version {}'.format(__VERSION__)) | ||
|
@@ -1226,3 +1232,6 @@ def processFile(fileName, verbose, disasmOnly): | |
print('Error: {}.'.format(e), file=sys.stderr) | ||
sys.exit(-1) | ||
sys.exit(0) | ||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[bdist_wheel] | ||
universal = 1 | ||
|
||
[metadata] | ||
license_file = LICENSE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#!/usr/bin/env python | ||
|
||
import codecs | ||
import os | ||
import re | ||
|
||
try: | ||
from setuptools import setup | ||
except ImportError: | ||
from distutils.core import setup | ||
|
||
try: | ||
from pypandoc import convert | ||
|
||
def read_md(f): return convert(f, 'rst', format='md') | ||
|
||
except ImportError: | ||
print("warning: pypandoc module not found, " | ||
"could not convert Markdown to RST") | ||
|
||
def read_md(f): return open(f, 'r').read() | ||
|
||
################################################################### | ||
|
||
NAME = 'pcodedmp' | ||
PACKAGES = [NAME] | ||
META_PATH = os.path.join(NAME, NAME + '.py') | ||
KEYWORDS = ['vba', 'p-code', 'disassembler'] | ||
CLASSIFIERS = [ | ||
'Development Status :: 5 - Production/Stable', | ||
'Environment :: Console', | ||
'Intended Audience :: Developers', | ||
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', | ||
'Natural Language :: English', | ||
'Operating System :: OS Independent', | ||
'Programming Language :: Python', | ||
'Programming Language :: Python :: 2', | ||
'Programming Language :: Python :: 2.7', | ||
'Programming Language :: Python :: 3', | ||
'Programming Language :: Python :: 3.3', | ||
'Programming Language :: Python :: 3.4', | ||
'Programming Language :: Python :: 3.5', | ||
'Programming Language :: Python :: 3.6', | ||
'Topic :: Security', | ||
'Topic :: Software Development :: Disassemblers', | ||
'Topic :: Utilities', | ||
] | ||
INSTALL_REQUIRES = ['oletools>=0.50'] | ||
|
||
################################################################### | ||
|
||
HERE = os.path.abspath(os.path.dirname(__file__)) | ||
|
||
|
||
def read(*parts): | ||
""" | ||
Build an absolute path from *parts* and and return the contents of the | ||
resulting file. Assume UTF-8 encoding. | ||
""" | ||
with codecs.open(os.path.join(HERE, *parts), 'r', 'utf-8') as f: | ||
return f.read() | ||
|
||
|
||
META_FILE = read(META_PATH) | ||
|
||
|
||
def find_meta(meta): | ||
""" | ||
Extract __*meta*__ from META_FILE. | ||
""" | ||
meta_match = re.search( | ||
r"^__{meta}__ = ['\"]([^'\"]*)['\"]".format(meta=meta), | ||
META_FILE, re.M | ||
) | ||
if meta_match: | ||
return meta_match.group(1) | ||
raise RuntimeError('Unable to find __{meta}__ string.'.format(meta=meta)) | ||
|
||
entry_points = { | ||
'console_scripts': [ | ||
NAME + '=' + NAME + '.' + NAME + ':main', | ||
], | ||
} | ||
|
||
if __name__ == '__main__': | ||
setup( | ||
name=NAME, | ||
description=find_meta('description'), | ||
license=find_meta('license'), | ||
url=find_meta('uri'), | ||
version=find_meta('VERSION'), | ||
author=find_meta('author'), | ||
author_email=find_meta('email'), | ||
maintainer=find_meta('author'), | ||
maintainer_email=find_meta('email'), | ||
keywords=KEYWORDS, | ||
long_description=read_md('README.md'), | ||
packages=PACKAGES, | ||
classifiers=CLASSIFIERS, | ||
install_requires=INSTALL_REQUIRES, | ||
entry_points=entry_points, | ||
) |