|
| 1 | +import os |
| 2 | +import shutil |
| 3 | +import sys |
| 4 | +from pathlib import Path |
| 5 | +from typing import Iterator, List |
| 6 | + |
| 7 | +from setuptools import setup |
| 8 | + |
| 9 | +SOURCE_ROOT = Path(__file__).resolve().parent |
| 10 | + |
| 11 | +pkg_info = SOURCE_ROOT / "PKG-INFO" |
| 12 | +in_source_package = pkg_info.exists() |
| 13 | + |
| 14 | + |
| 15 | +def main(): |
| 16 | + setup( |
| 17 | + name="frida-tools", |
| 18 | + version=detect_version(), |
| 19 | + description="Frida CLI tools", |
| 20 | + long_description="CLI tools for [Frida](https://frida.re).", |
| 21 | + long_description_content_type="text/markdown", |
| 22 | + author="Frida Developers", |
| 23 | + |
| 24 | + url="https://frida.re", |
| 25 | + install_requires=[ |
| 26 | + "colorama >= 0.2.7, < 1.0.0", |
| 27 | + "frida >= 17.2.8, < 18.0.0", |
| 28 | + "prompt-toolkit >= 2.0.0, < 4.0.0", |
| 29 | + "pygments >= 2.0.2, < 3.0.0", |
| 30 | + "websockets >= 13.0.0, < 14.0.0", |
| 31 | + ], |
| 32 | + license="wxWindows Library Licence, Version 3.1", |
| 33 | + zip_safe=False, |
| 34 | + keywords="frida debugger dynamic instrumentation inject javascript windows macos linux ios iphone ipad android qnx", |
| 35 | + classifiers=[ |
| 36 | + "Development Status :: 5 - Production/Stable", |
| 37 | + "Environment :: Console", |
| 38 | + "Environment :: MacOS X", |
| 39 | + "Environment :: Win32 (MS Windows)", |
| 40 | + "Intended Audience :: Developers", |
| 41 | + "Intended Audience :: Science/Research", |
| 42 | + "License :: OSI Approved", |
| 43 | + "Natural Language :: English", |
| 44 | + "Operating System :: MacOS :: MacOS X", |
| 45 | + "Operating System :: Microsoft :: Windows", |
| 46 | + "Operating System :: POSIX :: Linux", |
| 47 | + "Programming Language :: Python :: 3", |
| 48 | + "Programming Language :: Python :: 3.7", |
| 49 | + "Programming Language :: Python :: 3.8", |
| 50 | + "Programming Language :: Python :: 3.9", |
| 51 | + "Programming Language :: Python :: 3.10", |
| 52 | + "Programming Language :: JavaScript", |
| 53 | + "Topic :: Software Development :: Debuggers", |
| 54 | + "Topic :: Software Development :: Libraries :: Python Modules", |
| 55 | + ], |
| 56 | + packages=["frida_tools"], |
| 57 | + package_data={ |
| 58 | + "frida_tools": fetch_built_assets(), |
| 59 | + }, |
| 60 | + entry_points={ |
| 61 | + "console_scripts": [ |
| 62 | + "frida = frida_tools.repl:main", |
| 63 | + "frida-ls-devices = frida_tools.lsd:main", |
| 64 | + "frida-ps = frida_tools.ps:main", |
| 65 | + "frida-kill = frida_tools.kill:main", |
| 66 | + "frida-ls = frida_tools.ls:main", |
| 67 | + "frida-rm = frida_tools.rm:main", |
| 68 | + "frida-pull = frida_tools.pull:main", |
| 69 | + "frida-push = frida_tools.push:main", |
| 70 | + "frida-discover = frida_tools.discoverer:main", |
| 71 | + "frida-trace = frida_tools.tracer:main", |
| 72 | + "frida-itrace = frida_tools.itracer:main", |
| 73 | + "frida-join = frida_tools.join:main", |
| 74 | + "frida-create = frida_tools.creator:main", |
| 75 | + "frida-compile = frida_tools.compiler:main", |
| 76 | + "frida-pm = frida_tools.pm:main", |
| 77 | + "frida-apk = frida_tools.apk:main", |
| 78 | + ] |
| 79 | + }, |
| 80 | + ) |
| 81 | + |
| 82 | + |
| 83 | +def detect_version() -> str: |
| 84 | + if in_source_package: |
| 85 | + version_line = [ |
| 86 | + line for line in pkg_info.read_text(encoding="utf-8").split("\n") if line.startswith("Version: ") |
| 87 | + ][0].strip() |
| 88 | + version = version_line[9:] |
| 89 | + else: |
| 90 | + releng_location = next(enumerate_releng_locations(), None) |
| 91 | + if releng_location is not None: |
| 92 | + sys.path.insert(0, str(releng_location.parent)) |
| 93 | + from releng.frida_version import detect |
| 94 | + |
| 95 | + version = detect(SOURCE_ROOT).name.replace("-dev.", ".dev") |
| 96 | + else: |
| 97 | + version = "0.0.0" |
| 98 | + return version |
| 99 | + |
| 100 | + |
| 101 | +def fetch_built_assets() -> List[str]: |
| 102 | + assets = [] |
| 103 | + |
| 104 | + if in_source_package: |
| 105 | + pkgdir = SOURCE_ROOT / "frida_tools" |
| 106 | + assets += [f.name for f in pkgdir.glob("*_agent.js")] |
| 107 | + assets += [f.relative_to(pkgdir).as_posix() for f in (pkgdir / "bridges").glob("*.js")] |
| 108 | + assets += [f.name for f in pkgdir.glob("*.zip")] |
| 109 | + else: |
| 110 | + agents_builddir = SOURCE_ROOT / "build" / "agents" |
| 111 | + if agents_builddir.exists(): |
| 112 | + for child in agents_builddir.iterdir(): |
| 113 | + if child.is_dir(): |
| 114 | + for f in child.glob("*_agent.js"): |
| 115 | + shutil.copy(f, SOURCE_ROOT / "frida_tools") |
| 116 | + assets.append(f.name) |
| 117 | + |
| 118 | + bridges_builddir = SOURCE_ROOT / "build" / "bridges" |
| 119 | + if bridges_builddir.exists(): |
| 120 | + bridges_dir = SOURCE_ROOT / "frida_tools" / "bridges" |
| 121 | + bridges_dir.mkdir(exist_ok=True) |
| 122 | + for f in bridges_builddir.glob("*.js"): |
| 123 | + shutil.copy(f, bridges_dir) |
| 124 | + assets.append((Path("bridges") / f.name).as_posix()) |
| 125 | + |
| 126 | + apps_builddir = SOURCE_ROOT / "build" / "apps" |
| 127 | + if apps_builddir.exists(): |
| 128 | + for child in apps_builddir.iterdir(): |
| 129 | + if child.is_dir(): |
| 130 | + for f in child.glob("*.zip"): |
| 131 | + shutil.copy(f, SOURCE_ROOT / "frida_tools") |
| 132 | + assets.append(f.name) |
| 133 | + |
| 134 | + return assets |
| 135 | + |
| 136 | + |
| 137 | +def enumerate_releng_locations() -> Iterator[Path]: |
| 138 | + val = os.environ.get("MESON_SOURCE_ROOT") |
| 139 | + if val is not None: |
| 140 | + parent_releng = Path(val) / "releng" |
| 141 | + if releng_location_exists(parent_releng): |
| 142 | + yield parent_releng |
| 143 | + |
| 144 | + local_releng = SOURCE_ROOT / "releng" |
| 145 | + if releng_location_exists(local_releng): |
| 146 | + yield local_releng |
| 147 | + |
| 148 | + |
| 149 | +def releng_location_exists(location: Path) -> bool: |
| 150 | + return (location / "frida_version.py").exists() |
| 151 | + |
| 152 | + |
| 153 | +if __name__ == "__main__": |
| 154 | + main() |
0 commit comments