Last active
July 3, 2022 11:39
-
-
Save OptoCloud/f58788144996af2b6e2df1a34411684f to your computer and use it in GitHub Desktop.
This file contains 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
import os | |
import gzip | |
import shutil | |
import tarfile | |
def ensure_dir(dir): | |
if not os.path.exists(dir): | |
os.makedirs(dir) | |
def move_if_exists(src, dst): | |
if os.path.exists(src): | |
ensure_dir(os.path.dirname(dst)) | |
shutil.move(src, dst) | |
def read_all_text(path): | |
with open(path, 'r') as f: | |
return f.read() | |
def unpack_unitypackage(path): | |
package_name = os.path.basename(path) | |
package_dir = os.path.dirname(path) | |
unpack_folder = os.path.join(package_dir, os.path.splitext(package_name)[0]) | |
tar_path = os.path.join(unpack_folder, "archtemp.tar") | |
# Create target folder for package files | |
ensure_dir(unpack_folder) | |
# Extract unitypackage (gzip) | |
with gzip.open(path, 'rb') as f_in: | |
with open(tar_path, 'wb+') as f_out: | |
shutil.copyfileobj(f_in, f_out) | |
# Create folder to extract artifacts to | |
artifact_folder = os.path.join(unpack_folder, "artifacts") | |
ensure_dir(artifact_folder) | |
# Extract artifacts (tar) | |
tar = tarfile.open(tar_path, "r:*") | |
tar.extractall(artifact_folder) | |
tar.close() | |
# delete the archive | |
os.remove(tar_path) | |
# Get all subdirectories of the archive folder | |
artifact_dirs = get_subdirs(artifact_folder) | |
# Malicious folder in case someone has messed with the package and wants to extract to a different directory | |
malicious_folder = os.path.join(unpack_folder, "Malicious") | |
# Move all files and subdirectories to the target directory | |
for artifact_name in artifact_dirs: | |
artifact_dir = os.path.join(artifact_folder, artifact_name) | |
final_path = read_all_text(os.path.join(artifact_dir, "pathname")) | |
final_name = os.path.basename(final_path) | |
# If pathname contains a ".." in the path, it is not a valid path, extract it to a "Malicious" folder | |
if ".." in final_path or final_path.startswith("/"): | |
final_path = os.path.join(malicious_folder, artifact_name, final_name) | |
else: | |
final_path = os.path.join(unpack_folder, final_path) | |
move_if_exists(os.path.join(artifact_dir, "asset"), final_path) | |
move_if_exists(os.path.join(artifact_dir, "asset.meta"), final_path + ".meta") | |
# Delete the artifact folder | |
shutil.rmtree(artifact_folder) | |
# Get all subdirecotries of a directory | |
def get_subdirs(dir): | |
return [name for name in os.listdir(dir) | |
if os.path.isdir(os.path.join(dir, name))] | |
# Unpack all .unitypackage files | |
def unpack_all(sourceDir): | |
# Get all .unitypackage files in the source directory | |
packages = [name for name in os.listdir(sourceDir) if name.endswith(".unitypackage")] | |
# Unpack with 7zip | |
for package in packages: | |
unpack_unitypackage(os.path.join(sourceDir, package)) | |
# Main function | |
if __name__ == "__main__": | |
unpack_all(".") | |
print("Unpacking complete!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment