-
Notifications
You must be signed in to change notification settings - Fork 43
/
patch_bypy.py
59 lines (48 loc) · 1.44 KB
/
patch_bypy.py
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
import stat
import shutil
import click
import launcher_helper as helper
def patch(
bypy: str,
new_pyc_file: str,
launcher: str,
embed_path: str,
output: str | None = None,
_os: str = "win",
):
if output is None:
output = bypy
else:
shutil.copyfile(bypy, output)
with open(new_pyc_file, "rb") as f:
data = f.read()[0x10:]
offset, cap = helper.find(launcher, embed_path, _os)
if cap < len(data):
raise ValueError(f"new pyc size({len(data)}) large than capacity({cap})")
print(f"[+] pyc size {cap:#x} -> {len(data):#x} (shrink: {cap-len(data):#x})")
with open(output, "r+b") as f:
f.seek(offset)
f.write(data)
@click.command()
@click.option("--bypy", required=True, type=click.Path(exists=True))
@click.option("--new-pyc-file", required=True, type=click.Path(exists=True))
@click.option("--launcher", required=True, type=click.Path(exists=True))
@click.option("--embed_path", required=True, type=click.Path(exists=False))
@click.option("--output", required=False, type=click.Path(exists=False), default=None)
@click.option(
"--os",
type=click.Choice(["win", "linux", "mac"]),
default="win",
required=False,
)
def cli(
bypy: str,
new_pyc_file: str,
launcher: str,
embed_path: str,
output: str | None = None,
os: str = "win",
):
patch(bypy, new_pyc_file, launcher, embed_path, output, os)
if __name__ == "__main__":
cli()