4 Commits
1.5.1 ... 1.6.1

Author SHA1 Message Date
ben
bc359714d7 Fix help. 2018-09-29 23:42:07 +02:00
ben
875747ad7a Add zipany format. v1.6 2018-09-29 23:37:54 +02:00
ben
200508be7f Fix PDF offset with acrobat-compatibility option. 2018-09-29 22:04:05 +02:00
ben
fc7e44a646 Rename pdfraw to pdfany and allow 2 payloads. v1.5.2 2018-09-29 14:06:08 +02:00
6 changed files with 126 additions and 56 deletions

View File

@@ -2,7 +2,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from .polyglotpdfzip import PolyglotPdfZip from .polyglotpdfzip import PolyglotPdfZip
from .polyglotpdfraw import PolyglotPdfRaw from .polyglotpdfany import PolyglotPdfAny
from .polyglotzippdf import PolyglotZipPdf from .polyglotzippdf import PolyglotZipPdf
from .polyglotszippdf import PolyglotSZipPdf from .polyglotszippdf import PolyglotSZipPdf
from .polyglotzipany import PolyglotZipAny

View File

@@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
import logging
'''
|-------------------------------| -
|--------- PDF Header ----------K1 | J1
|-------------------------------| -
|---- PDF OBJ 1 = Payload 1 ----K2 |
|-------------------------------| -
|---- Original PDF Ojbects -----K3 | J2
|-------------------------------| -
|-- PDF Last OBJ = Payload 2 ---K4 |
|-------------------------------| |
|---------- Xref Table ---------| |
|-------------------------------K5 |
|----------- Trailer -----------| |
|-------------------------------| |
'''
class PolyglotPdfAny():
from PdfFileTransformer import Pdf
def __init__(self, Pdf, payload1filename, payload2filename):
self.buffer = bytearray()
self.pdf = Pdf
self.payload1 = bytearray()
if payload1filename is not None:
with open(payload1filename, "rb") as f:
self.payload1 = f.read()
self.payload2 = bytearray()
if payload2filename is not None:
with open(payload2filename, "rb") as f:
self.payload2 = f.read()
def generate(self):
k2stream = self.payload1
if len(k2stream) > 0:
self.pdf.insert_new_obj_stream_at_start(k2stream)
k4stream = self.payload2
if len(k4stream) > 0:
self.pdf.insert_new_obj_stream_at_end(k4stream)
self.buffer = self.pdf.get_build_buffer()
def write(self, filename):
fd = open(filename, "wb")
fd.write(self.buffer)
fd.close()

View File

@@ -1,40 +0,0 @@
# -*- coding: utf-8 -*-
import logging
'''
|-------------------------------| -
|--------- PDF Header ----------K1 | J1
|-------------------------------| -
|----- PDF OBJ 1 = RAW Data ----K2 |
|-------------------------------| -
|---- Original PDF Ojbects -----K3 | J2
|-------------------------------| -
|---------- Xref Table ---------| |
|-------------------------------K5 |
|----------- Trailer -----------| |
|-------------------------------| |
'''
class PolyglotPdfRaw():
from PdfFileTransformer import Pdf
def __init__(self, Pdf, Raw_filename):
self.buffer = bytearray()
self.pdf = Pdf
self.raw_filename = Raw_filename
self.buffer = bytearray()
def generate(self):
raw_buffer = bytearray()
with open(self.raw_filename, "rb") as f:
raw_buffer = f.read()
k2_stream = raw_buffer
self.pdf.insert_new_obj_stream_at_start(k2_stream)
self.buffer = self.pdf.get_build_buffer()
def write(self, filename):
fd = open(filename, "wb")
fd.write(self.buffer)
fd.close()

View File

@@ -81,6 +81,8 @@ class PolyglotSZipPdf(PolyglotPdfZip):
k2_stream_offset = new_pdf.get_first_stream_offset() k2_stream_offset = new_pdf.get_first_stream_offset()
new_pdf.file_offset = offset new_pdf.file_offset = offset
if self.acrobat_compatibility:
new_pdf.file_offset = new_pdf.file_offset + 1
pdf_buffer = new_pdf.get_build_buffer() pdf_buffer = new_pdf.get_build_buffer()
j2 = pdf_buffer[k2_stream_offset + size_k2_stream:] j2 = pdf_buffer[k2_stream_offset + size_k2_stream:]

View File

@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
import logging
'''
|-------------------------------| -
|---------- Payload 1 ----------K1 | J1
|-------------------------------| -
|---- ZIP Local File Header ----K2 |
|-------------------------------| -
|---------- Payload 2-----------K3 | J2
|-------------------------------| -
|---- ZIP Central Directory ----K4 |
|-------------------------------| |
|--- End of Central Directory --K5 |
|-------------------------------| |
'''
class PolyglotZipAny():
from ZipFileTransformer import Zip
def __init__(self, Zip, payload1filename, payload2filename):
self.buffer = bytearray()
self.zip = Zip
self.payload1 = bytearray()
if payload1filename is not None:
with open(payload1filename, "rb") as f:
self.payload1 = f.read()
self.payload2 = bytearray()
if payload2filename is not None:
with open(payload2filename, "rb") as f:
self.payload2 = f.read()
def generate(self):
self.zip.add_data_to_file(self.payload1, self.payload2, True)
self.buffer = self.zip.buffer
def write(self, filename):
fd = open(filename, "wb")
fd.write(self.buffer)
fd.close()

View File

@@ -9,7 +9,9 @@ from ZipFileTransformer import Zip
from PolyglotFile import PolyglotZipPdf from PolyglotFile import PolyglotZipPdf
from PolyglotFile import PolyglotPdfZip from PolyglotFile import PolyglotPdfZip
from PolyglotFile import PolyglotSZipPdf from PolyglotFile import PolyglotSZipPdf
from PolyglotFile import PolyglotPdfRaw from PolyglotFile import PolyglotPdfAny
from PolyglotFile import PolyglotZipAny
def main(): def main():
@@ -19,12 +21,18 @@ def main():
'* zippdf: Generate a file valid as ZIP and PDF.' + '* zippdf: Generate a file valid as ZIP and PDF.' +
' The format is closest to ZIP.\n' + ' The format is closest to ZIP.\n' +
'* szippdf: Generate a file valid as ZIP and PDF.' + '* szippdf: Generate a file valid as ZIP and PDF.' +
' The format is strictly a ZIP.' + ' The format is strictly a ZIP.\n' +
' Archive is modified.\n' + ' Archive is modified.\n' +
'* pdfraw: Generate a file strictly valid as a PDF ' + '* pdfany: Generate a valid PDF file with payload1' +
'with a custom first object content.') ' file content as first object\n' +
' or/and payload2 file' +
' content as last oject.\n' +
'* zipany: Generate a valid ZIP file with payload1' +
' file content at start of file\n' +
' or/and payload2 file content between' +
' LFH and CD.\n')
usage_str = '%(prog)s format [options] output-file' usage_str = '%(prog)s format [options] output-file'
epilog_str = 'TruePolyglot v1.5.1' epilog_str = 'TruePolyglot v1.6.1'
frm = argparse.RawTextHelpFormatter frm = argparse.RawTextHelpFormatter
parser = argparse.ArgumentParser(description=description_str, parser = argparse.ArgumentParser(description=description_str,
epilog=epilog_str, epilog=epilog_str,
@@ -33,14 +41,17 @@ def main():
parser.add_argument('format', nargs='+', choices=["pdfzip", parser.add_argument('format', nargs='+', choices=["pdfzip",
"zippdf", "zippdf",
"szippdf", "szippdf",
"pdfraw"], "pdfany",
"zipany"],
help='Output polyglot format') help='Output polyglot format')
parser.add_argument('--pdffile', dest='pdffile', parser.add_argument('--pdffile', dest='pdffile',
help='PDF input file') help='PDF input file')
parser.add_argument('--zipfile', dest='zipfile', parser.add_argument('--zipfile', dest='zipfile',
help='ZIP input file') help='ZIP input file')
parser.add_argument('--rawfile', dest='rawfile', parser.add_argument('--payload1file', dest='payload1file',
help='RAW input file') help='Payload 1 input file')
parser.add_argument('--payload2file', dest='payload2file',
help='Payload 2 input file')
parser.add_argument('--acrobat-compatibility', parser.add_argument('--acrobat-compatibility',
dest='acrobat_compatibility', dest='acrobat_compatibility',
help='Add a byte at start for Acrobat Reader compatibility with szippdf format', help='Add a byte at start for Acrobat Reader compatibility with szippdf format',
@@ -57,11 +68,12 @@ def main():
if args.acrobat_compatibility and args.format[0] != "szippdf": if args.acrobat_compatibility and args.format[0] != "szippdf":
parser.error('--acrobat-compatibility is for szippdf only') parser.error('--acrobat-compatibility is for szippdf only')
if "pdf" in args.format[0] and args.pdffile is None: if "pdf" in args.format[0] and args.pdffile is None:
parser.error('pdffile is required') parser.error('pdffile is required')
if "zip" in args.format[0] and args.zipfile is None: if "zip" in args.format[0] and args.zipfile is None:
parser.error('zipfile is required') parser.error('zipfile is required')
if "raw" in args.format[0] and args.rawfile is None: if ("any" in args.format[0] and args.payload1file is None and
parser.error('rawfile is required') args.payload2file is None):
parser.error('payload1file or payload2file is required')
if args.verbose == "none": if args.verbose == "none":
logging.basicConfig(level=logging.CRITICAL) logging.basicConfig(level=logging.CRITICAL)
@@ -84,9 +96,13 @@ def main():
p = Pdf(args.pdffile) p = Pdf(args.pdffile)
z = Zip(args.zipfile) z = Zip(args.zipfile)
a = PolyglotSZipPdf(p, z, args.acrobat_compatibility) a = PolyglotSZipPdf(p, z, args.acrobat_compatibility)
if args.format[0] == "pdfraw": if args.format[0] == "pdfany":
p = Pdf(args.pdffile) p = Pdf(args.pdffile)
a = PolyglotPdfRaw(p, args.rawfile) a = PolyglotPdfAny(p, args.payload1file, args.payload2file)
if args.format[0] == "zipany":
z = Zip(args.zipfile)
a = PolyglotZipAny(z, args.payload1file, args.payload2file)
a.generate() a.generate()
a.write(args.output_file[0]) a.write(args.output_file[0])