SkillAgentSearch skills...

Pdvzip

PNG-ZIP-JAR Polyglot File Tool

Install / Use

/learn @CleasbyCode/Pdvzip

README

pdvzip

Embed a ZIP or JAR file within a PNG image to create a tweetable and "executable" PNG polyglot file.
Share the image on X-Twitter and a few other compatible platforms, which retains the embedded archive.

Note: For compatibility reasons, please do not use encrypted / password protected ZIP files.

There is also a Web edition, which you can use immediately, as a convenient alternative to downloading and compiling the CLI source code. Web file uploads are limited to 20MB.

Based on the similar idea by David Buchanan, from his original Python program tweetable-polyglot-png,
pdvzip uses different methods for storing and extracting embedded files within a PNG image.

Demo Image
Credits: Image - @KCP228 PowerShell Script - @gierrofo

The Linux/Windows extraction script is stored within the iCCP chunk of the PNG image. The embedded ZIP/JAR file is stored within its own IDAT chunk, which will be the last IDAT chunk of the image file.

With pdvzip, you can embed a ZIP/JAR file up to a maximum size of *2GB (cover image + archive file). Compatible sites, listed below, have their own much smaller size limits.

Compatible Platforms

Posting size limit measured by the combined size of the cover image + compressed data file.

  • X-Twitter (5MB), Flickr (200MB), ImgBB (32MB), PostImage (32MB), ImgPile (8MB).

Image dimension size limits:

  • PNG-32/24 (Truecolor) 68x68 Min. - 900x900 Max.
  • PNG-8 (Indexed-color) 68x68 Min. - 4096x4096 Max.

Usage (Linux)

$ chmod +x compile_pdvzip.sh
$ ./compile_pdvzip.sh

Compiling pdvzip...
Compilation successful. Executable 'pdvzip' created.

$ sudo cp pdvzip /usr/bin
$ pdvzip

Usage: pdvzip <cover_image> <zip/jar>
       pdvzip --info

$ pdvzip my_cover_image.png document_pdf.zip

Created PNG-ZIP polyglot image file: pzip_55183.png (4038367 bytes).

Complete!

$ pdvzip my_cover_image.png hello_world.jar

Created PNG-JAR polyglot image file: pjar_19662.png (1016336 bytes).

Complete!

Extracting Your Embedded File(s)

Important: When saving images from X-Twitter, click the image in the post to fully expand it, before saving.

The following section covers the extraction of embedded ZIP files. JAR files are covered later.

pdvzip (for Linux) will attempt to automatically set executable permissions on newly created polyglot image files.

You will need to manually set executable permissions using chmod on these polyglot images downloaded from hosting sites or copied from another machine.

https://github.com/user-attachments/assets/8feca575-b135-4f58-839a-2159fce09b44

https://github.com/user-attachments/assets/77472a02-52dd-4a5c-a035-b30dcc842cce

https://github.com/user-attachments/assets/a143e694-31f5-4235-ace1-30217fe8ab41

Linux - using bash (or sh) shell environment.


$ ./pzip_55183.png

For any other Linux shell environment, you will probably need to invoke bash (or sh) to run the image file.


mx% bash ./pzip_55183.png 

Alternative extraction (Linux). Using wget to download and run the image directly from the hosting site.
X-Twitter wget example: Image with embedded python script.


$ wget -O Fibo.png "https://pbs.twimg.com/media/GLXTYeCWMAAA6B_.png";chmod +x Fibo.png;bash ./Fibo.png

Windows (Rename the image file extension to '.cmd')


G:\demo> ren pzip_55183.png pzip_55183.cmd
G:\demo> .\pzip_55183.cmd

Alternative extraction (Windows). Using iwr to download and run the image directly from the hosting site.
Flickr iwr example: Image with embedded mp4 video file.


iwr -o swing.cmd "https://live.staticflickr.com/65535/54025688614_2f9d474cba_o_d.png";.\swing.cmd

Opening the .cmd file from the desktop, on its first run, Windows may display a security warning.
Clear this by clicking 'More info' then select 'Run anyway'.

To avoid security warnings, run the file from a Windows console, as shown in the above example.

The file (or folder) within the ZIP archive that appears first within the ZIP file record, determines what extraction script, based on file type, is used.

For common video & audio files, Linux will first attempt to use the media player mpv or vlc if no mpv. Firefox is used as a last resort. Windows uses the default media player.

