Last active
January 24, 2026 02:08
-
-
Save dmknght/dcd184729d18ac0601bdc503b1004ec2 to your computer and use it in GitHub Desktop.
Quickly extract encrypted firmware and packages inside firmware of Synology. This script is a wrapper of SynoXtract. Must compile SynoXtract first.
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
| import os | |
| import subprocess | |
| """ | |
| Automatically extract synology firmware and packages inside it. The SynoXtract is from https://github.com/prt1999/SynoXtract. Compile it first. | |
| Steps: | |
| 1. Extract firmware .pat file | |
| 2. (Start loop): Extract spk file (package) | |
| 3. Extract tar file. It should contain everything, include ELF files. | |
| 4. (End loop) Return 2. | |
| """ | |
| ROOT_PRJ_DIR = "/home/dmknght/Desktop/FIS_2026/P2O_Synology/" | |
| PATH_SYNOXTRACT = f"{ROOT_PRJ_DIR}/SynoXtract/sextractor" | |
| PATH_ENC_FIRMWARE = f"{ROOT_PRJ_DIR}/DSM_DS1525+_86009.pat" | |
| tmp_dir_name = os.path.splitext(os.path.basename(PATH_ENC_FIRMWARE))[0] | |
| PATH_TARGET_DIR = f"{ROOT_PRJ_DIR}/{tmp_dir_name}" # AUTOMATICALLY GET DIR NAME FROM FILE. EASIER TO EDIT | |
| PATH_TARGET_PKG = f"{PATH_TARGET_DIR}/__extracted_packages/" | |
| # Extract firmware from encrypted file. Make sure target folder exists first. Otherwise, just create dir in first place | |
| if not os.path.exists(PATH_TARGET_DIR): | |
| os.mkdir(PATH_TARGET_DIR) | |
| if not os.path.exists(f"{PATH_TARGET_DIR}/Synology.sig"): | |
| subprocess.run([PATH_SYNOXTRACT, "-i", PATH_ENC_FIRMWARE, "-d", PATH_TARGET_DIR]) | |
| else: | |
| print("[!] Seem like {PATH_TARGET_DIR} has extracted files already. Skipping!") | |
| # By now, command should be executed successfully. Do we need to handle error and exit? | |
| # encrypted .spk files are in f"{PATH_TARGET_DIR}/packages/". We need to extract them too | |
| ## 1. Get names of .spk files (without extensions) | |
| ## 2. Create destiation dir package_target_dir = f"{PATH_TARGET_DIR}/__extracted_packages/{package_name}" | |
| ## 3. Extract data from .spk files to package_target_dir | |
| ## 4. Create path f"package_target_dir/{__extracted_package_data}" which is the location to extract .tar file | |
| ## 5. Extract tar files to there | |
| if not os.path.exists(PATH_TARGET_PKG): | |
| os.mkdir(PATH_TARGET_PKG) | |
| for root, dirs, files in os.walk(f"{PATH_TARGET_DIR}/packages"): | |
| for each_file in files: | |
| file_name = os.path.splitext(each_file)[0] | |
| tmp_target_pkg = f"{PATH_TARGET_PKG}/{file_name}" # Where to extract .spk files to | |
| tmp_spk_file = os.path.join(root, each_file) | |
| # mkdir then extract again. Pretty much can create a function then reuse the code but it's only 2 lines. Also I'm so lazy for a more compilcated structure | |
| if not os.path.exists(tmp_target_pkg): | |
| os.mkdir(tmp_target_pkg) | |
| subprocess.run([PATH_SYNOXTRACT, "-i", tmp_spk_file, "-d", tmp_target_pkg]) | |
| # By now, we have everything we need. Just need to extract tar file | |
| tmp_source_tar = f"{tmp_target_pkg}/package.tgz" | |
| if not os.path.exists(tmp_source_tar): | |
| print(f"[x] Can not find package.tgz at {tmp_source_tar}. Something is wrong?") | |
| else: | |
| tmp_target_tar = f"{tmp_target_pkg}/__extracted_tar" # Where to extract tar file from .spk to | |
| if not os.path.exists(tmp_target_tar): | |
| os.mkdir(tmp_target_tar) | |
| subprocess.run(["tar", "-xvf", tmp_source_tar, "-C", tmp_target_tar]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment