fa-tui 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
fa_tui/__init__.py ADDED
File without changes
fa_tui/app.py ADDED
@@ -0,0 +1,129 @@
1
+ import re
2
+ from textual.app import App, ComposeResult
3
+ from textual.widgets import ListView, ListItem, Label, Static
4
+ from textual.containers import Vertical, Horizontal
5
+ from textual import events
6
+ import subprocess
7
+ from pathlib import Path
8
+
9
+ result_data = {}
10
+
11
+ class FridaTUI(App):
12
+ CSS = """
13
+ Screen {
14
+ layout: vertical;
15
+ background: $background;
16
+ }
17
+ #mode-label {
18
+ padding: 1;
19
+ text-align: center;
20
+ background: $accent;
21
+ color: $text;
22
+ }
23
+ #js-files, #frida-output {
24
+ width: 100%;
25
+ height: 100%;
26
+ border: solid $primary;
27
+ padding: 1;
28
+ }
29
+ ListView {
30
+ height: 100%;
31
+ }
32
+ Label {
33
+ padding: 1;
34
+ }
35
+ """
36
+
37
+ def compose(self) -> ComposeResult:
38
+ # 使用 Horizontal 容器将两组列表并排显示
39
+ yield Horizontal(
40
+ Vertical(
41
+ Static("frida-ps -Uai 输出", classes="title"),
42
+ ListView(id="frida-output")
43
+ ),
44
+ Vertical(
45
+ Static("当前目录中的 JS 文件", classes="title"),
46
+ ListView(id="js-files")
47
+ )
48
+ )
49
+ # 添加一个显示当前模式的标签,提示可按 M 切换
50
+ yield Static("当前模式: spawn (按 M 切换)", id="mode-label")
51
+ def on_mount(self) -> None:
52
+ self.mode = "spawn" # 默认模式为 spawn,对应 -f
53
+ self.js_files = []
54
+ self.frida_processes = []
55
+
56
+ # 加载当前目录下的 JS 文件
57
+ js_files = [f.name for f in Path.cwd().glob("*.js")]
58
+ self.js_files = js_files
59
+ js_list = self.query_one("#js-files", ListView)
60
+ for file in js_files:
61
+ js_list.append(ListItem(Label(file)))
62
+
63
+ # 加载 frida-ps -Uai 输出
64
+ try:
65
+ result = subprocess.run(
66
+ ["frida-ps", "-Uai"],
67
+ capture_output=True,
68
+ text=True,
69
+ check=True
70
+ )
71
+ output_lines = result.stdout.splitlines()[2:] # 跳过前两行
72
+ self.frida_processes = output_lines
73
+ frida_list = self.query_one("#frida-output", ListView)
74
+ for line in output_lines:
75
+ frida_list.append(ListItem(Label(line)))
76
+ except Exception as e:
77
+ self.frida_processes = [f"Error: {e}"]
78
+ frida_list = self.query_one("#frida-output", ListView)
79
+ frida_list.append(ListItem(Label(str(e))))
80
+
81
+ async def on_key(self, event: events.Key) -> None:
82
+ # 按 M 键切换模式
83
+ if event.key.lower() == "m":
84
+ self.mode = "attach" if self.mode == "spawn" else "spawn"
85
+ mode_label = self.query_one("#mode-label", Static)
86
+ mode_label.update(f"当前模式: {self.mode} (按 M 切换)")
87
+ # 按 Enter 键选择当前项并退出 TUI
88
+ elif event.key == "enter":
89
+ js_index = self.query_one("#js-files", ListView).index
90
+ frida_index = self.query_one("#frida-output", ListView).index
91
+
92
+ js_file = self.js_files[js_index] if js_index is not None and js_index < len(self.js_files) else None
93
+ frida_proc = self.frida_processes[frida_index] if frida_index is not None and frida_index < len(self.frida_processes) else None
94
+
95
+ # 将选择结果和当前模式存入全局变量
96
+ result_data["js_file"] = js_file
97
+ result_data["frida_proc"] = frida_proc
98
+ result_data["mode"] = self.mode
99
+
100
+ await self.action_quit()
101
+
102
+ def main():
103
+ FridaTUI().run()
104
+
105
+ if result_data:
106
+ js_file = result_data.get("js_file") or ""
107
+ frida_line = result_data.get("frida_proc") or ""
108
+ mode = result_data.get("mode", "spawn")
109
+
110
+ parts = frida_line.split()
111
+ pkg = parts[-1] if parts else ""
112
+
113
+ if js_file and pkg:
114
+ # 根据模式选择不同参数
115
+ option = "-f" if mode == "spawn" else "-n"
116
+ cmd = f"frida -U {option} {pkg} -l {js_file}"
117
+ print(f"执行命令:{cmd}")
118
+ try:
119
+ subprocess.run(["frida", "-U", option, pkg, "-l", js_file])
120
+ except FileNotFoundError:
121
+ print("找不到 frida 命令,请确认已正确安装并在 PATH 中。")
122
+ except Exception as e:
123
+ print(f"执行失败: {e}")
124
+ else:
125
+ print("无法生成 frida 命令,可能未正确选择 JS 或进程")
126
+
127
+
128
+ if __name__ == "__main__":
129
+ main()
@@ -0,0 +1,62 @@
1
+ Metadata-Version: 2.1
2
+ Name: fa-tui
3
+ Version: 0.1.0
4
+ Summary: 一个文本TUI工具,用于选择frida进程和JS脚本。适用于Android系统
5
+ Author-email: hongenge <hongen.me@gmail.com>
6
+ Project-URL: Homepage, https://github.com/hongenge/fa-tui
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: textual>=3.5.0
10
+
11
+ # fa-tui
12
+
13
+ 一个`frida`的终端 TUI 工具,用于选择 `frida-ps -Uai` 输出的进程和本地目录中的 JS 文件,并以 spawn 或 attach 模式执行 Frida 注入命令。
14
+
15
+ > ⚠️ **注意**
16
+ > 本工具设计用于 Android 设备的 Frida Hook,依赖 `frida` 和 `frida-ps` 命令正确连接 Android 设备(如通过 USB 或 TCP 连接的设备)。
17
+
18
+ ## ✨ 功能特点
19
+
20
+ - 实时列出 `frida-ps -Uai` 获取的 Android 设备进程列表
21
+ - 自动扫描当前目录下的 JS 脚本文件
22
+ - 支持切换 `spawn` / `attach` 模式(默认 `spawn`,按 `M` 切换)
23
+ - 支持鼠标和键盘操作选择进程和脚本,回车自动执行注入命令
24
+
25
+ ## 📦 安装方式
26
+
27
+
28
+ ```bash
29
+ pip install fa-tui
30
+ ````
31
+
32
+ ## 🚀 使用方法
33
+
34
+ 在终端中运行:
35
+
36
+ ```bash
37
+ fa-tui
38
+ ```
39
+
40
+ 交互界面将展示:
41
+ * 左侧:`frida-ps -Uai` 输出的 Android 进程列表
42
+ * 右侧:当前目录中的 JS 文件列表
43
+ * 底部:当前注入模式,按 `M` 键可切换 `spawn` 和 `attach` 模式
44
+ * 按 Ctrl+Q 可随时退出程序
45
+
46
+ 选中 JS 文件和目标进程后,按下 `Enter` 键,将会自动执行:
47
+
48
+ ```bash
49
+ frida -U -f 包名 -l 脚本.js # spawn 模式
50
+ # 或
51
+ frida -U -n 包名 -l 脚本.js # attach 模式
52
+ ```
53
+
54
+ ## 🔧 依赖项
55
+
56
+ * Python 3.8+
57
+
58
+ * 已安装并配置 `frida` 命令行工具(`frida` 与 `frida-ps`)
59
+
60
+ * Android 设备连接且可用 `frida-ps -Uai` 正确列出进程
61
+
62
+ * [Textual](https://github.com/Textualize/textual)
@@ -0,0 +1,7 @@
1
+ fa_tui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ fa_tui/app.py,sha256=syu1bsEgiErgUZh3AmQA3P5joF2MEIu7PKcFEMjTrl0,4598
3
+ fa_tui-0.1.0.dist-info/METADATA,sha256=q4KjsfhqPd4snvyxRrZLCPTj6t2dE3YYv2em5ibKY6o,1868
4
+ fa_tui-0.1.0.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
5
+ fa_tui-0.1.0.dist-info/entry_points.txt,sha256=DzfsvNL9TeRqgL7arD_d4CcvTGSNNwgIVTD40Q_t9Rg,43
6
+ fa_tui-0.1.0.dist-info/top_level.txt,sha256=EMFC920Cb0vfmnnsEZYZUm2BHVLC5yfOVzo9lsZOxqU,7
7
+ fa_tui-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.3.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ fa-tui = fa_tui.app:main
@@ -0,0 +1 @@
1
+ fa_tui