PDF - Linux will use evince or firefox. Windows uses the default PDF viewer.
Python - Linux & Windows use python3 to run these programs.
PowerShell - Linux uses pwsh (if installed), Windows uses either powershell.exe or pwsh.exe to run these scripts. Folder - Linux uses xdg-open, Windows uses powershell.exe with II (Invoke-Item) command, to open zipped folders.

For any other file type within your ZIP file, Linux & Windows will rely on the operating system's set default method/application. Obviously, the compressed/embedded file needs to be compatible with the operating system you run it on.

If the archive file is JAR or the compressed file type within the ZIP archive is PowerShell, Python, Shell Script or a Windows/Linux Executable, pdvzip will give you the option to provide command-line arguments for your file, if required.

The command-line arguments will be added to the Linux/Windows extraction script, embedded within the iCCP chunk of your PNG cover image.

Make sure to enclose arguments containing spaces, such as file & directory names, within "quotation" marks. e.g.

$ ./pdvzip my_cover_image.png jdvrif_linux_executable.zip

For this file type you can provide command-line arguments here, if required.

Linux: -e ../my_cover_image.jpg "../my document file.pdf"

Also, be aware when using arguments for the compressed ZIP file types (not JAR), you are always working from within the subdirectory "pdvzip_extracted".

https://github.com/user-attachments/assets/e55e9671-423c-4439-89e6-356c0080b4c1

https://github.com/user-attachments/assets/8d6d97c1-4c70-4f60-bba5-b01fad08b60e

To just get access to the file(s) within the ZIP archive, rename the '.png' file extension to '.zip'.
Treat the ZIP archive as read-only, do not add or remove files from the PNG-ZIP polyglot file.

Executing Embedded Java Programs

Linux Option 1:

$ java -jar pjar_19662.png
Note: If you use this method to run your embedded Java program, you will have to manually add command-line
      arguments (if required) to the end of the command, as your embedded arguments will not work with
      this method. e.g.
      user1@mx:~/Desktop$ java -jar ./pjar_19662.png -u john_s -a 42 -f "John Smith"

Linux Option 2a, using bash (or sh) shell environment:

$ ./pjar_19662.png
Note: This method will execute the embedded Java program and also use any embedded
      command-line arguments with the Java program.

Linux Option 2b, using any other shell environment, you will need to invoke bash (or sh) to execute the image:

mx% bash ./pjar_19662.png

Windows Option 1:

PS C:\Users\Nick\Desktop\jar_demo> java -jar .\pjar_19662.png 
Note: If you use this method to run your embedded Java program, you will have to manually add command-line
      arguments (if required) to the end of the command, as your embedded arguments will not work with
      this method. e.g.
      PS C:\Users\Nick\Desktop\jar_demo> java -jar .\pjar_19662.png -u john_s -a 42 -f "John Smith"

Windows Option 2:

PS C:\Users\Nick\Desktop\jar_demo> ren .\pjar_19662.png .\pjar_19662.cmd
PS C:\Users\Nick\Desktop\jar_demo> .\pjar_19662.cmd
Note: This method will execute the embedded Java program and will also use any
      embedded command-line arguments with the Java program.

https://github.com/user-attachments/assets/9451ad50-4c7c-4fa3-a1be-3854189bde00

PNG Image Requirements for Arbitrary Data Preservation

PNG file size (image + archive file) must not exceed the platform's size limit.

The site will either refuse to upload your image or it will convert your image to jpg, such as X-Twitter, and you will lose the embedded content.

Dimensions:

PNG-32/24 (Truecolor)

Image dimensions can be set between a minimum of 68 x 68 and a maximum of 900 x 900.

Note: A cover image that is detected as PNG-32/24 Truecolor (color type 6 or 2), with less than 257 colors, will be converted by pdvzip to a PNG-8 Indexed-color (color type 3) image. This is done for compatiblity reasons as it should prevent platforms such as X-Twitter from also converting your image, which would result in the loss of the embedded archive file.

PNG-8 (Indexed-color)

Image dimensions can be set between a minimum of 68 x 68 and a maximum of 4096 x 4096.

***PNG

View on GitHub
GitHub Stars57
CategoryDevelopment
Updated7d ago
Forks3

Languages

C++

Security Score

100/100

Audited on Mar 29, 2026

No findings