forked from STBD1574/vanilla_mcp_util
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbatch_process.py
More file actions
90 lines (73 loc) · 3.34 KB
/
Copy pathbatch_process.py
File metadata and controls
90 lines (73 loc) · 3.34 KB
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
import os
import sys
import subprocess
import uncompyle6
import contextlib
import io
from concurrent.futures import ProcessPoolExecutor
from log import logging, logger
from anti_confuser import restore_data
def file_handler(input_path: str, output_path: str) -> None:
if not os.path.exists(input_path) or not input_path.endswith(".mcs"):
return
if output_path is None:
output_path = input_path.replace(".mcs", ".pyc")
try:
log_path = output_path.replace(".pyc", "_log.txt")
with open(log_path, "w", encoding="utf-8") as f:
with contextlib.redirect_stdout(f), contextlib.redirect_stderr(f):
open(output_path, 'wb').write(
restore_data(open(input_path, 'rb').read()))
try:
subprocess.run(['pycdas', output_path, '-o', output_path.replace(".pyc", "_asm.txt")],
check=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
except Exception as e:
pass
py_path = output_path.replace(".pyc", ".py")
with open(py_path, "w", encoding="utf-8") as f:
try:
with contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(io.StringIO()):
uncompyle6.decompile_file(output_path, f)
except Exception as e:
f.write(f"\n# Uncompyle6 Error: {str(e)}\n")
logger.info(f"Processed: {input_path}")
except Exception as e:
logger.error(f"Error processing {input_path}: {e}")
def main():
if len(sys.argv) < 2:
logger.error("Usage: python batch_process.py <input_folder> [output_folder]")
return
input_file = os.path.abspath(sys.argv[1])
output_folder = os.path.abspath(sys.argv[2]) if len(sys.argv) > 2 else None
max_workers = 8
futures = []
with ProcessPoolExecutor(max_workers=max_workers) as pool:
if os.path.isdir(input_file):
for root, dirs, files in os.walk(input_file):
for filename in files:
if not filename.endswith(".mcs"):
continue
file_path = os.path.join(root, filename)
relative_path = os.path.relpath(file_path, input_file)
if output_folder:
out_dir = os.path.join(output_folder, os.path.dirname(relative_path))
os.makedirs(out_dir, exist_ok=True)
out_path = os.path.join(out_dir, filename.replace(".mcs", ".pyc"))
else:
out_path = file_path.replace(".mcs", ".pyc")
futures.append(pool.submit(file_handler, file_path, out_path))
else:
futures.append(pool.submit(file_handler, input_file, output_folder))
# Wait for all futures with a global timeout or per-item monitoring
from concurrent.futures import as_completed
for future in as_completed(futures):
try:
future.result(timeout=60)
except Exception as e:
logger.error(f"Task failed or timed out: {e}")
future.cancel()
if __name__ == "__main__":
logger.setLevel(logging.INFO)
main()