I have this Python code to process and output a PNG image for CTF (Catch The Flag). The original code was in Python 2.7, and I did some changes to make it work in Python 3
However when running it, I have this error:
f.write(struct.pack('>L', crc32(chtype+paldata)&0xffffffff))
TypeError: can't concat str to bytes
The code:
#!/usr/bin/env python
import sys
import struct
from zlib import crc32
import os
# PNG file format signature
pngsig = b'\x89PNG\r\n\x1a\n'
def swap_palette(filename, n):
# open in read+write mode
with open(filename, 'r+b') as f:
f.seek(0)
# verify that we have a PNG file
if f.read(len(pngsig)) != pngsig:
raise RuntimeError('not a png file!')
while True:
chunkstr = f.read(8)
if len(chunkstr) != 8:
# end of file
break
# decode the chunk header
length, chtype = struct.unpack('>L4s', chunkstr)
# we only care about palette chunks
print(chtype)
if chtype == b'PLTE':
print("I'm here")
curpos = f.tell()
paldata = f.read(length)
# replace palette entry n with white, the rest with black
paldata = ("\x00\x00\x00" * n) + "\xff\xff\xff" + ("\x00\x00\x00" * (256 - n - 1))
# replace palette entry 127 to 127 + n with white, the rest with black
#paldata = ("\x00\x00\x00" * 127) + ("\xff\xff\xff"*n) + ("\x00\x00\x00" * (256 - (127 + n)))
# go back and write the modified palette in-place
f.seek(curpos)
f.write(os.fsencode(paldata))
f.write(struct.pack('>L', crc32(chtype+paldata)&0xffffffff))
else:
# skip over non-palette chunks
f.seek(length+4, os.SEEK_CUR)
if __name__ == '__main__':
import shutil
shutil.copyfile(sys.argv[1], sys.argv[2])
swap_palette(sys.argv[2], int(sys.argv[3]))
The cmd command should be: python [filename.py] "[png image path]" "[output path].png" [any integer between 0 to 127]
The result should a new black image with some white areas within it
User contributions licensed under CC BY-SA 3.0