Skip to content

Instantly share code, notes, and snippets.

@shreve
Created August 9, 2022 04:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shreve/7190041eb4268354fa3384cdb9853d9f to your computer and use it in GitHub Desktop.
Save shreve/7190041eb4268354fa3384cdb9853d9f to your computer and use it in GitHub Desktop.
Read and modify your FlipperZero dolphin's state
"""
Dolphin.py
Access your dolphin's state.
"""
import sys
from struct import Struct
apps = [
"SubGhz",
"Rfid",
"Nfc",
"Ir",
"Ibutton",
"Badusb",
"U2f",
]
dolphin_struct = Struct("B B B B I 7B B I I i L")
payload_struct = Struct("7B B I I i L")
class Dolphin:
def __init__(self):
self.header = {
"magic": 0,
"version": 0,
"checksum": 0,
"flags": 0,
"timestamp": 0,
}
self.apps_icounter = {app: 0 for app in apps}
self.butthurt_limit = 0
self.flags = 0
self.icounter = 0
self.butthurt = 0
self.timestamp = 0
def set(self, *values):
self.header = {
"magic": values[0],
"version": values[1],
"checksum": values[2],
"flags": values[3],
"timestamp": values[4],
}
self.apps_icounter = dict(zip(apps, values[5:12]))
self.butthurt_limit = values[12]
self.flags = values[13]
self.icounter = values[14]
self.butthurt = values[15]
self.timestamp = values[16]
self.check()
return self
@classmethod
def load(cls, file):
"""Load a dolphin from a file"""
new = Dolphin()
with open(file, "rb") as fp:
parsed_data = dolphin_struct.unpack(fp.read())
return new.set(*parsed_data)
def save(self, file):
"""Save a dolphin to a file"""
self.check()
with open(file, "wb") as fp:
fp.write(self.pack())
def pack(self):
"""Pack the dolphin into byte string"""
return dolphin_struct.pack(
self.header["magic"],
self.header["version"],
self.compute_checksum(),
self.header["flags"],
self.header["timestamp"],
*self.values,
)
def pack_payload(self):
"""Pack just the payload into a byte string"""
return payload_struct.pack(*self.values)
@property
def values(self):
"""Return the payload values of the dolphin."""
return [
*self.apps_icounter.values(),
self.butthurt_limit,
self.flags,
self.icounter,
self.butthurt,
self.timestamp,
]
def compute_checksum(self):
"""Compute the checksum of the payload"""
checksum = 0
for byte in self.pack_payload():
checksum += int(byte)
return checksum % 128
def check(self):
# assert self.icounter == sum(self.apps_icounter.values())
assert self.compute_checksum() == self.header["checksum"]
def main():
d = Dolphin.load(sys.argv[1])
# Pretend I played with him.
d.icounter += 9999
d.header["checksum"] = d.compute_checksum()
d.save(".dolphin.state")
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment