Skip to content

Instantly share code, notes, and snippets.

@VincenzoLaSpesa
Created January 20, 2022 09:59
Show Gist options
  • Select an option

  • Save VincenzoLaSpesa/213283d6fb72cdd6893c5eef0a3964c8 to your computer and use it in GitHub Desktop.

Select an option

Save VincenzoLaSpesa/213283d6fb72cdd6893c5eef0a3964c8 to your computer and use it in GitHub Desktop.
A small script for packing or unpacking single file packages made of a sh script and a tgz payload
from subprocess import check_output
import argparse
import pprint
import os
import mmap
def run(cmd, echo=True, shell=True, printOutput = True) -> str:
""" Runs a command, returns the output """
if echo:
print(cmd)
output = check_output(cmd, shell=shell).decode("utf-8")
if printOutput:
print(output)
return output
def run_powershell(cmd):
cmd2=f"PowerShell -NoProfile -ExecutionPolicy Bypass -Command \"& {cmd}\""
print(run(cmd2))
parser = argparse.ArgumentParser()
parser.add_argument("-p",'--pack', action='store_true')
parser.add_argument("-u",'--unpack', action='store_true')
parser.add_argument("-m", "--marker",type=str, help="Marker that separates the files", required=True)
parser.add_argument("-o", "--output",type=str, help="output file name ( or prefix if unpacking)", required=True)
parser.add_argument("-l", "--limit",type=int, help="stop searching after some chunks", default=2)
parser.add_argument('files', type=str, nargs='+')
args = parser.parse_args()
pprint.pprint(args)
if (args.pack and args.unpack) or not (args.pack or args.unpack):
print("You can either pack or unpack")
parser.print_help()
exit(False)
if args.pack:
for f in args.files:
if not os.path.isfile(f):
print(f,"does not exist")
exit(False)
with open(args.output,"wb") as outfile:
for i,f in enumerate(args.files):
with open(f, "rb") as infile:
print("packing", f)
outfile.write(infile.read())
if i+1<len(args.files):
xx=(args.marker+":").encode("ascii")
outfile.write(xx)
outfile.write(bytes([0x0a,0xfd]))
fsizekb=int(os.path.getsize(args.output) / 1024)
print("Done", fsizekb, "kB written")
exit(True)
if args.unpack:
if len(args.files) > 1:
print("You can unpack only a single file at once")
exit(False)
points=[]
tokens=[]
with open(args.files[0], "rb") as infile:
while infile.readable() and len(points)+1 < args.limit:
x=infile.readline()
try:
xx=x.decode("utf-8")
if xx.startswith(args.marker):
p=infile.tell()-len(x)
tokens.append(len(x)+1)
print("Found a chunk in",p)
points.append(p)
except:
pass
points.append(os.path.getsize(args.files[0]))
tokens.append(0)
print("Cutting points",points)
print("Separators size",tokens)
cursor=0
data=""
with open(args.files[0], "rb") as infile:
for i,p in enumerate(points):
if i<len(points):
data=infile.read(p-cursor)
else:
data=infile.read()
infile.seek(infile.tell()+tokens[i])
f=f"{args.output}_{i}.bin"
with open(f,"wb") as outfile:
outfile.write(data)
print(f,"contains", len(data),"bytes of data")
cursor=p
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment