Created
January 20, 2022 09:59
-
-
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
This file contains hidden or 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
| 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