aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: b62615d094088685e921e776035d5dcf2f713c64 (plain)
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

   

Bodeting, Understanding Bodets Harmony PSA Protocol

What will you find here?

  • Research on how the Bodet Harmony PSA Protocol works
  • Tools to allow features to be used your Netsilon can't do
  • Research on replacing the Bodet Software Called SIGMA and the Time Server for it (I can't even take its name serious) and eventually links to the replacement software called BE-YOUR-OWN-SIGMA (if I achieve reverse engineering it to a certain decentish degree).

Important Disclaimer: While the structural fields of the packets are mostly well understood, the checksum calculation remains quiet mysterious. Without correctly reproducing the checksum, generating functional packets yourself remains unreliable unless you copy known working ones, therefore this can only be used for repetitive actions with already learnt and working commands.

Sample Data Folder :

Contains valid payloads that get accepted by the system if sent to multicast address 239.192.55.2 stop-payloads.txt

Research folder contains active stuff im working on right now.

If you want to help out with figuring things out this is where to look I'd say

Please IF YOU KNOW HOW TO MAKE THE CHECKSUMS WORK PROPERLY OR KNOW MORE THAN ME PLEASE HELP ME!!!

General info

Common Hardware Details (Seemingly for all but Master Clock)

  • Platform: Freescale MQX RTOS
  • MCU: Most likely a Freescale/NXP Cortex-M4 (based on MQX + strings + 2017 build date)
  • Networking Stack: LwIP
  • Storage: MFS-style filesystem, Speakers and Sound Generating Components have an SD Card
  • Web Interface: Embedded HTTP server (Server: MQX HTTP - Freescale Embedded Web Server)
  • Ports & Protocols:
  • HTTP, FTP (port 21), SNMP, IGMP multicast, UDP
  • FTP Banner: RTCS FTP Server Ready

Build Pipeline

  • Project was built using Windows Jenkins (who could've guessed that), based on hardcoded paths in strings of firmware files: d:\JenkinsJobs\workspace\Indus\Harmonys\Harmonys_trio\Metis_appli\Middlewares\Third_Party\LwIP\
  • Sources show extensive use of LwIP stack and standard Freescale directory structures

Possible Default Credentials

Based on repeated appearances in both firmware strings :

Username Password
public jkl1vi5erjnfh
public aSe2=9Z8gOi37*

Checksum Observations

  • Found log strings that explicitly reference checksum calculation and failures: CHK = %04x (%d) CHK BAD !!! %d
  • Could however also be just for firmware integrity maybe? Rather unlikely though.

Also of note :

F_traitement_trame_PROTOCOLE
F_traitement_trame_vie_repeteur
REP STREAM !!! ERREUR !!!
RX %d/%d (%d/%d)
  • These functions appear responsible for:
  • Receiving and validating packets
  • Detecting checksum mismatches
  • Possibly retrying on failures?

IP Button Packet Anatomy

Each IP Button Bodet Sound Protocol Payload follows a consistent format:

[MEL HEADER]-[LENGTH]-[START]-[SEQUENCE]-[COMMAND]-[ZONE INFO]-[METADATA]-[CHECKSUM]

Seems to send two of the packets each time a button is pressed

MEL Header

  • Hex: 4D 45 4C
  • ASCII: "MEL" (probably short for "Melody")
  • Identifies this as a Bodet Sound Protocol packet

Length

  • 2 bytes
  • Indicates payload size in decimal (excluding MAC/IP/UDP headers)
  • Example: 0021 = 33 bytes

Start Marker

  • Constant: 0100
  • Marks start of command block

Sequence Number

  • 2 bytes, Little Endian
  • Only the first byte appears to increment; the second is often FF, suggesting padding or reserved space
  • Likely acts as a replay or event counter

Command Code

  • Examples:

  • 3001 = Melody

  • 5001 = Alarm
  • 5002 = Stop

Zone Info

  • 12 bytes (6 words of 16 bits = 96 bits)
  • Represents zones 1–100 using a bitfield
  • Each zone bit is encoded as:

byte_index = (zone - 1) // 8 bit_index = (zone - 1) % 8 set bit (7 - bit_index) in byte[byte_index] * You can enable multiple zones in a single packet by OR-ing the relevant bits * Examples:

  • 8000 0000 0000 0000 0000 0000 = Zone 8 only
  • 0000 8000 0000 0000 0000 0000 = Zone 16 only
  • 0000 0000 0000 0000 0020 0000 = Zone 86

  • Note : this is just an assumption not enough testing has been done

Metadata Fields

  • After Zone Info:

  • 0001 - Probably Fixed field (sometimes 0002 with certain multizone commands)

  • 03 - Volume (1-8)
  • 02 - Repeat count (or 00 for infinite)
  • `01 - Probably Fixed field or field to actually tell the device yes play something lol
  • 09 - Melody ID (9 in this case)
  • 0100 - Possible end-of-command marker, appears to terminate command blocks (expept for stop commands)
  • 01 - Fixed

Checksum (1 byte)

  • Position: Final byte of packet
  • Behavior: Matches (sum of all previous bytes) & 0xFF in most cases, but not always.
  • Status: SEND HELP (see section below)

Examples (Annotated)

Melody to Zone 8, Melody 9, Infinite Repeats

4d454c 0021 0100 28ff 3001 8000 0000 0000 0000 0000 0000 0001 03 00 01 09 0100 01 d5
  • Zone 8 = 8000 ...
  • Volume = 03, Repeats = 00 (infinite)
  • Melody = 09
  • Checksum = D5

Stop All Zones

4d454c 001a 0100 24ff 5002 ffff ffff ffff ffff ffff ffff 0f 01 07
  • All zones = FF FF ... (you actually cant choose which zone to turn of system refuses zonemaps here)
  • Command = Stop (5002)
  • Ends with 0F 01 instead of 0100 → supports theory that 0100 indicates only the end of melody/alarm command block
  • Checksum = 07

Checksum Problem

While many packets obey a simple rule:

checksum = sum(packet[:-1]) & 0xFF

... others diverge due to what appears to be a variable offset or conditional logic. Several hypotheses have been explored:

  • Static or conditional offset subtracted from the sum
  • Offset based on specific bytes (e.g., command, zone byte)
  • Very small chance of a lookup table (LUT) approach per command (dont think so though since IP buttons have only 256KB RAM)

Consequences

If the checksum is wrong, the Bodet PSA system and its components obviously ignore the packet. Hence generating your own commands reliably is not yet possible unless mimicking an exact known good packet.

This makes full integration with modern systems (for triggering Bodet audio via automation) dependent on further reverse engineering.


Please Help me !!!

If you have firmware dumps, better knowladge of UDP and reverse engeneering checksums or just generally more insights, feel free to contribute

Bruteforcing Tool (hexen.py)

The executables/hexen.py script provides a utility to send raw hex payloads and includes a bruteforce mode for the last byte of a given hex prefix. This is particularly useful for trying to find working checksums or other variable last bytes.

How it Works:

  1. Initiating Bruteforce:

    • Run the script: python hexen.py
    • To start a bruteforce, type: brute <hex_prefix>
      • Example: brute 4d454c0021010004ff300180000000000000000000000000010202010f010001
      • The script will then iterate through all possible last bytes (0x00 to 0xFF) appending them to this prefix.
  2. Configuration Prompts:

    • Mode Selection:
      • (1) Manual: Sends one packet at a time and asks for feedback.
      • (2) Auto Ascending: Sends all packets from <prefix>00 to <prefix>ff automatically.
      • (3) Auto Descending: Sends all packets from <prefix>ff down to <prefix>00 automatically.
    • Delay:
      • Prompts for the time (in seconds, e.g., 0.5, 1) to wait between sending each packet.
  3. Interactive Controls (During Bruteforce):

    • Manual Mode (1):
      • After each packet is sent, you'll be prompted: Did it work? (y/n/auto/stop/r=retry last 3/c=cancel):
        • y: Confirms the current hex string worked. The bruteforce for this prefix stops, and the successful string is saved to the MAGIC file.
        • n: Continues to the next hex value.
        • auto: Switches to auto-ascending mode for the remainder of the current prefix.
        • stop or c: Aborts the current bruteforce operation.
        • r: Resends the last up to 3 packets (including the current one).
    • Auto Modes (2 or 3) (Windows Only - requires msvcrt):
      • An initial message will inform you: During auto mode: press 'c' to cancel, 'r' to retry last 3, 'p' to pause/resume.
        • c: Cancels the current bruteforce operation.
        • r: Pauses sending, resends the last up to 3 packets, then resumes.
        • p: Toggles pause/resume for the auto-sending process.
  4. Saving Results to MAGIC File:

    • The MAGIC file path is defined at the top of hexen.py (default: /Users/crt/Documents/bodeting/research/bad-bruteforcing/attempt-1.txt).
    • Successful Bruteforce: If you confirm a packet worked (with 'y' in manual mode), the complete successful full_hex_string is automatically appended to this file.
    • Cancelled/Completed (No Success): If the bruteforce is cancelled or finishes all iterations without a 'y' confirmation, you'll be prompted: Kein Zauber hat gewirkt oder du hast abgebrochen. Gib den Suffix für '<hex_prefix>' ein, um ihn ins Buch zu kritzeln (oder Enter zum Überspringen):
      • If you enter a suffix (e.g., fa), the script will save hex_prefix + entered_suffix to the MAGIC file.
      • If you press Enter, nothing is saved for that attempt.
    • The script checks if the directory for the MAGIC file exists and if the file is writable, providing error messages if issues are encountered.

This tool aims to simplify the process of testing variations of known packet structures, especially when only the checksum isnt known

MQX ARM M4 Firmware Analysis Tools

This toolkit provides specialized tools for analyzing MQX ARM M4 firmware, with a particular focus on identifying IP packet checksum algorithms.

Tools Overview

  1. improved_disassembler.py: An enhanced disassembler with visual formatting, pattern recognition, and network protocol awareness.

  2. checksum_finder.py: A specialized tool focused specifically on finding checksum algorithms in firmware.

Installation

Install the required dependencies:

pip install -r requirements.txt

Usage

Analyzing firmware with the improved disassembler

python improved_disassembler.py path/to/firmware.bin -o analysis_output.txt -b 0x08000000

Finding checksum algorithms

python checksum_finder.py path/to/firmware.bin -o checksum_analysis.txt -b 0x08000000

Tool Features

  • Color-coded output for better readability (in terminal)
  • Detection of network-related strings and constants
  • Pattern-based identification of common checksum algorithms
  • Context-aware disassembly around potential checksum code
  • Export analysis to text files for further examination

Understanding the Results

The tools look for:

  • IP header constants: Values commonly found in IP header processing (0x0800, 0x45, 0x06, etc.)
  • Checksum patterns: Common instruction sequences used in checksum calculations
  • Network strings: TCP/IP-related strings in the firmware

When a potential checksum implementation is found, the tools provide the surrounding context to help understand the algorithm.