Skip to content

Latest commit

 

History

History
executable file
·
99 lines (67 loc) · 4.32 KB

protocol-behavior-notes.md

File metadata and controls

executable file
·
99 lines (67 loc) · 4.32 KB

Protocol Behavior and Binary Evidence

This document collects runtime strings, binary evidence, and related corroboration for the protocol findings in protocol.md and packet-reference.md.

Marconi Architecture

The network subsystem is logitech::marconi with these observed classes:

  • DiscoveryMgr, BroadcastDiscovery, NodeStoreDiscovery
  • ConnectionMgr, Tunnel, Device, Watchdog

Source Paths

Build paths recovered from debug strings in the binary:

logi\provider\flow\lib\flow\src\Device.cpp
logi\marconi\lib\marconi\src\BroadcastDiscovery.cpp
logi\marconi\lib\marconi\src\DiscoveryMgr.cpp
logi\marconi\lib\marconi\src\Tunnel.cpp
logi\provider\devices\src\devio\features\feature_1814_change_host.cpp

Feature flags: marconi_broadcast_discovery_enabled, marconi_nodestore_discovery_enabled, marconi_discovery_listen_only, flow_sentry_verbose

Discovery Log Strings

Internal log format strings from the binary confirm the discovery packet fields:

Broadcasting InitiateDiscoveryPacket: (%u, %u, %u), force: %s.
Received BeaconPacket: (%u, %u, %u), hostId: %s, from: %s:%u, to: %s:%u, force: %s, ping port %u, isEnabled: %s, peer hostId: %s.
Unicasting PingPacket: (%u, %u, %u), hostId: %s, address: %s:%u, force: %s.
Received PingPacket: (%u, %u, %u), hostId: %s, from: %s:%u, to: %s:%u, force: %s, connect port: %u, device.peer[%u]: hostId: %s
Initiating connection: (%u, %u, %u), hostId: %s, from: %s:%u, to: %s:%u, force: %s.

Tunnel Log Strings

Sending ClientHelloPacket, %s
Received ClientHelloPacket; hostId: %s, %s
Sending ServerHelloPacket, %s
Sending PromoteConnectionPacket, hostId: %s
Sending HeartbeatPacket, hostId: %s (%I64d, %I64d)

> **Note:** This is a Windows log format string, not the wire payload. The actual HeartbeatPacket wire payload is a single u8 counter.
Sending GlobalDataPacket; size: %u, %s.
Sending DeviceDataPacket; size: %u, %s.

Flow Packet Classes

Observed in binary strings: SettingsPacket, InitiateFlowPacket, SetCurrentHostPacket, keyboard::KeyPacket, clipboard::ClipboardUpdatePacket, clipboard::GetFormatDataPacket, clipboard::FormatDataPacket, clipboard::FileDescriptorsPacket, clipboard::FileDataPacket, clipboard::ErrorPacket, SetOwnerPacket

Discovery Packet Schemas

Static analysis of InitiateDiscoveryPacket, BeaconPacket, and PingPacket deserializers at known RVAs in the binary:

Field InitiateDiscovery Beacon Ping
id u32 (+0x10) u32 (+0x10) u32 (+0x10)
serialNumber u32 (+0x14) u32 (+0x14) u32 (+0x14)
channel u32 (+0x18) u32 (+0x18) u32 (+0x18)
hostId — string (+0x20) string (+0x20)
force bool (+0x1c) bool (+0x40) bool (+0x40)
port — u16 (+0x42) u16 (+0x42)

Note: Offsets are from Windows binary RVA analysis (deserializer function offsets), not the wire format. The actual wire format is: identity(8) + channel(4) + presenceFlag(1).

HID++ Device Switching

Flow uses HID++ for local host switching. Relevant features observed:

  • 0x1814 — Feature1814ChangeHost: GetHostInfo, SetCurrentHost, GetCookies, event ChangeHostRequestedEvent
  • 0x1815 — host metadata / host names

thekogans Library

Logitech links several thekogans open-source libraries (https://github.com/thekogans):

  • thekogans/crypto -- AES-256-GCM, X25519 ECDH, key derivation
  • thekogans/packet -- packet framing, serialization, session management
  • thekogans/util -- Serializer, Buffer, SecureVector
  • thekogans/stream -- stream-based serialization

The frame format wraps FARS-serialized payloads in a thekogans::packet envelope with AES-256-GCM encryption via thekogans::crypto.

Frame layout on the wire:

keyId(32) + frameCiphertextLength(4) + ivLength(2) + ciphertextLength(4) + macLength(2) + nonce(12) + ciphertext + tag(16)

After decryption, the plaintext contains a PlaintextHeader (2 bytes: random padding length + flags), optional random padding, optional Session::Header (24 bytes: GUID + sequence number), and the serialized packet.

The packet itself uses a variable-length header: magic(4) + classNameLength(varint) + className + version(2) + size(varint).

In Flow captures, ClientHelloPacket / ServerHelloPacket carry the X25519 DHE parameters and negotiated session keyId used by subsequent frames.