-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathupload_to_flipper.py
More file actions
executable file
·144 lines (118 loc) · 4.98 KB
/
upload_to_flipper.py
File metadata and controls
executable file
·144 lines (118 loc) · 4.98 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
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
#!/usr/bin/env python3
"""
NullSec Flipper Zero Suite Uploader
Uploads all assets to Flipper via serial
"""
import serial
import time
import os
import sys
class FlipperUploader:
def __init__(self, port='/dev/ttyACM0', baud=230400):
self.port = port
self.baud = baud
self.serial = None
def connect(self):
try:
self.serial = serial.Serial(self.port, self.baud, timeout=2)
time.sleep(0.5)
self.serial.read(self.serial.in_waiting)
print(f"[✓] Connected to Flipper on {self.port}")
return True
except Exception as e:
print(f"[✗] Connection failed: {e}")
return False
def send_command(self, cmd, wait=0.5):
if not self.serial:
return None
self.serial.write(f"{cmd}\r\n".encode())
time.sleep(wait)
response = self.serial.read(self.serial.in_waiting).decode(errors='ignore')
return response
def mkdir(self, path):
return self.send_command(f"storage mkdir {path}")
def write_file(self, remote_path, local_path):
"""Write a file to Flipper via CLI"""
with open(local_path, 'rb') as f:
data = f.read()
# For text files, use storage write
self.send_command(f"storage remove {remote_path}", wait=0.2)
# Write in chunks
chunk_size = 200
self.send_command(f"storage write {remote_path}", wait=0.1)
for i in range(0, len(data), chunk_size):
chunk = data[i:i+chunk_size]
self.serial.write(chunk)
time.sleep(0.05)
self.serial.write(b'\x03') # Ctrl+C to end
time.sleep(0.2)
return True
def upload_directory(self, local_dir, remote_dir):
"""Upload entire directory structure"""
print(f"\n[*] Uploading {local_dir} -> {remote_dir}")
self.mkdir(remote_dir)
for root, dirs, files in os.walk(local_dir):
rel_path = os.path.relpath(root, local_dir)
if rel_path == '.':
remote_subdir = remote_dir
else:
remote_subdir = f"{remote_dir}/{rel_path}"
self.mkdir(remote_subdir)
for file in files:
if file.endswith(('.py', '.pyc', '.sh')):
continue
local_path = os.path.join(root, file)
remote_path = f"{remote_subdir}/{file}"
print(f" -> {file}")
self.write_file(remote_path, local_path)
def disconnect(self):
if self.serial:
self.serial.close()
print("[✓] Disconnected")
def main():
base_dir = "/home/antics/nullsec/flipper-zero"
print("\n╔═══════════════════════════════════════════════╗")
print("║ NullSec Flipper Suite Uploader ║")
print("╚═══════════════════════════════════════════════╝\n")
uploader = FlipperUploader()
if not uploader.connect():
print("Make sure Flipper is connected and no other app is using it")
sys.exit(1)
# Create NullSec directories
print("[*] Creating NullSec directories...")
uploader.mkdir("/ext/nullsec")
uploader.mkdir("/ext/nullsec/badusb")
uploader.mkdir("/ext/nullsec/subghz")
uploader.mkdir("/ext/nullsec/infrared")
uploader.mkdir("/ext/nullsec/nfc")
# Upload content
uploads = [
(f"{base_dir}/apps/badusb", "/ext/nullsec/badusb"),
(f"{base_dir}/apps/subghz", "/ext/nullsec/subghz"),
(f"{base_dir}/apps/infrared", "/ext/nullsec/infrared"),
]
for local, remote in uploads:
if os.path.exists(local):
uploader.upload_directory(local, remote)
# Upload animations as asset pack
print("\n[*] Uploading animation pack...")
uploader.mkdir("/ext/asset_packs/NullSec")
uploader.mkdir("/ext/asset_packs/NullSec/Anims")
anim_dir = f"{base_dir}/assets/animations"
for anim in os.listdir(anim_dir):
anim_path = os.path.join(anim_dir, anim)
if os.path.isdir(anim_path) and anim.endswith("_128x64"):
remote_anim = f"/ext/asset_packs/NullSec/Anims/{anim}"
uploader.mkdir(remote_anim)
for f in os.listdir(anim_path):
if f.endswith('.bm') or f == 'meta.txt':
local_file = os.path.join(anim_path, f)
remote_file = f"{remote_anim}/{f}"
print(f" -> {anim}/{f}")
uploader.write_file(remote_file, local_file)
uploader.disconnect()
print("\n[✓] Upload complete!")
print(" Go to Momentum Settings > Protocols > Asset Packs")
print(" Select 'NullSec' to activate the theme\n")
if __name__ == "__main__":
main()