1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
| import os import shutil import zipfile import tarfile import gzip import bz2 import lzma import py7zr import time
# --- 配置 --- START_ARCHIVE = 'layer_1000.7z' WORKING_DIR = 'temp_extraction_folder' FINAL_DIR = 'final_content'
# ----------------
def is_archive(filename): """根据文件名后缀判断是否是支持的压缩文件类型(更强大的版本)""" fn_lower = filename.lower()
# 标准的以点开头的扩展名 supported_extensions = [ '.7z', '.zip', '.tar', '.gz', '.tgz', '.bz2', '.tbz2', '.xz', '.txz' ] for ext in supported_extensions: if fn_lower.endswith(ext): return True
# <-- 修改: 增加对 'tar_gz' 这类非标准后缀的检查 if fn_lower.endswith(('tar_gz', 'tar_bz2', 'tar_xz')): return True
return False
def decompress_once(file_path, destination_dir): """ 对单个文件进行一次解压操作 返回新解压出的文件名列表 """ print(f"-> 正在解压: {os.path.basename(file_path)}")
before_files = set(os.listdir(destination_dir))
try: filename_lower = file_path.lower()
# <-- 修改: 将 'tar_gz' 等非标准名称加入 tarfile 的处理逻辑中 # 优先处理 tar 系列压缩包,因为它们可能包含 .gz, .bz2 等后缀 if filename_lower.endswith( ('.tar', '.tar.gz', '.tgz', '.tar.bz2', '.tbz2', '.tar.xz', '.txz', 'tar_gz', 'tar_bz2', 'tar_xz')): # 'r:*' 模式可以自动检测压缩类型 (gz, bz2, xz) with tarfile.open(file_path, 'r:*') as t: t.extractall(path=destination_dir) elif filename_lower.endswith('.7z'): with py7zr.SevenZipFile(file_path, mode='r') as z: z.extractall(path=destination_dir) elif filename_lower.endswith('.zip'): with zipfile.ZipFile(file_path, 'r') as z: z.extractall(path=destination_dir) elif filename_lower.endswith('.gz'): output_path = os.path.join(destination_dir, os.path.basename(file_path)[:-3]) with gzip.open(file_path, 'rb') as f_in: with open(output_path, 'wb') as f_out: shutil.copyfileobj(f_in, f_out) elif filename_lower.endswith('.bz2'): output_path = os.path.join(destination_dir, os.path.basename(file_path)[:-4]) with bz2.open(file_path, 'rb') as f_in: with open(output_path, 'wb') as f_out: shutil.copyfileobj(f_in, f_out) elif filename_lower.endswith('.xz'): output_path = os.path.join(destination_dir, os.path.basename(file_path)[:-3]) with lzma.open(file_path, 'rb') as f_in: with open(output_path, 'wb') as f_out: shutil.copyfileobj(f_in, f_out) else: print(f"不支持的文件类型: {file_path}") return []
except Exception as e: print(f"解压 {os.path.basename(file_path)} 时发生错误: {e}") # 尝试继续,比如 tarfile 可能会因为文件不是 tar 格式而报错 return None
after_files = set(os.listdir(destination_dir)) new_files = after_files - before_files
return [os.path.join(destination_dir, f) for f in new_files]
def main(): """主执行函数""" start_time = time.time()
if not os.path.exists(START_ARCHIVE): print(f"错误:初始压缩包 '{START_ARCHIVE}' 不存在!") return
if os.path.exists(WORKING_DIR): shutil.rmtree(WORKING_DIR) os.makedirs(WORKING_DIR)
if os.path.exists(FINAL_DIR): shutil.rmtree(FINAL_DIR) os.makedirs(FINAL_DIR)
current_file = os.path.join(WORKING_DIR, os.path.basename(START_ARCHIVE)) shutil.copy(START_ARCHIVE, current_file)
layer_count = 0 while current_file and is_archive(current_file): layer_count += 1 print(f"\n--- 第 {layer_count} 层 ---")
new_files = decompress_once(current_file, WORKING_DIR)
if new_files is None: print("解压过程出错,程序终止。") break
old_file_to_remove = current_file
if not new_files: print("解压后未产生新文件,可能已是最后一层。") current_file = None # 终止循环 elif len(new_files) == 1: current_file = new_files[0] else: print(f"警告:解压后得到 {len(new_files)} 个文件。将自动寻找下一个压缩包。") next_archive = None for f in new_files: if is_archive(f): next_archive = f print(f"找到下一个目标: {os.path.basename(f)}") break if not next_archive: print("在解压出的多个文件中未找到下一个压缩包,程序终止。") current_file = next_archive
try: if os.path.exists(old_file_to_remove): os.remove(old_file_to_remove) print(f"<- 已清理: {os.path.basename(old_file_to_remove)}") except OSError as e: print(f"清理文件失败: {e}")
# 循环结束,处理最终文件 final_file_path = current_file if current_file else old_file_to_remove if os.path.exists(final_file_path): print("\n==========================================") print("🎉 解压完成!已找到最底层文件。") final_filename = os.path.basename(final_file_path) destination_path = os.path.join(FINAL_DIR, final_filename) shutil.move(final_file_path, destination_path) print(f"最终文件 '{final_filename}' 已移动到 '{FINAL_DIR}' 文件夹中。")
try: with open(destination_path, 'r', encoding='utf-8') as f: content = f.read(200) print("\n文件内容预览:") print("--------------------") print(content) print("--------------------") if "flag" in content.lower() or "{" in content: print("提示:在文件中找到了 'flag' 或 '{' 等关键词!") if "flag{I_lOve_Y0u}" in content: print("\n>>> 恭喜!Flag找到了!<<<") except Exception: print("无法以文本方式读取最终文件,它可能是二进制文件。") else: print("\n未能找到最终文件。")
shutil.rmtree(WORKING_DIR) print(f"临时工作目录 '{WORKING_DIR}' 已被清理。")
end_time = time.time() print(f"\n总耗时: {end_time - start_time:.2f} 秒")
if __name__ == '__main__': main()
|