Skip to content

SessionKey handshake for V1-initial S7-1200 PLCs#724

Open
gijzelaerr wants to merge 40 commits into
masterfrom
research/harpo-port-incomplete
Open

SessionKey handshake for V1-initial S7-1200 PLCs#724
gijzelaerr wants to merge 40 commits into
masterfrom
research/harpo-port-incomplete

Conversation

@gijzelaerr
Copy link
Copy Markdown
Owner

Summary

Complete port of the HarpoS7 Family-0 session-key authentication chain, enabling browse() and other S7CommPlus data operations on V1-initial S7-1200 PLCs (FW < 4.5) that currently drop the connection after session setup.

  • Full crypto chain: 11 transpiled monoliths, BigInt operations, Transform7/12/13, PreSeedTransform, KeyDerivationTransform, SeedTransform, LutGenerator, ChecksumTransform, HarpoFingerprint, RealPlcAuthenticator — all byte-identical against HarpoS7 C# test vectors for both S7-1500 and S7-1200 key families
  • 25 vendored Siemens public keys for key lookup by fingerprint
  • Wired into _setup_session(): when the PLC's CreateObject response contains a known public key fingerprint and a session challenge, the 180-byte SecurityKeyEncryptedKey blob is automatically generated and included at address 1830
  • 104 session-auth tests including end-to-end vector tests matching the C# reference implementation

What this fixes

V1-initial S7-1200 PLCs (FW v4.0–v4.4) require a SessionKey blob in the session-setup SetMultiVariables write. Without it, the PLC drops the connection. This PR generates that blob using the same crypto as TIA Portal, ported from HarpoS7 (MIT).

Test plan

  • 104 session-auth unit tests (monoliths, transforms, fingerprint, end-to-end blob vectors)
  • Full test suite: 1673 passed, 0 failed
  • Needs real-PLC verification@xBiggs can you test this branch against your S7-1200 FW v4.2.2? Enable debug logging and try browse().

New dependency

  • cryptography (for AES-ECB in the authenticator)

Closes #710, closes #717

🤖 Generated with Claude Code

gijzelaerr and others added 26 commits April 27, 2026 08:28
V1-initial S7-1200 PLCs (e.g. FW v4.2.x) only return ServerSessionVersion
when the client introduces itself with a fuller CreateObject attribute set.
A minimal request (ClientRID only) gets an incomplete session and every
subsequent CommPlus op fails with ERROR2 (0x05A9). Match TIA Portal's
attribute set so the PLC fills in ServerSessionVersion, then echo it back
verbatim in a V2 SetMultiVariables.

ServerSessionVersion is a Struct(314) on real hardware, not a UDInt; capture
it verbatim and echo unchanged. Session-setup write uses V2 framing,
transport flags 0x34, and no IntegrityId regardless of what the PLC
negotiated on initial connect (matches thomas-v2 SetSessionSetupData). Also
fixes the broken STRUCT case in _skip_typed_value (4-byte ID + key/value
pairs + 0x00 terminator, not VLQ count + element list).

Sync client only for now — async will mirror once verified against real
hardware. Refs #710, #712.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The CreateObject response header is 10 bytes long with no SessionId field;
the actual session IDs are returned as a list of UInt32 VLQ values in the
ResponseSet body (after ReturnValue + ObjectIdCount). Our code was reading
14 bytes as if a regular response header, picking up garbage as the session
ID. The wrong InObjectId then caused the V2 SetMultiVariables session-setup
to be rejected by real PLCs (TCP RST). Refs #710 #712.

Reference: thomas-v2/S7CommPlusDriver CreateObjectResponse.Deserialize.

Also updates the test emulator to emit responses in the same format real
PLCs use (10-byte header, ObjectIds list), so the unit tests stay
representative.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The V1-initial S7-1200 drops the V2 SetMultiVariables session-setup
connection if we write its own device identity (element 319 of the
ServerSessionVersion struct, e.g. "1;6ES7 215-1BG40-0XB0 ;V4.2") back
to it verbatim. TIA Portal handles this by stripping element 319 to an
empty WString before echoing — replicating that here.

The rest of the captured Struct(314) value is echoed unchanged.

Refs #710 #712.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Frame-by-frame comparison of TIA Portal V19's pcap (against an S7-1200
FW 4.2.2, V1-initial firmware) versus our previous SetMultiVariables
shows TIA writes *two* items in the session-setup frame:

  1. address 1830 (SESSION_SETUP_LEGITIMATION) — a Struct(1800) with
     four nested fields plus a 180-byte Blob. The blob carries the
     PLC's 8-byte OMS session UUID at offset 32 (little-endian); the
     remaining bytes look like opaque identity/integrity material.
  2. address 306 (SERVER_SESSION_VERSION) — the existing PAOM-stripped
     echo.

Without the address-1830 item the V1-initial PLC silently closes the
TCP connection right after the setup write — the symptom @xBiggs
reports on #710 / #713.

We capture the OMS UUID from the CreateObject response's
ObjectVariableTypeName attribute (id 233, "01:HEX" WString) and patch
it into the blob; everything else is replayed verbatim from the TIA
reference capture as a first-pass experiment. If the PLC validates
other byte ranges, we'll have to reverse those next.

The two-item form is gated on having an OMS UUID. The C# driver's
existing one-item form (SERVER_SESSION_VERSION only) still runs on
PLCs that don't surface an OMS UUID, matching the C# reference exactly.

Reference: thomas-v2/S7CommPlusDriver SetMultiVariablesRequest.cs;
TIAPortalV19AccessibleDevices.pcapng frame 31 (#710 / #713).

Refs #710 #712 #713

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After 0c9af7c the parser kept scanning past the SERVER_SESSION_VERSION
attribute (so it could also grab ObjectVariableTypeName for the V2
legitimation), which made the trailing "ServerSessionVersion not found"
debug fire on every successful capture. Gate it on the captured fields
so it only fires when we actually didn't find it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wireshark's s7comm-plus dissector reveals that the value at address
1830 is a Struct(1800) named ``StructSecurityKey`` carrying a
``SessionKey`` — specifically a 180-byte ``SecurityKeyEncryptedKey``
blob with the layout:

  0-3   uint32 LE  magic = 0xFEE1DEAD
  4-7   uint32 LE  blobsize (0xB4)
  16-23 uint64 LE  symmetric_key_checksum
  32-39 uint64 LE  public_key_checksum    (what attribute 233 carries)
  48-N            encrypted_random_seed   (RSA-encrypted)
  N..   16 bytes   AES-CBC IV
  N+16..56 bytes   encrypted_challenge

So generating this requires Siemens' RSA public key (identified by the
8-byte fingerprint in attribute 233's "01:HEX" string) plus the KDF
that turns the seed into the AES-CBC key. We don't have either, so the
TIA-replay we shipped in a2111e7 was always going to fail against any
new session — the PLC cannot decrypt a static blob.

Roll back the address-1830 send. Keep the public-key checksum
extraction as a diagnostic capture (renamed from `_oms_session_uuid`
to `_public_key_checksum` to match the dissector's terminology); a
future commit can use it to dispatch to a key-aware handshake once we
have the keys, or to clearly log "this firmware needs a SessionKey we
can't generate" when we don't.

Net effect on V1-initial S7-1200 (FW < 4.5): same as before this PR —
SetupSession still fails, the unified client falls back to legacy
PUT/GET, db_read works, browse() requires CommPlus and so still
raises. PR #713 stays a draft pending the key situation.

Refs #710 #712 #713

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First slice of the S7CommPlus session-key handshake (refs #717). Adds
a fingerprint parser and an in-memory public-key lookup for the three
PLC families HarpoS7 1.1.0 supports: S7-1500 (family 0), S7-1200
(family 1) and PlcSim (family 3). Key bytes are vendored verbatim
from bonk-dev/HarpoS7's MIT-licensed binaries.

@xBiggs's PLC fingerprint `01:BD426B091F08731A` is in the bundle, so
once the rest of the handshake (AES, SHA-256, the proprietary monolith
transforms, and the auth orchestration) lands we'll be able to
generate a valid SecurityKeyEncryptedKey for that PLC.

This commit alone changes no runtime behaviour — the new module is
not yet wired into `_setup_session`. That happens in a later slice
once the handshake produces verified output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Second slice of the HarpoS7 port (refs #717). Adds the small SHA-256
fingerprinting function that computes the symmetric/public key id
fields embedded in the SecurityKeyEncryptedKey blob.

The function is just `SHA-256(key[:24] + b"DERIVE")[:8]` — well-defined
in HarpoS7's `KeyExtensions.DeriveKeyId`. We verify byte-correctness in
two ways:

  1. The three test vectors HarpoS7 ships in `KeyExtensionsTests.cs`
     (a 64-byte PlcSim key plus two repeating-byte cases).
  2. A self-consistency check: every bundled public key, when run
     through `derive_key_id`, must produce the LE byte-reversal of
     the BE-display hex it's keyed on. This catches both algorithm
     bugs and key-byte transcription errors in #b44792d.

@xBiggs's PLC fingerprint `01:BD426B091F08731A` round-trips correctly,
so once the next slices land we can compute exactly the
publickeychecksum / symmetrickeychecksum the PLC expects to see.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Third slice of the HarpoS7 port (refs #717). Produces the leading 48
bytes of the 180/216-byte SessionKey blob — magic, length, key
fingerprints, and per-family flags — matching the layout the
Wireshark s7comm-plus dissector decodes.

The headline regression test compares our output against TIA Portal
V19's actual wire bytes from @xBiggs's pcap (frame 31 of
TIAPortalV19AccessibleDevices.pcapng), modulo the per-session
symmetric_key_id slot (which TIA randomises). Every other byte in
the 48-byte header matches verbatim.

Ported from HarpoS7's `BlobMetadataWriter.WriteMetadata` plus the
per-family `Get{Public,Symmetric}KeyFlags` and `GetBlobLength`
helpers. The PlcSim path is preserved for completeness, though the
seed handling on that family differs and isn't exercised yet.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fourth slice of the HarpoS7 port (refs #717). Adds three pure-SHA-256
KDFs the handshake uses to spin off the various AES keys:

- derive_challenge_encryption_key — 16-byte AES-128 key for encrypting
  the PLC challenge
- derive_seed_encryption_key_and_iv — 32-byte AES-256 key + 16-byte IV
  for encrypting the random seed (counter-mode SHA-256 chain over
  reverse(a2) || a3 || counter_byte)
- derive_legitimation_challenge_key — 24-byte key for encrypting the
  legitimation challenge after session establishment

All three verified byte-for-byte against the test vectors HarpoS7
ships in `KeyUtilitiesTests.cs`.

The fourth helper from upstream — `derive_session_key` — is
intentionally left out of this slice: it depends on
`HarpoFingerprint.FingerprintChallenge`, which lives in the Family-0
"monolith" transforms and lands in a later slice.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ash_block)

Fifth slice of the HarpoS7 port (refs #717). Adds the proprietary
128-bit transform that powers HarpoAesCtr's integrity-MAC computation
and the encrypted-seed generation in the SessionKey blob.

Three primitives — all pure-Python, all verified byte-for-byte against
HarpoS7's vector tests:

  - lut1: one round of the transform, 16 → 16 bytes
  - generate_lookup_table: 16-byte key → 4 KB working table
  - hash_block: 16-byte input → 16-byte output, using the working table

The full 4096-byte expected output of generate_lookup_table is pinned
verbatim from HarpoHashTests.cs as a regression vector — covers both
sub-loops in the C# implementation (the lut1 cascade and the
xor-and-replicate fill phase).

The 512-byte LUT_SEED constant doubles as HarpoHashSeed (upstream
stores it twice for ergonomic byte vs ushort access; we just reslice
when needed).

This unblocks the next slice: HarpoAes / HarpoAesCtr.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sixth slice of the HarpoS7 port (refs #717). Thin wrapper around the
``cryptography`` library's AES-128-ECB primitive, matching HarpoS7's
``HarpoAes`` API. Used as a building block by ``HarpoAesCtr`` for
counter encryption and integrity-MAC checksum derivation.

Tests verify the canonical NIST FIPS-197 §C.1 vector plus basic
construction invariants. Skipped when the optional ``cryptography``
package is unavailable, matching the existing ``test_s7_v2.py``
pattern for code under the ``s7commplus`` extra.

Also includes a one-time `ruff format` cleanup of the slice-4 KDF
tests — collapsing a few short multi-line hex literals onto one line
each. No behaviour change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Seventh slice of the HarpoS7 port (refs #717). Ports the Init and
EncryptCtr halves of HarpoAesCtr — the custom AES-CTR-with-MAC
primitive that encrypts the seed and challenge inside the
SecurityKeyEncryptedKey blob.

Init derives a 4 KB working table from `AES-ECB(key, 0)` and folds
the IV into a 16-byte counter through HarpoHash rounds. EncryptCtr
increments the counter, AES-encrypts it for keystream, XORs against
plaintext, and feeds ciphertext into a running HarpoHash accumulator.

The two end-to-end vectors from HarpoAesCtrTests pass byte-for-byte:

- TestInit: counter state after Init(0xCC * 16) matches the expected
  16 bytes.
- TestEncrypt2Times: encrypting 16 bytes then 24 bytes back-to-back
  produces the expected ciphertexts — exercises the partial-block
  carryover code path.

CalculateChecksum is intentionally deferred to a follow-up slice; it
needs the full mock-state plumbing the upstream test uses, plus the
4096-byte mockChecksumLut as a vendored test asset.

The 12-byte-IV and unaligned-tail paths are left as
NotImplementedError — same as upstream — since the SessionKey
handshake never hits them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Eighth slice of the HarpoS7 port (refs #717). Completes HarpoAesCtr
by porting the CalculateChecksum finaliser. Folds the bit-lengths of
encrypted regions into the running MAC, runs one final HarpoHash
round, AES-encrypts the original IV extension, and XORs the two for
the output checksum bytes.

Verified against HarpoS7's CalculateChecksumTest vector via direct
field injection (Python equivalent of the C# reflection-based
mocking). The 4096-byte mockChecksumLut from the upstream test is
vendored as `tests/fixtures/harpo_aes_ctr_mock_checksum_lut.bin`.

This finishes "bucket 1" of the port — every standard primitive
(SHA-256 KDFs, AES-128-ECB, HarpoHash, HarpoAesCtr) now passes
byte-for-byte against HarpoS7's own ground-truth test vectors. What
remains is the Family-0 monolith transforms (the proprietary block
cipher) and the auth orchestration layer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ninth slice of the HarpoS7 port (refs #717). Adds a mechanical C#-to-
Python transpiler in tools/ and runs it against HarpoS7's Family-0
Monoliths 1-8 and 11 — straight-line bitwise transforms that compute
intermediate state for the SecurityKeyEncryptedKey blob.

Each generated monolith passes byte-for-byte against HarpoS7's own
test vectors (vendored as `tests/fixtures/family0/monoliths/*.bin`).
Total ~8.5k transpiled statements verified, no manual edits to the
generated code.

Strategy notes:

- Each MonolithN.Execute is a stream of `;`-terminated statements:
  variable declarations (discardable), `uVar = expr` assignments,
  `dst_dwords[i] = expr` writes, and a single optional `return`. No
  internal control flow. The transpiler treats the body as flat text:
  splits on `;`, normalises src/dst aliases, masks every assignment
  to uint32 (Python ints don't wrap), and emits a Python function
  with src/dst-dword views.
- Monoliths 9 and 10 are orchestrators that call into Nine/Part1..11
  and Ten/Part1..3 — those use a different signature taking a shared
  `locals` array. They're not yet ported and arrive in a follow-up
  slice that extends the transpiler's signature handling.

The Transforms layer (the public API into Family-0) and the auth
orchestration come after; this slice is pure infrastructure.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rators

Tenth slice of the HarpoS7 port (refs #717). Extends the transpiler
to handle Family-0 Part subprograms (which take a shared `locals`
uint array in addition to or instead of source/destination buffers),
runs it on all 14 Parts (Nine/Part1..11 + Ten/Part1..3), and adds
hand-written Monolith9/Monolith10 orchestrators that chain them.

The transpiler now detects the C# `Execute` parameter list and
emits the matching Python signature: `Execute(source, locals)`,
`Execute(locals)`, and `Execute(destination, locals)` are all
supported. `locals` is renamed `locals_` to avoid the Python
builtin.

Mechanical translation: ~17k more transpiled statements across the
14 Parts. All compile and run, no exceptions.

Vector status:
  - Monolith9 / Monolith10 produce non-byte-exact output against the
    upstream blob fixtures (xfail-marked, refs #717). Monolith10
    matches for the first ~219 bytes then diverges, suggesting the
    bug is in a specific Part rather than the orchestrator structure.
    Investigation deferred — not on the critical path for the
    SessionKey handshake, which uses the simpler Monoliths and the
    Transforms layer (next slice).

  - The `test_monolith9_and_10_at_least_run` smoke test catches
    regressions in transpiler signature handling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Eleventh slice of the HarpoS7 port (refs #717). Manual port of
``HarpoS7.Family0.BitOperations.BigIntOperations`` — short, idiomatic
helpers for packing/unpacking 192-bit integers between the wire
format and the proprietary 30-bits-per-limb representation the
SessionKey curve operations use internally.

Five operations: prepare (6→5 uints), finalize (5→6 uints),
prepare_finalize (in-place fusion), rotate_right_30, rotate_left_31.
All exact-byte verified against HarpoS7's vector fixtures.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Twelfth slice of the HarpoS7 port (refs #717). Manual port of the
four ``BigInt*`` Transform classes plus the BigIntegerCompressor
helper. Python's built-in ``int`` is arbitrary-precision, so we
don't need a separate BigInteger library — just careful use of
``int.to_bytes`` and ``int.from_bytes`` with the right signedness.

Operations:
  - big_int_addition (8 fixtures, 2 sub-cases)
  - big_int_subtraction (11 fixtures, 4 sub-cases incl. all the
    negative-result corner cases that need the upstream's signed
    sign-extension dance)
  - big_int_multiplication (9 fixtures, 3 sub-cases)
  - big_int_square (10 fixtures, 2 sub-cases)

All 11 vector tests pass byte-for-byte against the upstream blob
fixtures.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Thirteenth slice of the HarpoS7 port (refs #717). Manual port of the
two GHASH-style transforms — both vector-verified against HarpoS7's
fixtures.

LutGenerator builds a 4 KB table of 256 UInt128 values from a 16-byte
seed by iterated GF(2¹²⁸) doubling under the AES-GCM-style reduction
polynomial x¹²⁸ + x⁷ + x² + x + 1.

ChecksumTransform consumes that table plus a 16-byte key to produce
a 16-byte integrity tag, walking key bytes MSB→LSB and rotating the
work buffer one byte after every 4-byte block.

Neither depends on the still-broken Monolith9/10 path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Root cause of part of the Monolith9/10 divergence: C#'s uint << N
truncates the result to 32 bits, but Python's int << N doesn't. When
the overflow bits get picked up by a subsequent ~ (negative int) &
operation, the high bits differ from C#. Same for * 2.

Fix: add & 0xFFFFFFFF after every << and * 2 in the transpiled output.
Since << has higher precedence than & in Python, the mask applies to
the shift result before any surrounding operator sees it.

Result: Ten/Part1 is now byte-perfect (0 diffs vs C#). Ten/Part2 still
has 57 diffs from a different root cause (under investigation — need
more C# binary-search checkpoints). Monoliths 1-8/11 continue to pass.

Diagnosed using dotnet test against HarpoS7 with intermediate locals[]
dumps compared to Python output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Root causes diagnosed using .NET-side intermediate locals[] dumps
compared statement-by-statement against the Python port:

1. Left-shift overflow (Part1): C# uint << N truncates to 32 bits;
   Python int << N doesn't. When overflow bits get picked up by a
   subsequent ~ (negative) & operation, the result diverges. Fix:
   mask << results with & 0xFFFFFFFF in subexpressions.

2. Right-shift on identifiers (Part2/3): `ident >> N` wasn't
   wrapped in _shr() for uint32 masking. Only `) >> N` was handled.

3. ~(expr) >> N paren matching (Part3): the _fix_right_shifts walker
   found `) >> N`, walked back to the matching `(`, but stripped the
   leading `~` — making `~(X) >> N` into `_shr(X, N)` instead of
   `_shr(~(X), N)`. Fix: include any leading `~` chain as part of
   the operand.

All 11 monoliths + both orchestrators now pass byte-for-byte.
Removed the xfail markers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Port remaining transforms and orchestration for pre-TLS V1
session-key handshake, verified byte-identical against HarpoS7
C# test vectors for both S7-1500 and S7-1200 key families.

New modules:
- transform7: core ECC scalar multiplication (monolith wrappers +
  Transform12 dispatch + BigInt operations)
- seed_transform: generates encrypted seed via Transform7 +
  Monolith1/2/8/11 + Transform13
- pre_seed_transform, key_derivation_transform, transform13:
  Monolith9/10-based key preparation transforms
- monolith_wrappers: WithCopy wrappers for Monoliths 3-7
- fingerprint: HarpoFingerprint challenge fingerprinting with
  vendored data tables (ContextMutator + FingerprintConsts)
- authenticator: RealPlcAuthenticator blob builder (metadata +
  seed + AES-ECB encrypted challenge + GHASH checksum)
- legacy_auth: top-level entry point (authenticate_real_plc)
- key_derivation.derive_session_key: HMAC-SHA256 session key via
  fingerprint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Includes vendored binary data (transform1_data, transform7_data,
transform7_indexes) that were already referenced by code but not
staged, plus test fixtures and vector tests for PreSeedTransform,
KeyDerivationTransform, and Transform13.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Inline small constant tables as documented Python literals in
data/_constants.py — hex ints for opaque values, named tuples
for structured data (ECC coordinates, dispatch tables, mutation
operations). The 4 large tables (transform12 metadata 244K,
big-int aux 18K, fingerprint data1/data2 67K) stay as .bin.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the CreateObject response contains a public key fingerprint
and a 20-byte session challenge, and we have a matching Siemens
public key in our vendored key store, _setup_session() now generates
the 180-byte SecurityKeyEncryptedKey blob and includes it as a
second item (address 1830) in the SetMultiVariables request.

This is the pre-TLS authentication mechanism needed for V1-initial
S7-1200 PLCs (FW < 4.5) where browse() currently fails.

Changes:
- Capture session challenge from CreateObject response (any 20-byte
  BLOB attribute in the PObject tree)
- Store public key fingerprint string for key lookup
- _try_session_key_auth(): look up public key, call
  authenticate_real_plc() to generate blob + session key
- _encode_security_key_struct(): build the Struct(1800) PObject
  wrapping the blob with key descriptors
- _setup_session(): conditionally include SecurityKey as Item 1
  alongside ServerSessionVersion as Item 2
- Add SecurityKey struct IDs to protocol.py

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread s7/session_auth/family0/authenticator.py Dismissed
Comment thread s7/session_auth/family0/authenticator.py Dismissed
Ruff format applied to all new files, f-string lint fixes in
transform13.py, and .bin files excluded from trailing-whitespace
and end-of-file-fixer hooks (they corrupt binary test fixtures).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@gijzelaerr
Copy link
Copy Markdown
Owner Author

@xBiggs ac84da7 adds V3 HMAC integrity framing. After the SessionKey handshake, all data ops now use V3 frames with a 32-byte HMAC-SHA256 prefix (computed from the session key), matching what TIA Portal does in your ProgramBlocks pcap.

Can you test again?

pip install --force-reinstall git+https://github.com/gijzelaerr/python-snap7.git@research/harpo-port-incomplete

This should fix the V254 responses — the PLC was rejecting our unsigned V1 requests after auth.

@xBiggs
Copy link
Copy Markdown

xBiggs commented May 13, 2026

DEBUG:snap7.connection:TCP connected to 192.168.0.1:102
DEBUG:snap7.connection:Sent COTP Connection Request
DEBUG:snap7.connection:Negotiated PDU size: 1024
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc1, length=2
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc2, length=16
DEBUG:snap7.connection:Received COTP Connection Confirm
INFO:snap7.connection:Connected to 192.168.0.1:102, PDU size: 1024
DEBUG:s7.connection:=== InitSSL === sending (26 bytes): 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 33 bytes: 03 00 00 21 02 f0 80 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=38 payload (34 bytes): 02 f0 80 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== InitSSL === received (31 bytes): 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:InitSSL response: version=V1, data_length=23
DEBUG:s7.connection:InitSSL response body (27 bytes): 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === sending (192 bytes): 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 199 bytes: 03 00 00 c7 02 f0 80 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=215 payload (211 bytes): 02 f0 80 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 0f 57 b9 49 85 d1 89 76 4f 23 ba 01 e4 84 fe a4 a4 43 9f a0 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === received (208 bytes): 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 0f 57 b9 49 85 d1 89 76 4f 23 ba 01 e4 84 fe a4 a4 43 9f a0 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response: version=V1, data_length=200
DEBUG:s7.connection:CreateObject response body (204 bytes): 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 0f 57 b9 49 85 d1 89 76 4f 23 ba 01 e4 84 fe a4 a4 43 9f a0 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response header: opcode=0x32 function=0x04CA seq=1 transport=0x36
DEBUG:s7.connection:CreateObject response: return_value=0 object_ids=['0x39b', '0x3c2']
DEBUG:s7.connection:Session created: id=0x0000039B (923), version=V1
INFO:s7.connection:Public key fingerprint captured: 01:BD426B091F08731A
INFO:s7.connection:Session challenge captured (20 bytes): 0f57b94985d189764f23ba01e484fea4a4439fa0
INFO:s7.connection:ServerSessionVersion struct captured (84 bytes)
INFO:s7.connection:SessionKey auth blob generated (180 bytes)
INFO:s7.connection:SecurityKey blob included in session setup
DEBUG:s7.connection:=== SetupSession === sending (390 bytes): 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 c1 b3 05 32 2a f2 38 98 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 dc b5 a6 64 45 b4 1c 14 f6 26 69 59 63 e5 76 cb 07 0b ff c7 32 12 e9 af 5f f9 58 7e 5f 13 70 7e 95 93 1d 75 92 f9 d4 09 25 4c 4d 15 93 84 9d 88 79 0b d4 c0 cb 27 95 34 cd 47 75 4e 6a 66 0a 4d 0c 65 56 b2 f0 8d 1d 77 40 fc 19 e4 3a ba 61 e4 5c 49 fb 08 13 bb 54 da f9 e9 6d e8 1f 24 a8 26 54 90 7e a4 0a 0e e2 2f 90 d0 8f 79 38 a0 83 b1 3d 4e c5 c0 b7 14 56 7c 71 2b 2f 9f 58 9a 6a 49 fb 3b 24 27 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Sent 397 bytes: 03 00 01 8d 02 f0 80 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 c1 b3 05 32 2a f2 38 98 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 dc b5 a6 64 45 b4 1c 14 f6 26 69 59 63 e5 76 cb 07 0b ff c7 32 12 e9 af 5f f9 58 7e 5f 13 70 7e 95 93 1d 75 92 f9 d4 09 25 4c 4d 15 93 84 9d 88 79 0b d4 c0 cb 27 95 34 cd 47 75 4e 6a 66 0a 4d 0c 65 56 b2 f0 8d 1d 77 40 fc 19 e4 3a ba 61 e4 5c 49 fb 08 13 bb 54 da f9 e9 6d e8 1f 24 a8 26 54 90 7e a4 0a 0e e2 2f 90 d0 8f 79 38 a0 83 b1 3d 4e c5 c0 b7 14 56 7c 71 2b 2f 9f 58 9a 6a 49 fb 3b 24 27 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=32 payload (28 bytes): 02 f0 80 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:=== SetupSession === received (25 bytes): 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:SetupSession response: function=0x0542
INFO:s7.connection:Session setup completed successfully
INFO:s7.connection:S7CommPlus connected to 192.168.0.1:102, version=V1, session=923, tls=False
INFO:s7.client:Connected to 192.168.0.1:102 using S7CommPlus
INFO:snap7.client:S7Client initialized (pure Python implementation)
DEBUG:snap7.connection:TCP connected to 192.168.0.1:102
DEBUG:snap7.connection:Sent COTP Connection Request
DEBUG:snap7.connection:Negotiated PDU size: 1024
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc1, length=2
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc2, length=2
DEBUG:snap7.connection:Received COTP Connection Confirm
INFO:snap7.connection:Connected to 192.168.0.1:102, PDU size: 1024
DEBUG:snap7.connection:Sent 25 bytes: 03 00 00 19 02 f0 80 32 01 00 00 00 01 00 08 00 00 f0 00 00 01 00 01 01 e0
DEBUG:snap7.connection:Received TPKT: version=3 length=27 payload (23 bytes): 02 f0 80 32 03 00 00 00 01 00 08 00 00 00 00 f0 00 00 01 00 01 00 f0
INFO:snap7.client:Negotiated PDU length: 240
INFO:snap7.client:[192.168.0.1 R0/S1] Connected to 192.168.0.1:102 rack 0 slot 1
INFO:snap7.client:Auto-tuned max_parallel=2 (PDU=240)
INFO:s7.client:Legacy S7 connected to 192.168.0.1:102
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x04BB seq=3 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 04 bb 00 00 00 03 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (13 bytes): 03 00 01 00 02 81 69 93 59 00 00 00 00
DEBUG:s7.connection:  Full frame (68 bytes): 72 03 00 3c 20 5c 6a 33 29 27 34 0d ad 20 3b e8 1c aa 1a 58 d5 c8 4b 7b e8 df 31 75 d8 0e 43 bd c4 3b ce 52 b5 31 00 00 04 bb 00 00 00 03 00 00 03 9b 36 03 00 01 00 02 81 69 93 59 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 75 bytes: 03 00 00 4b 02 f0 80 72 03 00 3c 20 5c 6a 33 29 27 34 0d ad 20 3b e8 1c aa 1a 58 d5 c8 4b 7b e8 df 31 75 d8 0e 43 bd c4 3b ce 52 b5 31 00 00 04 bb 00 00 00 03 00 00 03 9b 36 03 00 01 00 02 81 69 93 59 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=209 payload (205 bytes): 02 f0 80 72 fe 00 c6 00 00 00 00 00 00 02 84 00 00 00 00 00 00 00 00 00 00 00 17 00 00 9d 6c 00 00 9d 6d 00 00 00 08 00 00 00 02 00 00 9d 6e 00 00 00 04 00 00 03 9b 00 00 9d 6f 00 00 00 04 00 00 04 bb 00 00 9d 70 00 00 00 03 00 03 00 00 9d 71 00 00 00 09 a2 01 3b 00 01 39 ff 88 00 00 9d 72 00 00 00 04 00 00 00 00 00 00 9d 73 00 00 00 04 00 00 04 bb 00 00 9d 74 00 00 00 04 00 00 00 e9 00 00 9d 75 00 00 00 04 00 00 00 00 00 00 9d 76 00 00 00 03 00 06 00 00 9d 77 00 00 00 03 00 00 00 00 9d 78 00 00 00 03 10 00 00 00 9d 79 00 00 00 03 10 12 00 00 9d 7a 00 00 00 03 08 01 00 00 9d 7b 00 00 00 03 10 29 00 00 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (202 bytes): 72 fe 00 c6 00 00 00 00 00 00 02 84 00 00 00 00 00 00 00 00 00 00 00 17 00 00 9d 6c 00 00 9d 6d 00 00 00 08 00 00 00 02 00 00 9d 6e 00 00 00 04 00 00 03 9b 00 00 9d 6f 00 00 00 04 00 00 04 bb 00 00 9d 70 00 00 00 03 00 03 00 00 9d 71 00 00 00 09 a2 01 3b 00 01 39 ff 88 00 00 9d 72 00 00 00 04 00 00 00 00 00 00 9d 73 00 00 00 04 00 00 04 bb 00 00 9d 74 00 00 00 04 00 00 00 e9 00 00 9d 75 00 00 00 04 00 00 00 00 00 00 9d 76 00 00 00 03 00 06 00 00 9d 77 00 00 00 03 00 00 00 00 9d 78 00 00 00 03 10 00 00 00 9d 79 00 00 00 03 10 12 00 00 9d 7a 00 00 00 03 08 01 00 00 9d 7b 00 00 00 03 10 29 00 00 00 00
DEBUG:s7.connection:  Frame header: version=V254, data_length=198, header_size=4
DEBUG:s7.connection:  V254 frame: returning raw data (198 bytes)
[]
DEBUG:snap7.connection:Sent 33 bytes: 03 00 00 21 02 f0 80 72 01 00 12 31 00 00 04 d4 00 00 00 04 00 00 03 9b 36 00 00 00 00 72 01 00 00
INFO:snap7.connection:Disconnected from 192.168.0.1:102
DEBUG:snap7.client:Heartbeat stopped
INFO:snap7.connection:Disconnected from 192.168.0.1:102
INFO:snap7.client:Disconnected from 192.168.0.1:102
DEBUG:snap7.client:Heartbeat stopped
INFO:snap7.client:Disconnected from 192.168.0.1:102

ac84da7.zip

@gijzelaerr
Copy link
Copy Markdown
Owner Author

V3 HMAC framing works — the PLC accepted the signed EXPLORE request (no RST). But the V254 response is actually the PLC's native format for EXPLORE on V1-initial firmware. Looking at your TIA Portal ProgramBlocks pcap, TIA doesn't use EXPLORE at all — it uses GET_VAR_SUBSTREAMED (0x0586) for browsing.

So the connection and framing are fully working now. The remaining browse() issue is that we need to use GET_VAR_SUBSTREAMED instead of EXPLORE for V1-initial PLCs, which is a separate change.

For the immediate fix: can you test db_read() or other data operations? Those should work now with the V3 HMAC framing:

import logging
logging.basicConfig(level=logging.DEBUG)
from s7 import Client

client = Client()
client.connect("192.168.0.1", 0, 1)
print("protocol:", client.protocol)
data = client.db_read(7, 0, 2)
print("db7[0:2]:", data)
client.disconnect()

V1-initial PLCs expect a 4-byte big-endian InObjectId in the EXPLORE
payload instead of a VLQ-encoded explore_id. Match the format observed
in TIA Portal v19 pcaps: InObjectId + fixed params + sequence byte.

Default explore target is 0x38 (system object for PLC program tree),
matching what TIA Portal sends.
@gijzelaerr
Copy link
Copy Markdown
Owner Author

@xBiggs ef9aee0 fixes the EXPLORE payload format. Our code was sending a VLQ-encoded explore_id, but V1-initial PLCs expect a 4-byte big-endian InObjectId (like TIA Portal sends). Also targets object 0x38 (system PLC program tree) instead of root.

pip install --force-reinstall git+https://github.com/gijzelaerr/python-snap7.git@research/harpo-port-incomplete

Try both explore() and browse():

import logging
logging.basicConfig(level=logging.DEBUG)
from s7 import Client

client = Client()
client.connect("192.168.0.1", 0, 1)
print("explore:", client.explore())
print("browse:", client.browse())
client.disconnect()

@xBiggs
Copy link
Copy Markdown

xBiggs commented May 13, 2026

DEBUG:snap7.connection:TCP connected to 192.168.0.1:102
DEBUG:snap7.connection:Sent COTP Connection Request
DEBUG:snap7.connection:Negotiated PDU size: 1024
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc1, length=2
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc2, length=16
DEBUG:snap7.connection:Received COTP Connection Confirm
INFO:snap7.connection:Connected to 192.168.0.1:102, PDU size: 1024
DEBUG:s7.connection:=== InitSSL === sending (26 bytes): 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 33 bytes: 03 00 00 21 02 f0 80 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=38 payload (34 bytes): 02 f0 80 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== InitSSL === received (31 bytes): 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:InitSSL response: version=V1, data_length=23
DEBUG:s7.connection:InitSSL response body (27 bytes): 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === sending (192 bytes): 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 199 bytes: 03 00 00 c7 02 f0 80 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=215 payload (211 bytes): 02 f0 80 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 23 c4 91 23 89 54 04 bb 88 35 a6 4f 18 ab 0d 7c 71 cf 24 c4 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === received (208 bytes): 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 23 c4 91 23 89 54 04 bb 88 35 a6 4f 18 ab 0d 7c 71 cf 24 c4 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response: version=V1, data_length=200
DEBUG:s7.connection:CreateObject response body (204 bytes): 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 23 c4 91 23 89 54 04 bb 88 35 a6 4f 18 ab 0d 7c 71 cf 24 c4 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response header: opcode=0x32 function=0x04CA seq=1 transport=0x36
DEBUG:s7.connection:CreateObject response: return_value=0 object_ids=['0x39b', '0x3c2']
DEBUG:s7.connection:Session created: id=0x0000039B (923), version=V1
INFO:s7.connection:Public key fingerprint captured: 01:BD426B091F08731A
INFO:s7.connection:Session challenge captured (20 bytes): 23c49123895404bb8835a64f18ab0d7c71cf24c4
INFO:s7.connection:ServerSessionVersion struct captured (84 bytes)
INFO:s7.connection:SessionKey auth blob generated (180 bytes)
INFO:s7.connection:SecurityKey blob included in session setup
DEBUG:s7.connection:=== SetupSession === sending (390 bytes): 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 21 93 db fd f7 a6 ca 34 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 4a 2a 34 e2 75 ac ff 2c cd 10 b7 f5 db c3 25 78 a0 6f 16 7d 64 a0 be 74 ef 27 2a 52 c8 05 bf 0b 35 68 a9 f7 f1 c8 5c 95 6a 53 ed ce 4f d3 a9 27 1d ec a1 00 95 3d e6 17 39 aa 39 27 b7 e8 2b d0 70 88 b0 7d 86 d3 24 ec ca 7d bf 34 e8 a3 27 20 6d ff 08 1d 02 f8 d5 e4 e7 af 20 50 11 fe 00 f1 05 f4 9c a6 fb 42 09 b6 55 e6 48 55 98 dc fc bc 91 79 1d 49 cb 66 bf 33 16 cc 22 45 cf 35 65 2c 5c 10 4e a5 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Sent 397 bytes: 03 00 01 8d 02 f0 80 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 21 93 db fd f7 a6 ca 34 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 4a 2a 34 e2 75 ac ff 2c cd 10 b7 f5 db c3 25 78 a0 6f 16 7d 64 a0 be 74 ef 27 2a 52 c8 05 bf 0b 35 68 a9 f7 f1 c8 5c 95 6a 53 ed ce 4f d3 a9 27 1d ec a1 00 95 3d e6 17 39 aa 39 27 b7 e8 2b d0 70 88 b0 7d 86 d3 24 ec ca 7d bf 34 e8 a3 27 20 6d ff 08 1d 02 f8 d5 e4 e7 af 20 50 11 fe 00 f1 05 f4 9c a6 fb 42 09 b6 55 e6 48 55 98 dc fc bc 91 79 1d 49 cb 66 bf 33 16 cc 22 45 cf 35 65 2c 5c 10 4e a5 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=32 payload (28 bytes): 02 f0 80 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:=== SetupSession === received (25 bytes): 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:SetupSession response: function=0x0542
INFO:s7.connection:Session setup completed successfully
INFO:s7.connection:S7CommPlus connected to 192.168.0.1:102, version=V1, session=923, tls=False
INFO:s7.client:Connected to 192.168.0.1:102 using S7CommPlus
INFO:snap7.client:S7Client initialized (pure Python implementation)
DEBUG:snap7.connection:TCP connected to 192.168.0.1:102
DEBUG:snap7.connection:Sent COTP Connection Request
DEBUG:snap7.connection:Negotiated PDU size: 1024
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc1, length=2
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc2, length=2
DEBUG:snap7.connection:Received COTP Connection Confirm
INFO:snap7.connection:Connected to 192.168.0.1:102, PDU size: 1024
DEBUG:snap7.connection:Sent 25 bytes: 03 00 00 19 02 f0 80 32 01 00 00 00 01 00 08 00 00 f0 00 00 01 00 01 01 e0
DEBUG:snap7.connection:Received TPKT: version=3 length=27 payload (23 bytes): 02 f0 80 32 03 00 00 00 01 00 08 00 00 00 00 f0 00 00 01 00 01 00 f0
INFO:snap7.client:Negotiated PDU length: 240
INFO:snap7.client:[192.168.0.1 R0/S1] Connected to 192.168.0.1:102 rack 0 slot 1
INFO:snap7.client:Auto-tuned max_parallel=2 (PDU=240)
INFO:s7.client:Legacy S7 connected to 192.168.0.1:102
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x04BB seq=3 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 04 bb 00 00 00 03 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (16 bytes): 00 00 00 38 00 01 00 01 00 00 0a 00 00 00 00 00
DEBUG:s7.connection:  Full frame (71 bytes): 72 03 00 3f 20 f6 b3 e1 71 92 2d db b3 09 2a 31 1e f1 4a 82 c8 5a 70 d2 f9 07 75 bd ad 3f 56 0f 4a 81 cf 55 8b 31 00 00 04 bb 00 00 00 03 00 00 03 9b 36 00 00 00 38 00 01 00 01 00 00 0a 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 78 bytes: 03 00 00 4e 02 f0 80 72 03 00 3f 20 f6 b3 e1 71 92 2d db b3 09 2a 31 1e f1 4a 82 c8 5a 70 d2 f9 07 75 bd ad 3f 56 0f 4a 81 cf 55 8b 31 00 00 04 bb 00 00 00 03 00 00 03 9b 36 00 00 00 38 00 01 00 01 00 00 0a 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=430 payload (426 bytes): 02 f0 80 72 03 01 9f 20 49 e3 67 b4 a3 b5 6c 35 9a 37 cb ee 9e 0c 10 b0 c5 4b 14 67 ba 6d 66 d1 80 6a 79 7e 4c ac 23 73 32 00 00 04 bb 00 00 00 03 34 00 00 00 00 03 0d a1 00 00 00 01 93 2e 30 00 a3 81 69 00 15 06 41 53 52 6f 6f 74 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 93 1b 10 02 08 13 00 00 00 0e 00 00 00 a3 a3 52 00 14 00 00 a3 be 56 10 02 04 00 00 00 00 a3 93 2f 00 04 00 a3 93 1c 00 15 0b 41 4f 4d 2e 52 35 30 36 5f 30 32 a3 93 1d 00 15 08 30 35 2e 30 36 2e 30 31 a3 93 1e 00 15 0b 30 35 2e 30 36 2e 30 32 2e 30 34 a3 93 1f 00 15 0f 50 41 4f 4d 2e 52 35 30 36 5f 30 34 5f 30 34 a3 9e 3c 10 02 10 72 01 a7 89 20 bb 75 40 8a ea 1b ee 39 6c e7 9b a1 00 00 00 03 93 58 30 00 a3 81 69 00 15 0a 50 4c 43 50 72 6f 67 72 61 6d a3 93 15 00 05 8c aa bc ca ff ac 91 d8 64 a3 93 16 00 04 00 a3 9c 33 00 01 01 a3 9d 22 00 05 00 a3 a1 2f 00 03 04 09 a3 a3 3f 10 03 02 ea 60 ee 47 a3 a4 14 00 01 00 a3 93 2f 00 04 32 a3 bb 26 00 0c 00 00 00 00 a3 bc 31 00 0c 00 00 00 00 a3 bc 32 00 10 00 00 00 00 00 00 00 00 a1 00 00 00 38 be 68 30 00 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 c0 39 20 03 01 04 09 a3 bf 78 10 02 08 09 61 c6 dc db b8 ca bf a3 bf 7a 10 02 08 9c 9f d3 c5 3d f0 37 82 a3 bf 7c 00 05 32 a3 bf 79 00 01 00 a3 bf 7b 00 05 32 a3 bf 7d 00 01 00 a2 a2 a2 00 00 00 00 72 03 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (423 bytes): 72 03 01 9f 20 49 e3 67 b4 a3 b5 6c 35 9a 37 cb ee 9e 0c 10 b0 c5 4b 14 67 ba 6d 66 d1 80 6a 79 7e 4c ac 23 73 32 00 00 04 bb 00 00 00 03 34 00 00 00 00 03 0d a1 00 00 00 01 93 2e 30 00 a3 81 69 00 15 06 41 53 52 6f 6f 74 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 93 1b 10 02 08 13 00 00 00 0e 00 00 00 a3 a3 52 00 14 00 00 a3 be 56 10 02 04 00 00 00 00 a3 93 2f 00 04 00 a3 93 1c 00 15 0b 41 4f 4d 2e 52 35 30 36 5f 30 32 a3 93 1d 00 15 08 30 35 2e 30 36 2e 30 31 a3 93 1e 00 15 0b 30 35 2e 30 36 2e 30 32 2e 30 34 a3 93 1f 00 15 0f 50 41 4f 4d 2e 52 35 30 36 5f 30 34 5f 30 34 a3 9e 3c 10 02 10 72 01 a7 89 20 bb 75 40 8a ea 1b ee 39 6c e7 9b a1 00 00 00 03 93 58 30 00 a3 81 69 00 15 0a 50 4c 43 50 72 6f 67 72 61 6d a3 93 15 00 05 8c aa bc ca ff ac 91 d8 64 a3 93 16 00 04 00 a3 9c 33 00 01 01 a3 9d 22 00 05 00 a3 a1 2f 00 03 04 09 a3 a3 3f 10 03 02 ea 60 ee 47 a3 a4 14 00 01 00 a3 93 2f 00 04 32 a3 bb 26 00 0c 00 00 00 00 a3 bc 31 00 0c 00 00 00 00 a3 bc 32 00 10 00 00 00 00 00 00 00 00 a1 00 00 00 38 be 68 30 00 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 c0 39 20 03 01 04 09 a3 bf 78 10 02 08 09 61 c6 dc db b8 ca bf a3 bf 7a 10 02 08 9c 9f d3 c5 3d f0 37 82 a3 bf 7c 00 05 32 a3 bf 79 00 01 00 a3 bf 7b 00 05 32 a3 bf 7d 00 01 00 a2 a2 a2 00 00 00 00 72 03 00 00
DEBUG:s7.connection:  Frame header: version=V3, data_length=415, header_size=4
DEBUG:s7.connection:  V3 HMAC (32 bytes): 49e367b4a3b56c359a37cbee9e0c10b0c54b1467ba6d66d1806a797e4cac2373
DEBUG:s7.connection:  Response data (382 bytes): 32 00 00 04 bb 00 00 00 03 34 00 00 00 00 03 0d a1 00 00 00 01 93 2e 30 00 a3 81 69 00 15 06 41 53 52 6f 6f 74 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 93 1b 10 02 08 13 00 00 00 0e 00 00 00 a3 a3 52 00 14 00 00 a3 be 56 10 02 04 00 00 00 00 a3 93 2f 00 04 00 a3 93 1c 00 15 0b 41 4f 4d 2e 52 35 30 36 5f 30 32 a3 93 1d 00 15 08 30 35 2e 30 36 2e 30 31 a3 93 1e 00 15 0b 30 35 2e 30 36 2e 30 32 2e 30 34 a3 93 1f 00 15 0f 50 41 4f 4d 2e 52 35 30 36 5f 30 34 5f 30 34 a3 9e 3c 10 02 10 72 01 a7 89 20 bb 75 40 8a ea 1b ee 39 6c e7 9b a1 00 00 00 03 93 58 30 00 a3 81 69 00 15 0a 50 4c 43 50 72 6f 67 72 61 6d a3 93 15 00 05 8c aa bc ca ff ac 91 d8 64 a3 93 16 00 04 00 a3 9c 33 00 01 01 a3 9d 22 00 05 00 a3 a1 2f 00 03 04 09 a3 a3 3f 10 03 02 ea 60 ee 47 a3 a4 14 00 01 00 a3 93 2f 00 04 32 a3 bb 26 00 0c 00 00 00 00 a3 bc 31 00 0c 00 00 00 00 a3 bc 32 00 10 00 00 00 00 00 00 00 00 a1 00 00 00 38 be 68 30 00 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 c0 39 20 03 01 04 09 a3 bf 78 10 02 08 09 61 c6 dc db b8 ca bf a3 bf 7a 10 02 08 9c 9f d3 c5 3d f0 37 82 a3 bf 7c 00 05 32 a3 bf 79 00 01 00 a3 bf 7b 00 05 32 a3 bf 7d 00 01 00 a2 a2 a2 00 00 00 00
DEBUG:s7.connection:  Response header: opcode=0x32 function=0x04BB seq=3 session=0x34000000 transport=0x00
DEBUG:s7.connection:  Response payload (368 bytes): 03 0d a1 00 00 00 01 93 2e 30 00 a3 81 69 00 15 06 41 53 52 6f 6f 74 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 93 1b 10 02 08 13 00 00 00 0e 00 00 00 a3 a3 52 00 14 00 00 a3 be 56 10 02 04 00 00 00 00 a3 93 2f 00 04 00 a3 93 1c 00 15 0b 41 4f 4d 2e 52 35 30 36 5f 30 32 a3 93 1d 00 15 08 30 35 2e 30 36 2e 30 31 a3 93 1e 00 15 0b 30 35 2e 30 36 2e 30 32 2e 30 34 a3 93 1f 00 15 0f 50 41 4f 4d 2e 52 35 30 36 5f 30 34 5f 30 34 a3 9e 3c 10 02 10 72 01 a7 89 20 bb 75 40 8a ea 1b ee 39 6c e7 9b a1 00 00 00 03 93 58 30 00 a3 81 69 00 15 0a 50 4c 43 50 72 6f 67 72 61 6d a3 93 15 00 05 8c aa bc ca ff ac 91 d8 64 a3 93 16 00 04 00 a3 9c 33 00 01 01 a3 9d 22 00 05 00 a3 a1 2f 00 03 04 09 a3 a3 3f 10 03 02 ea 60 ee 47 a3 a4 14 00 01 00 a3 93 2f 00 04 32 a3 bb 26 00 0c 00 00 00 00 a3 bc 31 00 0c 00 00 00 00 a3 bc 32 00 10 00 00 00 00 00 00 00 00 a1 00 00 00 38 be 68 30 00 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 c0 39 20 03 01 04 09 a3 bf 78 10 02 08 09 61 c6 dc db b8 ca bf a3 bf 7a 10 02 08 9c 9f d3 c5 3d f0 37 82 a3 bf 7c 00 05 32 a3 bf 79 00 01 00 a3 bf 7b 00 05 32 a3 bf 7d 00 01 00 a2 a2 a2 00 00 00 00
DEBUG:s7.connection:  Trailer (4 bytes): 72 03 00 00
explore:  b'\x03\r\xa1\x00\x00\x00\x01\x93.0\x00\xa3\x81i\x00\x15\x06ASRoot\xa3\x93\x15\x00\x05\x00\xa3\x93\x16\x00\x04\x00\xa3\x93\x1b\x10\x02\x08\x13\x00\x00\x00\x0e\x00\x00\x00\xa3\xa3R\x00\x14\x00\x00\xa3\xbeV\x10\x02\x04\x00\x00\x00\x00\xa3\x93/\x00\x04\x00\xa3\x93\x1c\x00\x15\x0bAOM.R506_02\xa3\x93\x1d\x00\x15\x0805.06.01\xa3\x93\x1e\x00\x15\x0b05.06.02.04\xa3\x93\x1f\x00\x15\x0fPAOM.R506_04_04\xa3\x9e<\x10\x02\x10r\x01\xa7\x89 \xbbu@\x8a\xea\x1b\xee9l\xe7\x9b\xa1\x00\x00\x00\x03\x93X0\x00\xa3\x81i\x00\x15\nPLCProgram\xa3\x93\x15\x00\x05\x8c\xaa\xbc\xca\xff\xac\x91\xd8d\xa3\x93\x16\x00\x04\x00\xa3\x9c3\x00\x01\x01\xa3\x9d"\x00\x05\x00\xa3\xa1/\x00\x03\x04\t\xa3\xa3?\x10\x03\x02\xea`\xeeG\xa3\xa4\x14\x00\x01\x00\xa3\x93/\x00\x042\xa3\xbb&\x00\x0c\x00\x00\x00\x00\xa3\xbc1\x00\x0c\x00\x00\x00\x00\xa3\xbc2\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\xa1\x00\x00\x008\xbeh0\x00\xa3\x93\x15\x00\x05\x00\xa3\x93\x16\x00\x04\x00\xa3\xc09 \x03\x01\x04\t\xa3\xbfx\x10\x02\x08\ta\xc6\xdc\xdb\xb8\xca\xbf\xa3\xbfz\x10\x02\x08\x9c\x9f\xd3\xc5=\xf07\x82\xa3\xbf|\x00\x052\xa3\xbfy\x00\x01\x00\xa3\xbf{\x00\x052\xa3\xbf}\x00\x01\x00\xa2\xa2\xa2\x00\x00\x00\x00'
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x04BB seq=4 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 04 bb 00 00 00 04 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (13 bytes): 03 00 01 00 02 81 69 93 59 00 00 00 00
DEBUG:s7.connection:  Full frame (68 bytes): 72 03 00 3c 20 5c f3 32 f6 bf 7f 9a 02 e2 c9 93 b1 e5 d9 9f f2 c1 f6 3f e5 1e 2e 8b c4 c1 8d 26 d9 f6 25 75 97 31 00 00 04 bb 00 00 00 04 00 00 03 9b 36 03 00 01 00 02 81 69 93 59 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 75 bytes: 03 00 00 4b 02 f0 80 72 03 00 3c 20 5c f3 32 f6 bf 7f 9a 02 e2 c9 93 b1 e5 d9 9f f2 c1 f6 3f e5 1e 2e 8b c4 c1 8d 26 d9 f6 25 75 97 31 00 00 04 bb 00 00 00 04 00 00 03 9b 36 03 00 01 00 02 81 69 93 59 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=209 payload (205 bytes): 02 f0 80 72 fe 00 c6 00 00 00 00 00 00 02 c3 00 00 00 00 00 00 00 00 00 00 00 17 00 00 9d 6c 00 00 9d 6d 00 00 00 08 00 00 00 02 00 00 9d 6e 00 00 00 04 00 00 03 9b 00 00 9d 6f 00 00 00 04 00 00 04 bb 00 00 9d 70 00 00 00 03 00 04 00 00 9d 71 00 00 00 09 a2 01 3b 00 01 39 ff 88 00 00 9d 72 00 00 00 04 00 00 00 00 00 00 9d 73 00 00 00 04 00 00 04 bb 00 00 9d 74 00 00 00 04 00 00 00 e9 00 00 9d 75 00 00 00 04 00 00 00 00 00 00 9d 76 00 00 00 03 00 06 00 00 9d 77 00 00 00 03 00 00 00 00 9d 78 00 00 00 03 10 00 00 00 9d 79 00 00 00 03 10 11 00 00 9d 7a 00 00 00 03 08 01 00 00 9d 7b 00 00 00 03 10 29 00 00 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (202 bytes): 72 fe 00 c6 00 00 00 00 00 00 02 c3 00 00 00 00 00 00 00 00 00 00 00 17 00 00 9d 6c 00 00 9d 6d 00 00 00 08 00 00 00 02 00 00 9d 6e 00 00 00 04 00 00 03 9b 00 00 9d 6f 00 00 00 04 00 00 04 bb 00 00 9d 70 00 00 00 03 00 04 00 00 9d 71 00 00 00 09 a2 01 3b 00 01 39 ff 88 00 00 9d 72 00 00 00 04 00 00 00 00 00 00 9d 73 00 00 00 04 00 00 04 bb 00 00 9d 74 00 00 00 04 00 00 00 e9 00 00 9d 75 00 00 00 04 00 00 00 00 00 00 9d 76 00 00 00 03 00 06 00 00 9d 77 00 00 00 03 00 00 00 00 9d 78 00 00 00 03 10 00 00 00 9d 79 00 00 00 03 10 11 00 00 9d 7a 00 00 00 03 08 01 00 00 9d 7b 00 00 00 03 10 29 00 00 00 00
DEBUG:s7.connection:  Frame header: version=V254, data_length=198, header_size=4
DEBUG:s7.connection:  V254 frame: returning raw data (198 bytes)
browse:  []
DEBUG:snap7.connection:Sent 33 bytes: 03 00 00 21 02 f0 80 72 01 00 12 31 00 00 04 d4 00 00 00 05 00 00 03 9b 36 00 00 00 00 72 01 00 00
INFO:snap7.connection:Disconnected from 192.168.0.1:102
DEBUG:snap7.client:Heartbeat stopped
INFO:snap7.connection:Disconnected from 192.168.0.1:102
INFO:snap7.client:Disconnected from 192.168.0.1:102
DEBUG:snap7.client:Heartbeat stopped
INFO:snap7.client:Disconnected from 192.168.0.1:102

ef9aee0.zip

The first explore() call worked with V3 format, but list_datablocks()
and browse() still used the old VLQ-based _build_explore_request.
Route all EXPLORE calls through _build_explore_payload_v3 when a
session key is present.
@gijzelaerr
Copy link
Copy Markdown
Owner Author

@xBiggs Great news — the first EXPLORE returned real data (ASRoot, PLCProgram with proper PObject tags)! The second call (from list_datablocks) was still using the old payload format. Fixed in 2b78b3c — all EXPLORE calls now use V3 format.

pip install --force-reinstall git+https://github.com/gijzelaerr/python-snap7.git@research/harpo-port-incomplete

@xBiggs
Copy link
Copy Markdown

xBiggs commented May 13, 2026

DEBUG:snap7.connection:TCP connected to 192.168.0.1:102
DEBUG:snap7.connection:Sent COTP Connection Request
DEBUG:snap7.connection:Negotiated PDU size: 1024
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc1, length=2
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc2, length=16
DEBUG:snap7.connection:Received COTP Connection Confirm
INFO:snap7.connection:Connected to 192.168.0.1:102, PDU size: 1024
DEBUG:s7.connection:=== InitSSL === sending (26 bytes): 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 33 bytes: 03 00 00 21 02 f0 80 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=38 payload (34 bytes): 02 f0 80 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== InitSSL === received (31 bytes): 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:InitSSL response: version=V1, data_length=23
DEBUG:s7.connection:InitSSL response body (27 bytes): 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === sending (192 bytes): 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 199 bytes: 03 00 00 c7 02 f0 80 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=215 payload (211 bytes): 02 f0 80 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 7e 69 4b 14 13 52 36 4b 72 63 c9 01 8a 2e f7 ff 62 c4 3c c5 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === received (208 bytes): 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 7e 69 4b 14 13 52 36 4b 72 63 c9 01 8a 2e f7 ff 62 c4 3c c5 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response: version=V1, data_length=200
DEBUG:s7.connection:CreateObject response body (204 bytes): 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 7e 69 4b 14 13 52 36 4b 72 63 c9 01 8a 2e f7 ff 62 c4 3c c5 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response header: opcode=0x32 function=0x04CA seq=1 transport=0x36
DEBUG:s7.connection:CreateObject response: return_value=0 object_ids=['0x39b', '0x3c2']
DEBUG:s7.connection:Session created: id=0x0000039B (923), version=V1
INFO:s7.connection:Public key fingerprint captured: 01:BD426B091F08731A
INFO:s7.connection:Session challenge captured (20 bytes): 7e694b141352364b7263c9018a2ef7ff62c43cc5
INFO:s7.connection:ServerSessionVersion struct captured (84 bytes)
INFO:s7.connection:SessionKey auth blob generated (180 bytes)
INFO:s7.connection:SecurityKey blob included in session setup
DEBUG:s7.connection:=== SetupSession === sending (390 bytes): 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 14 d3 46 bb 29 a4 ae e5 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 a2 e8 75 23 89 32 b3 c8 6b fa 01 77 a3 14 d6 57 3e 34 17 36 af 2c 3f d3 af 86 5e 06 5c 11 31 55 f7 15 d7 c1 2b 1b dc 60 8f 84 1f 6e 1c 45 2b 11 46 18 3c 7a 75 56 aa 0d f2 47 b9 cc 10 70 42 9e 5d 5a b7 2c 00 83 67 78 90 f3 16 88 48 79 99 0d 21 56 46 85 14 11 30 22 03 6c 52 90 34 6f 8c fe 33 f3 3b a4 20 32 5f 4b 05 43 23 af 7c e2 c3 4b 50 63 60 d3 91 24 09 7e 1d aa fe 85 29 5d c5 77 e9 56 3d 09 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Sent 397 bytes: 03 00 01 8d 02 f0 80 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 14 d3 46 bb 29 a4 ae e5 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 a2 e8 75 23 89 32 b3 c8 6b fa 01 77 a3 14 d6 57 3e 34 17 36 af 2c 3f d3 af 86 5e 06 5c 11 31 55 f7 15 d7 c1 2b 1b dc 60 8f 84 1f 6e 1c 45 2b 11 46 18 3c 7a 75 56 aa 0d f2 47 b9 cc 10 70 42 9e 5d 5a b7 2c 00 83 67 78 90 f3 16 88 48 79 99 0d 21 56 46 85 14 11 30 22 03 6c 52 90 34 6f 8c fe 33 f3 3b a4 20 32 5f 4b 05 43 23 af 7c e2 c3 4b 50 63 60 d3 91 24 09 7e 1d aa fe 85 29 5d c5 77 e9 56 3d 09 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=32 payload (28 bytes): 02 f0 80 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:=== SetupSession === received (25 bytes): 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:SetupSession response: function=0x0542
INFO:s7.connection:Session setup completed successfully
INFO:s7.connection:S7CommPlus connected to 192.168.0.1:102, version=V1, session=923, tls=False
INFO:s7.client:Connected to 192.168.0.1:102 using S7CommPlus
INFO:snap7.client:S7Client initialized (pure Python implementation)
DEBUG:snap7.connection:TCP connected to 192.168.0.1:102
DEBUG:snap7.connection:Sent COTP Connection Request
DEBUG:snap7.connection:Negotiated PDU size: 1024
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc1, length=2
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc2, length=2
DEBUG:snap7.connection:Received COTP Connection Confirm
INFO:snap7.connection:Connected to 192.168.0.1:102, PDU size: 1024
DEBUG:snap7.connection:Sent 25 bytes: 03 00 00 19 02 f0 80 32 01 00 00 00 01 00 08 00 00 f0 00 00 01 00 01 01 e0
DEBUG:snap7.connection:Received TPKT: version=3 length=27 payload (23 bytes): 02 f0 80 32 03 00 00 00 01 00 08 00 00 00 00 f0 00 00 01 00 01 00 f0
INFO:snap7.client:Negotiated PDU length: 240
INFO:snap7.client:[192.168.0.1 R0/S1] Connected to 192.168.0.1:102 rack 0 slot 1
INFO:snap7.client:Auto-tuned max_parallel=2 (PDU=240)
INFO:s7.client:Legacy S7 connected to 192.168.0.1:102
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x04BB seq=3 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 04 bb 00 00 00 03 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (16 bytes): 00 00 00 38 00 01 00 01 00 00 0a 00 00 00 00 00
DEBUG:s7.connection:  Full frame (71 bytes): 72 03 00 3f 20 37 09 80 43 76 91 0e c5 76 09 6e c7 d6 ac 45 4b 35 4f f9 8e ac 6e fa 3f dd ae 46 a1 92 52 d3 9d 31 00 00 04 bb 00 00 00 03 00 00 03 9b 36 00 00 00 38 00 01 00 01 00 00 0a 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 78 bytes: 03 00 00 4e 02 f0 80 72 03 00 3f 20 37 09 80 43 76 91 0e c5 76 09 6e c7 d6 ac 45 4b 35 4f f9 8e ac 6e fa 3f dd ae 46 a1 92 52 d3 9d 31 00 00 04 bb 00 00 00 03 00 00 03 9b 36 00 00 00 38 00 01 00 01 00 00 0a 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=430 payload (426 bytes): 02 f0 80 72 03 01 9f 20 a5 a5 8f f8 3d 48 aa ff db a9 df 42 a1 95 26 2e 2b 6b 75 94 1e 02 db 05 8c 80 59 4f 1f e1 af b6 32 00 00 04 bb 00 00 00 03 34 00 00 00 00 03 0d a1 00 00 00 01 93 2e 30 00 a3 81 69 00 15 06 41 53 52 6f 6f 74 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 93 1b 10 02 08 13 00 00 00 0e 00 00 00 a3 a3 52 00 14 00 00 a3 be 56 10 02 04 00 00 00 00 a3 93 2f 00 04 00 a3 93 1c 00 15 0b 41 4f 4d 2e 52 35 30 36 5f 30 32 a3 93 1d 00 15 08 30 35 2e 30 36 2e 30 31 a3 93 1e 00 15 0b 30 35 2e 30 36 2e 30 32 2e 30 34 a3 93 1f 00 15 0f 50 41 4f 4d 2e 52 35 30 36 5f 30 34 5f 30 34 a3 9e 3c 10 02 10 72 01 a7 89 20 bb 75 40 8a ea 1b ee 39 6c e7 9b a1 00 00 00 03 93 58 30 00 a3 81 69 00 15 0a 50 4c 43 50 72 6f 67 72 61 6d a3 93 15 00 05 8c aa bc ca ff ac 91 d8 64 a3 93 16 00 04 00 a3 9c 33 00 01 01 a3 9d 22 00 05 00 a3 a1 2f 00 03 04 09 a3 a3 3f 10 03 02 ea 60 ee 47 a3 a4 14 00 01 00 a3 93 2f 00 04 32 a3 bb 26 00 0c 00 00 00 00 a3 bc 31 00 0c 00 00 00 00 a3 bc 32 00 10 00 00 00 00 00 00 00 00 a1 00 00 00 38 be 68 30 00 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 c0 39 20 03 01 04 09 a3 bf 78 10 02 08 09 61 c6 dc db b8 ca bf a3 bf 7a 10 02 08 9c 9f d3 c5 3d f0 37 82 a3 bf 7c 00 05 32 a3 bf 79 00 01 00 a3 bf 7b 00 05 32 a3 bf 7d 00 01 00 a2 a2 a2 00 00 00 00 72 03 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (423 bytes): 72 03 01 9f 20 a5 a5 8f f8 3d 48 aa ff db a9 df 42 a1 95 26 2e 2b 6b 75 94 1e 02 db 05 8c 80 59 4f 1f e1 af b6 32 00 00 04 bb 00 00 00 03 34 00 00 00 00 03 0d a1 00 00 00 01 93 2e 30 00 a3 81 69 00 15 06 41 53 52 6f 6f 74 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 93 1b 10 02 08 13 00 00 00 0e 00 00 00 a3 a3 52 00 14 00 00 a3 be 56 10 02 04 00 00 00 00 a3 93 2f 00 04 00 a3 93 1c 00 15 0b 41 4f 4d 2e 52 35 30 36 5f 30 32 a3 93 1d 00 15 08 30 35 2e 30 36 2e 30 31 a3 93 1e 00 15 0b 30 35 2e 30 36 2e 30 32 2e 30 34 a3 93 1f 00 15 0f 50 41 4f 4d 2e 52 35 30 36 5f 30 34 5f 30 34 a3 9e 3c 10 02 10 72 01 a7 89 20 bb 75 40 8a ea 1b ee 39 6c e7 9b a1 00 00 00 03 93 58 30 00 a3 81 69 00 15 0a 50 4c 43 50 72 6f 67 72 61 6d a3 93 15 00 05 8c aa bc ca ff ac 91 d8 64 a3 93 16 00 04 00 a3 9c 33 00 01 01 a3 9d 22 00 05 00 a3 a1 2f 00 03 04 09 a3 a3 3f 10 03 02 ea 60 ee 47 a3 a4 14 00 01 00 a3 93 2f 00 04 32 a3 bb 26 00 0c 00 00 00 00 a3 bc 31 00 0c 00 00 00 00 a3 bc 32 00 10 00 00 00 00 00 00 00 00 a1 00 00 00 38 be 68 30 00 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 c0 39 20 03 01 04 09 a3 bf 78 10 02 08 09 61 c6 dc db b8 ca bf a3 bf 7a 10 02 08 9c 9f d3 c5 3d f0 37 82 a3 bf 7c 00 05 32 a3 bf 79 00 01 00 a3 bf 7b 00 05 32 a3 bf 7d 00 01 00 a2 a2 a2 00 00 00 00 72 03 00 00
DEBUG:s7.connection:  Frame header: version=V3, data_length=415, header_size=4
DEBUG:s7.connection:  V3 HMAC (32 bytes): a5a58ff83d48aaffdba9df42a195262e2b6b75941e02db058c80594f1fe1afb6
DEBUG:s7.connection:  Response data (382 bytes): 32 00 00 04 bb 00 00 00 03 34 00 00 00 00 03 0d a1 00 00 00 01 93 2e 30 00 a3 81 69 00 15 06 41 53 52 6f 6f 74 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 93 1b 10 02 08 13 00 00 00 0e 00 00 00 a3 a3 52 00 14 00 00 a3 be 56 10 02 04 00 00 00 00 a3 93 2f 00 04 00 a3 93 1c 00 15 0b 41 4f 4d 2e 52 35 30 36 5f 30 32 a3 93 1d 00 15 08 30 35 2e 30 36 2e 30 31 a3 93 1e 00 15 0b 30 35 2e 30 36 2e 30 32 2e 30 34 a3 93 1f 00 15 0f 50 41 4f 4d 2e 52 35 30 36 5f 30 34 5f 30 34 a3 9e 3c 10 02 10 72 01 a7 89 20 bb 75 40 8a ea 1b ee 39 6c e7 9b a1 00 00 00 03 93 58 30 00 a3 81 69 00 15 0a 50 4c 43 50 72 6f 67 72 61 6d a3 93 15 00 05 8c aa bc ca ff ac 91 d8 64 a3 93 16 00 04 00 a3 9c 33 00 01 01 a3 9d 22 00 05 00 a3 a1 2f 00 03 04 09 a3 a3 3f 10 03 02 ea 60 ee 47 a3 a4 14 00 01 00 a3 93 2f 00 04 32 a3 bb 26 00 0c 00 00 00 00 a3 bc 31 00 0c 00 00 00 00 a3 bc 32 00 10 00 00 00 00 00 00 00 00 a1 00 00 00 38 be 68 30 00 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 c0 39 20 03 01 04 09 a3 bf 78 10 02 08 09 61 c6 dc db b8 ca bf a3 bf 7a 10 02 08 9c 9f d3 c5 3d f0 37 82 a3 bf 7c 00 05 32 a3 bf 79 00 01 00 a3 bf 7b 00 05 32 a3 bf 7d 00 01 00 a2 a2 a2 00 00 00 00
DEBUG:s7.connection:  Response header: opcode=0x32 function=0x04BB seq=3 session=0x34000000 transport=0x00
DEBUG:s7.connection:  Response payload (368 bytes): 03 0d a1 00 00 00 01 93 2e 30 00 a3 81 69 00 15 06 41 53 52 6f 6f 74 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 93 1b 10 02 08 13 00 00 00 0e 00 00 00 a3 a3 52 00 14 00 00 a3 be 56 10 02 04 00 00 00 00 a3 93 2f 00 04 00 a3 93 1c 00 15 0b 41 4f 4d 2e 52 35 30 36 5f 30 32 a3 93 1d 00 15 08 30 35 2e 30 36 2e 30 31 a3 93 1e 00 15 0b 30 35 2e 30 36 2e 30 32 2e 30 34 a3 93 1f 00 15 0f 50 41 4f 4d 2e 52 35 30 36 5f 30 34 5f 30 34 a3 9e 3c 10 02 10 72 01 a7 89 20 bb 75 40 8a ea 1b ee 39 6c e7 9b a1 00 00 00 03 93 58 30 00 a3 81 69 00 15 0a 50 4c 43 50 72 6f 67 72 61 6d a3 93 15 00 05 8c aa bc ca ff ac 91 d8 64 a3 93 16 00 04 00 a3 9c 33 00 01 01 a3 9d 22 00 05 00 a3 a1 2f 00 03 04 09 a3 a3 3f 10 03 02 ea 60 ee 47 a3 a4 14 00 01 00 a3 93 2f 00 04 32 a3 bb 26 00 0c 00 00 00 00 a3 bc 31 00 0c 00 00 00 00 a3 bc 32 00 10 00 00 00 00 00 00 00 00 a1 00 00 00 38 be 68 30 00 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 c0 39 20 03 01 04 09 a3 bf 78 10 02 08 09 61 c6 dc db b8 ca bf a3 bf 7a 10 02 08 9c 9f d3 c5 3d f0 37 82 a3 bf 7c 00 05 32 a3 bf 79 00 01 00 a3 bf 7b 00 05 32 a3 bf 7d 00 01 00 a2 a2 a2 00 00 00 00
DEBUG:s7.connection:  Trailer (4 bytes): 72 03 00 00
explore:  b'\x03\r\xa1\x00\x00\x00\x01\x93.0\x00\xa3\x81i\x00\x15\x06ASRoot\xa3\x93\x15\x00\x05\x00\xa3\x93\x16\x00\x04\x00\xa3\x93\x1b\x10\x02\x08\x13\x00\x00\x00\x0e\x00\x00\x00\xa3\xa3R\x00\x14\x00\x00\xa3\xbeV\x10\x02\x04\x00\x00\x00\x00\xa3\x93/\x00\x04\x00\xa3\x93\x1c\x00\x15\x0bAOM.R506_02\xa3\x93\x1d\x00\x15\x0805.06.01\xa3\x93\x1e\x00\x15\x0b05.06.02.04\xa3\x93\x1f\x00\x15\x0fPAOM.R506_04_04\xa3\x9e<\x10\x02\x10r\x01\xa7\x89 \xbbu@\x8a\xea\x1b\xee9l\xe7\x9b\xa1\x00\x00\x00\x03\x93X0\x00\xa3\x81i\x00\x15\nPLCProgram\xa3\x93\x15\x00\x05\x8c\xaa\xbc\xca\xff\xac\x91\xd8d\xa3\x93\x16\x00\x04\x00\xa3\x9c3\x00\x01\x01\xa3\x9d"\x00\x05\x00\xa3\xa1/\x00\x03\x04\t\xa3\xa3?\x10\x03\x02\xea`\xeeG\xa3\xa4\x14\x00\x01\x00\xa3\x93/\x00\x042\xa3\xbb&\x00\x0c\x00\x00\x00\x00\xa3\xbc1\x00\x0c\x00\x00\x00\x00\xa3\xbc2\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\xa1\x00\x00\x008\xbeh0\x00\xa3\x93\x15\x00\x05\x00\xa3\x93\x16\x00\x04\x00\xa3\xc09 \x03\x01\x04\t\xa3\xbfx\x10\x02\x08\ta\xc6\xdc\xdb\xb8\xca\xbf\xa3\xbfz\x10\x02\x08\x9c\x9f\xd3\xc5=\xf07\x82\xa3\xbf|\x00\x052\xa3\xbfy\x00\x01\x00\xa3\xbf{\x00\x052\xa3\xbf}\x00\x01\x00\xa2\xa2\xa2\x00\x00\x00\x00'
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x04BB seq=4 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 04 bb 00 00 00 04 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (16 bytes): 00 00 00 03 00 01 00 01 00 00 0a 00 00 00 00 00
DEBUG:s7.connection:  Full frame (71 bytes): 72 03 00 3f 20 68 05 65 de 50 0a d0 78 a7 d5 66 b5 2d 39 b0 41 19 99 f8 7e a0 5e 90 a0 23 c2 5d 48 04 38 55 1b 31 00 00 04 bb 00 00 00 04 00 00 03 9b 36 00 00 00 03 00 01 00 01 00 00 0a 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 78 bytes: 03 00 00 4e 02 f0 80 72 03 00 3f 20 68 05 65 de 50 0a d0 78 a7 d5 66 b5 2d 39 b0 41 19 99 f8 7e a0 5e 90 a0 23 c2 5d 48 04 38 55 1b 31 00 00 04 bb 00 00 00 04 00 00 03 9b 36 00 00 00 03 00 01 00 01 00 00 0a 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=209 payload (205 bytes): 02 f0 80 72 fe 00 c6 00 00 00 00 00 00 02 c6 00 00 00 00 00 00 00 00 00 00 00 17 00 00 9d 6c 00 00 9d 6d 00 00 00 08 00 00 00 02 00 00 9d 6e 00 00 00 04 00 00 03 9b 00 00 9d 6f 00 00 00 04 00 00 04 bb 00 00 9d 70 00 00 00 03 00 04 00 00 9d 71 00 00 00 09 a2 01 3b 00 02 36 ff 88 00 00 9d 72 00 00 00 04 00 00 00 00 00 00 9d 73 00 00 00 04 00 00 04 bb 00 00 9d 74 00 00 00 04 00 00 00 e9 00 00 9d 75 00 00 00 04 00 00 00 00 00 00 9d 76 00 00 00 03 00 06 00 00 9d 77 00 00 00 03 00 00 00 00 9d 78 00 00 00 03 10 00 00 00 9d 79 00 00 00 03 10 11 00 00 9d 7a 00 00 00 03 08 01 00 00 9d 7b 00 00 00 03 10 29 00 00 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (202 bytes): 72 fe 00 c6 00 00 00 00 00 00 02 c6 00 00 00 00 00 00 00 00 00 00 00 17 00 00 9d 6c 00 00 9d 6d 00 00 00 08 00 00 00 02 00 00 9d 6e 00 00 00 04 00 00 03 9b 00 00 9d 6f 00 00 00 04 00 00 04 bb 00 00 9d 70 00 00 00 03 00 04 00 00 9d 71 00 00 00 09 a2 01 3b 00 02 36 ff 88 00 00 9d 72 00 00 00 04 00 00 00 00 00 00 9d 73 00 00 00 04 00 00 04 bb 00 00 9d 74 00 00 00 04 00 00 00 e9 00 00 9d 75 00 00 00 04 00 00 00 00 00 00 9d 76 00 00 00 03 00 06 00 00 9d 77 00 00 00 03 00 00 00 00 9d 78 00 00 00 03 10 00 00 00 9d 79 00 00 00 03 10 11 00 00 9d 7a 00 00 00 03 08 01 00 00 9d 7b 00 00 00 03 10 29 00 00 00 00
DEBUG:s7.connection:  Frame header: version=V254, data_length=198, header_size=4
DEBUG:s7.connection:  V254 frame: returning raw data (198 bytes)
browse:  []
INFO:snap7.connection:Disconnected from 192.168.0.1:102
DEBUG:snap7.client:Heartbeat stopped
INFO:snap7.connection:Disconnected from 192.168.0.1:102
INFO:snap7.client:Disconnected from 192.168.0.1:102
DEBUG:snap7.client:Heartbeat stopped
INFO:snap7.client:Disconnected from 192.168.0.1:102

2b78b3c.zip

@gijzelaerr
Copy link
Copy Markdown
Owner Author

Good progress. The EXPLORE to 0x38 works and returns the program tree (ASRootPLCProgram). The second EXPLORE to object 3 gets V254 — the PLC only accepts EXPLORE for certain object IDs.

The program tree doesn't contain individual DBs — those need a deeper explore. TIA Portal uses 0x8A11FFFF as the explore target for DB discovery, which is DB_ACCESS_AREA_BASE + 0x3FFFF (a wildcard). The browse flow needs to be reworked for V1-initial PLCs to use this two-level explore pattern.

The auth handshake and V3 HMAC framing are fully working now — this is purely a browse-level issue. I'll track the remaining browse work separately.

V1-initial PLCs reject EXPLORE to object 3 (PLC_PROGRAM_RID) with
V254. TIA Portal explores 0x8A11FFFF (DB_ACCESS_AREA_BASE + 0x3FFFF)
instead, which returns the full program tree with DB children.
@gijzelaerr
Copy link
Copy Markdown
Owner Author

@xBiggs f67f39d changes list_datablocks() to explore 0x8A11FFFF (the DB wildcard address TIA Portal uses) instead of object 3 (which the PLC rejects).

pip install --force-reinstall git+https://github.com/gijzelaerr/python-snap7.git@research/harpo-port-incomplete

Try browse() again — if the EXPLORE response contains DB objects, the parser should pick them up now.

@xBiggs
Copy link
Copy Markdown

xBiggs commented May 15, 2026

DEBUG:snap7.connection:TCP connected to 192.168.0.1:102
DEBUG:snap7.connection:Sent COTP Connection Request
DEBUG:snap7.connection:Negotiated PDU size: 1024
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc1, length=2
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc2, length=16
DEBUG:snap7.connection:Received COTP Connection Confirm
INFO:snap7.connection:Connected to 192.168.0.1:102, PDU size: 1024
DEBUG:s7.connection:=== InitSSL === sending (26 bytes): 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 33 bytes: 03 00 00 21 02 f0 80 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=38 payload (34 bytes): 02 f0 80 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== InitSSL === received (31 bytes): 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:InitSSL response: version=V1, data_length=23
DEBUG:s7.connection:InitSSL response body (27 bytes): 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === sending (192 bytes): 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 199 bytes: 03 00 00 c7 02 f0 80 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=215 payload (211 bytes): 02 f0 80 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 ef f2 9b 59 0a 16 cd a7 8b 26 dd cc 8a cc 79 e4 13 23 7e 83 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === received (208 bytes): 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 ef f2 9b 59 0a 16 cd a7 8b 26 dd cc 8a cc 79 e4 13 23 7e 83 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response: version=V1, data_length=200
DEBUG:s7.connection:CreateObject response body (204 bytes): 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 ef f2 9b 59 0a 16 cd a7 8b 26 dd cc 8a cc 79 e4 13 23 7e 83 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response header: opcode=0x32 function=0x04CA seq=1 transport=0x36
DEBUG:s7.connection:CreateObject response: return_value=0 object_ids=['0x39b', '0x3c2']
DEBUG:s7.connection:Session created: id=0x0000039B (923), version=V1
INFO:s7.connection:Public key fingerprint captured: 01:BD426B091F08731A
INFO:s7.connection:Session challenge captured (20 bytes): eff29b590a16cda78b26ddcc8acc79e413237e83
INFO:s7.connection:ServerSessionVersion struct captured (84 bytes)
INFO:s7.connection:SessionKey auth blob generated (180 bytes)
INFO:s7.connection:SecurityKey blob included in session setup
DEBUG:s7.connection:=== SetupSession === sending (390 bytes): 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 39 36 7a 21 0e 06 50 f4 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 f0 ba 32 93 5d 7b 0a 3f 33 eb bf 23 c9 ce ed b5 81 ed 03 53 9a fc 36 f4 27 65 b4 e9 97 74 8d c0 67 8c 02 a5 6d d3 3b da d5 5f 8a 39 03 9c b4 05 a6 37 31 38 04 6f 83 f5 56 51 fd 5b b3 24 65 4f 84 80 32 bb b3 bc ee 75 d8 89 8d 41 a5 d5 c2 36 27 60 dd c3 b4 2b 74 8f 3f b9 05 de 5e 1c c5 f9 c9 7c eb 83 4f a9 22 66 33 a5 b4 4a a2 a4 51 90 b4 7f 0d 3b 4d 2d b6 52 6e d0 06 ee 1c 5d db 29 47 2a c1 72 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Sent 397 bytes: 03 00 01 8d 02 f0 80 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 39 36 7a 21 0e 06 50 f4 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 f0 ba 32 93 5d 7b 0a 3f 33 eb bf 23 c9 ce ed b5 81 ed 03 53 9a fc 36 f4 27 65 b4 e9 97 74 8d c0 67 8c 02 a5 6d d3 3b da d5 5f 8a 39 03 9c b4 05 a6 37 31 38 04 6f 83 f5 56 51 fd 5b b3 24 65 4f 84 80 32 bb b3 bc ee 75 d8 89 8d 41 a5 d5 c2 36 27 60 dd c3 b4 2b 74 8f 3f b9 05 de 5e 1c c5 f9 c9 7c eb 83 4f a9 22 66 33 a5 b4 4a a2 a4 51 90 b4 7f 0d 3b 4d 2d b6 52 6e d0 06 ee 1c 5d db 29 47 2a c1 72 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=32 payload (28 bytes): 02 f0 80 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:=== SetupSession === received (25 bytes): 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:SetupSession response: function=0x0542
INFO:s7.connection:Session setup completed successfully
INFO:s7.connection:S7CommPlus connected to 192.168.0.1:102, version=V1, session=923, tls=False
INFO:s7.client:Connected to 192.168.0.1:102 using S7CommPlus
INFO:snap7.client:S7Client initialized (pure Python implementation)
DEBUG:snap7.connection:TCP connected to 192.168.0.1:102
DEBUG:snap7.connection:Sent COTP Connection Request
DEBUG:snap7.connection:Negotiated PDU size: 1024
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc1, length=2
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc2, length=2
DEBUG:snap7.connection:Received COTP Connection Confirm
INFO:snap7.connection:Connected to 192.168.0.1:102, PDU size: 1024
DEBUG:snap7.connection:Sent 25 bytes: 03 00 00 19 02 f0 80 32 01 00 00 00 01 00 08 00 00 f0 00 00 01 00 01 01 e0
DEBUG:snap7.connection:Received TPKT: version=3 length=27 payload (23 bytes): 02 f0 80 32 03 00 00 00 01 00 08 00 00 00 00 f0 00 00 01 00 01 00 f0
INFO:snap7.client:Negotiated PDU length: 240
INFO:snap7.client:[192.168.0.1 R0/S1] Connected to 192.168.0.1:102 rack 0 slot 1
INFO:snap7.client:Auto-tuned max_parallel=2 (PDU=240)
INFO:s7.client:Legacy S7 connected to 192.168.0.1:102
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x04BB seq=3 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 04 bb 00 00 00 03 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (16 bytes): 00 00 00 38 00 01 00 01 00 00 0a 00 00 00 00 00
DEBUG:s7.connection:  Full frame (71 bytes): 72 03 00 3f 20 d4 d0 f8 30 d7 c0 b5 c3 66 72 bc 02 87 6d 05 22 88 d6 f1 b0 38 41 63 49 bf e6 a2 a5 e6 0b 31 02 31 00 00 04 bb 00 00 00 03 00 00 03 9b 36 00 00 00 38 00 01 00 01 00 00 0a 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 78 bytes: 03 00 00 4e 02 f0 80 72 03 00 3f 20 d4 d0 f8 30 d7 c0 b5 c3 66 72 bc 02 87 6d 05 22 88 d6 f1 b0 38 41 63 49 bf e6 a2 a5 e6 0b 31 02 31 00 00 04 bb 00 00 00 03 00 00 03 9b 36 00 00 00 38 00 01 00 01 00 00 0a 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=430 payload (426 bytes): 02 f0 80 72 03 01 9f 20 08 c9 41 1b 01 7b df cd 41 fd 1e b4 88 8f 14 b7 f9 c2 2b ae 85 1f af 5c f2 cf 76 4f 4d 3a 97 db 32 00 00 04 bb 00 00 00 03 34 00 00 00 00 03 0d a1 00 00 00 01 93 2e 30 00 a3 81 69 00 15 06 41 53 52 6f 6f 74 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 93 1b 10 02 08 13 00 00 00 0e 00 00 00 a3 a3 52 00 14 00 00 a3 be 56 10 02 04 00 00 00 00 a3 93 2f 00 04 00 a3 93 1c 00 15 0b 41 4f 4d 2e 52 35 30 36 5f 30 32 a3 93 1d 00 15 08 30 35 2e 30 36 2e 30 31 a3 93 1e 00 15 0b 30 35 2e 30 36 2e 30 32 2e 30 34 a3 93 1f 00 15 0f 50 41 4f 4d 2e 52 35 30 36 5f 30 34 5f 30 34 a3 9e 3c 10 02 10 72 01 a7 89 20 bb 75 40 8a ea 1b ee 39 6c e7 9b a1 00 00 00 03 93 58 30 00 a3 81 69 00 15 0a 50 4c 43 50 72 6f 67 72 61 6d a3 93 15 00 05 8c aa bc ca ff ac 91 d8 64 a3 93 16 00 04 00 a3 9c 33 00 01 01 a3 9d 22 00 05 00 a3 a1 2f 00 03 04 09 a3 a3 3f 10 03 02 ea 60 ee 47 a3 a4 14 00 01 00 a3 93 2f 00 04 32 a3 bb 26 00 0c 00 00 00 00 a3 bc 31 00 0c 00 00 00 00 a3 bc 32 00 10 00 00 00 00 00 00 00 00 a1 00 00 00 38 be 68 30 00 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 c0 39 20 03 01 04 09 a3 bf 78 10 02 08 09 61 c6 dc db b8 ca bf a3 bf 7a 10 02 08 9c 9f d3 c5 3d f0 37 82 a3 bf 7c 00 05 32 a3 bf 79 00 01 00 a3 bf 7b 00 05 32 a3 bf 7d 00 01 00 a2 a2 a2 00 00 00 00 72 03 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (423 bytes): 72 03 01 9f 20 08 c9 41 1b 01 7b df cd 41 fd 1e b4 88 8f 14 b7 f9 c2 2b ae 85 1f af 5c f2 cf 76 4f 4d 3a 97 db 32 00 00 04 bb 00 00 00 03 34 00 00 00 00 03 0d a1 00 00 00 01 93 2e 30 00 a3 81 69 00 15 06 41 53 52 6f 6f 74 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 93 1b 10 02 08 13 00 00 00 0e 00 00 00 a3 a3 52 00 14 00 00 a3 be 56 10 02 04 00 00 00 00 a3 93 2f 00 04 00 a3 93 1c 00 15 0b 41 4f 4d 2e 52 35 30 36 5f 30 32 a3 93 1d 00 15 08 30 35 2e 30 36 2e 30 31 a3 93 1e 00 15 0b 30 35 2e 30 36 2e 30 32 2e 30 34 a3 93 1f 00 15 0f 50 41 4f 4d 2e 52 35 30 36 5f 30 34 5f 30 34 a3 9e 3c 10 02 10 72 01 a7 89 20 bb 75 40 8a ea 1b ee 39 6c e7 9b a1 00 00 00 03 93 58 30 00 a3 81 69 00 15 0a 50 4c 43 50 72 6f 67 72 61 6d a3 93 15 00 05 8c aa bc ca ff ac 91 d8 64 a3 93 16 00 04 00 a3 9c 33 00 01 01 a3 9d 22 00 05 00 a3 a1 2f 00 03 04 09 a3 a3 3f 10 03 02 ea 60 ee 47 a3 a4 14 00 01 00 a3 93 2f 00 04 32 a3 bb 26 00 0c 00 00 00 00 a3 bc 31 00 0c 00 00 00 00 a3 bc 32 00 10 00 00 00 00 00 00 00 00 a1 00 00 00 38 be 68 30 00 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 c0 39 20 03 01 04 09 a3 bf 78 10 02 08 09 61 c6 dc db b8 ca bf a3 bf 7a 10 02 08 9c 9f d3 c5 3d f0 37 82 a3 bf 7c 00 05 32 a3 bf 79 00 01 00 a3 bf 7b 00 05 32 a3 bf 7d 00 01 00 a2 a2 a2 00 00 00 00 72 03 00 00
DEBUG:s7.connection:  Frame header: version=V3, data_length=415, header_size=4
DEBUG:s7.connection:  V3 HMAC (32 bytes): 08c9411b017bdfcd41fd1eb4888f14b7f9c22bae851faf5cf2cf764f4d3a97db
DEBUG:s7.connection:  Response data (382 bytes): 32 00 00 04 bb 00 00 00 03 34 00 00 00 00 03 0d a1 00 00 00 01 93 2e 30 00 a3 81 69 00 15 06 41 53 52 6f 6f 74 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 93 1b 10 02 08 13 00 00 00 0e 00 00 00 a3 a3 52 00 14 00 00 a3 be 56 10 02 04 00 00 00 00 a3 93 2f 00 04 00 a3 93 1c 00 15 0b 41 4f 4d 2e 52 35 30 36 5f 30 32 a3 93 1d 00 15 08 30 35 2e 30 36 2e 30 31 a3 93 1e 00 15 0b 30 35 2e 30 36 2e 30 32 2e 30 34 a3 93 1f 00 15 0f 50 41 4f 4d 2e 52 35 30 36 5f 30 34 5f 30 34 a3 9e 3c 10 02 10 72 01 a7 89 20 bb 75 40 8a ea 1b ee 39 6c e7 9b a1 00 00 00 03 93 58 30 00 a3 81 69 00 15 0a 50 4c 43 50 72 6f 67 72 61 6d a3 93 15 00 05 8c aa bc ca ff ac 91 d8 64 a3 93 16 00 04 00 a3 9c 33 00 01 01 a3 9d 22 00 05 00 a3 a1 2f 00 03 04 09 a3 a3 3f 10 03 02 ea 60 ee 47 a3 a4 14 00 01 00 a3 93 2f 00 04 32 a3 bb 26 00 0c 00 00 00 00 a3 bc 31 00 0c 00 00 00 00 a3 bc 32 00 10 00 00 00 00 00 00 00 00 a1 00 00 00 38 be 68 30 00 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 c0 39 20 03 01 04 09 a3 bf 78 10 02 08 09 61 c6 dc db b8 ca bf a3 bf 7a 10 02 08 9c 9f d3 c5 3d f0 37 82 a3 bf 7c 00 05 32 a3 bf 79 00 01 00 a3 bf 7b 00 05 32 a3 bf 7d 00 01 00 a2 a2 a2 00 00 00 00
DEBUG:s7.connection:  Response header: opcode=0x32 function=0x04BB seq=3 session=0x34000000 transport=0x00
DEBUG:s7.connection:  Response payload (368 bytes): 03 0d a1 00 00 00 01 93 2e 30 00 a3 81 69 00 15 06 41 53 52 6f 6f 74 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 93 1b 10 02 08 13 00 00 00 0e 00 00 00 a3 a3 52 00 14 00 00 a3 be 56 10 02 04 00 00 00 00 a3 93 2f 00 04 00 a3 93 1c 00 15 0b 41 4f 4d 2e 52 35 30 36 5f 30 32 a3 93 1d 00 15 08 30 35 2e 30 36 2e 30 31 a3 93 1e 00 15 0b 30 35 2e 30 36 2e 30 32 2e 30 34 a3 93 1f 00 15 0f 50 41 4f 4d 2e 52 35 30 36 5f 30 34 5f 30 34 a3 9e 3c 10 02 10 72 01 a7 89 20 bb 75 40 8a ea 1b ee 39 6c e7 9b a1 00 00 00 03 93 58 30 00 a3 81 69 00 15 0a 50 4c 43 50 72 6f 67 72 61 6d a3 93 15 00 05 8c aa bc ca ff ac 91 d8 64 a3 93 16 00 04 00 a3 9c 33 00 01 01 a3 9d 22 00 05 00 a3 a1 2f 00 03 04 09 a3 a3 3f 10 03 02 ea 60 ee 47 a3 a4 14 00 01 00 a3 93 2f 00 04 32 a3 bb 26 00 0c 00 00 00 00 a3 bc 31 00 0c 00 00 00 00 a3 bc 32 00 10 00 00 00 00 00 00 00 00 a1 00 00 00 38 be 68 30 00 a3 93 15 00 05 00 a3 93 16 00 04 00 a3 c0 39 20 03 01 04 09 a3 bf 78 10 02 08 09 61 c6 dc db b8 ca bf a3 bf 7a 10 02 08 9c 9f d3 c5 3d f0 37 82 a3 bf 7c 00 05 32 a3 bf 79 00 01 00 a3 bf 7b 00 05 32 a3 bf 7d 00 01 00 a2 a2 a2 00 00 00 00
DEBUG:s7.connection:  Trailer (4 bytes): 72 03 00 00
Explore:  b'\x03\r\xa1\x00\x00\x00\x01\x93.0\x00\xa3\x81i\x00\x15\x06ASRoot\xa3\x93\x15\x00\x05\x00\xa3\x93\x16\x00\x04\x00\xa3\x93\x1b\x10\x02\x08\x13\x00\x00\x00\x0e\x00\x00\x00\xa3\xa3R\x00\x14\x00\x00\xa3\xbeV\x10\x02\x04\x00\x00\x00\x00\xa3\x93/\x00\x04\x00\xa3\x93\x1c\x00\x15\x0bAOM.R506_02\xa3\x93\x1d\x00\x15\x0805.06.01\xa3\x93\x1e\x00\x15\x0b05.06.02.04\xa3\x93\x1f\x00\x15\x0fPAOM.R506_04_04\xa3\x9e<\x10\x02\x10r\x01\xa7\x89 \xbbu@\x8a\xea\x1b\xee9l\xe7\x9b\xa1\x00\x00\x00\x03\x93X0\x00\xa3\x81i\x00\x15\nPLCProgram\xa3\x93\x15\x00\x05\x8c\xaa\xbc\xca\xff\xac\x91\xd8d\xa3\x93\x16\x00\x04\x00\xa3\x9c3\x00\x01\x01\xa3\x9d"\x00\x05\x00\xa3\xa1/\x00\x03\x04\t\xa3\xa3?\x10\x03\x02\xea`\xeeG\xa3\xa4\x14\x00\x01\x00\xa3\x93/\x00\x042\xa3\xbb&\x00\x0c\x00\x00\x00\x00\xa3\xbc1\x00\x0c\x00\x00\x00\x00\xa3\xbc2\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\xa1\x00\x00\x008\xbeh0\x00\xa3\x93\x15\x00\x05\x00\xa3\x93\x16\x00\x04\x00\xa3\xc09 \x03\x01\x04\t\xa3\xbfx\x10\x02\x08\ta\xc6\xdc\xdb\xb8\xca\xbf\xa3\xbfz\x10\x02\x08\x9c\x9f\xd3\xc5=\xf07\x82\xa3\xbf|\x00\x052\xa3\xbfy\x00\x01\x00\xa3\xbf{\x00\x052\xa3\xbf}\x00\x01\x00\xa2\xa2\xa2\x00\x00\x00\x00'
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x04BB seq=4 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 04 bb 00 00 00 04 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (16 bytes): 8a 11 ff ff 00 01 00 01 00 00 0a 00 00 00 00 00
DEBUG:s7.connection:  Full frame (71 bytes): 72 03 00 3f 20 16 ba d6 de c1 64 fa 7d aa 39 ff 1c 9b 0f 4b 25 b7 91 3f ff 9a c6 ef 01 87 ea f2 e2 70 b5 ed d9 31 00 00 04 bb 00 00 00 04 00 00 03 9b 36 8a 11 ff ff 00 01 00 01 00 00 0a 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 78 bytes: 03 00 00 4e 02 f0 80 72 03 00 3f 20 16 ba d6 de c1 64 fa 7d aa 39 ff 1c 9b 0f 4b 25 b7 91 3f ff 9a c6 ef 01 87 ea f2 e2 70 b5 ed d9 31 00 00 04 bb 00 00 00 04 00 00 03 9b 36 8a 11 ff ff 00 01 00 01 00 00 0a 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=209 payload (205 bytes): 02 f0 80 72 fe 00 c6 00 00 00 00 00 00 02 c6 00 00 00 00 00 00 00 00 00 00 00 17 00 00 9d 6c 00 00 9d 6d 00 00 00 08 00 00 00 02 00 00 9d 6e 00 00 00 04 00 00 03 9b 00 00 9d 6f 00 00 00 04 00 00 04 bb 00 00 9d 70 00 00 00 03 00 04 00 00 9d 71 00 00 00 09 a2 01 3b 00 02 36 ff 88 00 00 9d 72 00 00 00 04 00 00 00 00 00 00 9d 73 00 00 00 04 00 00 04 bb 00 00 9d 74 00 00 00 04 00 00 00 e9 00 00 9d 75 00 00 00 04 00 00 00 00 00 00 9d 76 00 00 00 03 00 06 00 00 9d 77 00 00 00 03 00 00 00 00 9d 78 00 00 00 03 10 00 00 00 9d 79 00 00 00 03 10 11 00 00 9d 7a 00 00 00 03 08 01 00 00 9d 7b 00 00 00 03 10 29 00 00 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (202 bytes): 72 fe 00 c6 00 00 00 00 00 00 02 c6 00 00 00 00 00 00 00 00 00 00 00 17 00 00 9d 6c 00 00 9d 6d 00 00 00 08 00 00 00 02 00 00 9d 6e 00 00 00 04 00 00 03 9b 00 00 9d 6f 00 00 00 04 00 00 04 bb 00 00 9d 70 00 00 00 03 00 04 00 00 9d 71 00 00 00 09 a2 01 3b 00 02 36 ff 88 00 00 9d 72 00 00 00 04 00 00 00 00 00 00 9d 73 00 00 00 04 00 00 04 bb 00 00 9d 74 00 00 00 04 00 00 00 e9 00 00 9d 75 00 00 00 04 00 00 00 00 00 00 9d 76 00 00 00 03 00 06 00 00 9d 77 00 00 00 03 00 00 00 00 9d 78 00 00 00 03 10 00 00 00 9d 79 00 00 00 03 10 11 00 00 9d 7a 00 00 00 03 08 01 00 00 9d 7b 00 00 00 03 10 29 00 00 00 00
DEBUG:s7.connection:  Frame header: version=V254, data_length=198, header_size=4
DEBUG:s7.connection:  V254 frame: returning raw data (198 bytes)
Browse:  []
DEBUG:snap7.connection:Sent 33 bytes: 03 00 00 21 02 f0 80 72 01 00 12 31 00 00 04 d4 00 00 00 05 00 00 03 9b 36 00 00 00 00 72 01 00 00
INFO:snap7.connection:Disconnected from 192.168.0.1:102
DEBUG:snap7.client:Heartbeat stopped
INFO:snap7.connection:Disconnected from 192.168.0.1:102
INFO:snap7.client:Disconnected from 192.168.0.1:102
DEBUG:snap7.client:Heartbeat stopped
INFO:snap7.client:Disconnected from 192.168.0.1:102

f67f39d.zip

@gijzelaerr
Copy link
Copy Markdown
Owner Author

0x8A11FFFF also gets V254. Only the root object (0x38) returns real data. The PLC's EXPLORE only supports the top-level program tree — individual DB discovery requires GET_VAR_SUBSTREAMED, matching what TIA Portal does (frames 25-54 in your ProgramBlocks pcap).

So the auth and framing layers are fully working, but browse() on V1-initial PLCs needs a different DB discovery mechanism than EXPLORE. That's a separate piece of work — I'll track it in #728.

For now: explore() works (returns the program tree), db_read()/db_write() should work too via S7CommPlus. Can you try a direct db_read(7, 0, 2) via the S7CommPlus path (not legacy fallback)?

from s7._s7commplus_client import S7CommPlusClient

client = S7CommPlusClient()
client.connect("192.168.0.1")
print("connected via S7CommPlus")
data = client.db_read(7, 0, 2)
print(f"db7[0:2] = {data.hex()}")
client.disconnect()

@xBiggs
Copy link
Copy Markdown

xBiggs commented May 15, 2026

DEBUG:snap7.connection:TCP connected to 192.168.0.1:102
DEBUG:snap7.connection:Sent COTP Connection Request
DEBUG:snap7.connection:Negotiated PDU size: 1024
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc1, length=2
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc2, length=16
DEBUG:snap7.connection:Received COTP Connection Confirm
INFO:snap7.connection:Connected to 192.168.0.1:102, PDU size: 1024
DEBUG:s7.connection:=== InitSSL === sending (26 bytes): 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 33 bytes: 03 00 00 21 02 f0 80 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=38 payload (34 bytes): 02 f0 80 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== InitSSL === received (31 bytes): 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:InitSSL response: version=V1, data_length=23
DEBUG:s7.connection:InitSSL response body (27 bytes): 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === sending (192 bytes): 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 199 bytes: 03 00 00 c7 02 f0 80 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=215 payload (211 bytes): 02 f0 80 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 dd 97 05 55 33 20 6c 8c ab 3d 6b d2 3d 33 90 ab cf 04 95 1f a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === received (208 bytes): 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 dd 97 05 55 33 20 6c 8c ab 3d 6b d2 3d 33 90 ab cf 04 95 1f a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response: version=V1, data_length=200
DEBUG:s7.connection:CreateObject response body (204 bytes): 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 dd 97 05 55 33 20 6c 8c ab 3d 6b d2 3d 33 90 ab cf 04 95 1f a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response header: opcode=0x32 function=0x04CA seq=1 transport=0x36
DEBUG:s7.connection:CreateObject response: return_value=0 object_ids=['0x39b', '0x3c2']
DEBUG:s7.connection:Session created: id=0x0000039B (923), version=V1
INFO:s7.connection:Public key fingerprint captured: 01:BD426B091F08731A
INFO:s7.connection:Session challenge captured (20 bytes): dd97055533206c8cab3d6bd23d3390abcf04951f
INFO:s7.connection:ServerSessionVersion struct captured (84 bytes)
INFO:s7.connection:SessionKey auth blob generated (180 bytes)
INFO:s7.connection:SecurityKey blob included in session setup
DEBUG:s7.connection:=== SetupSession === sending (390 bytes): 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 2c 21 96 fb 9a e5 3f 30 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 fa e7 48 07 b1 f8 fa 40 28 68 07 35 b9 66 b1 00 ee 4a b4 af 37 82 0b 80 dd a5 a9 55 8d 40 3e 1f 14 74 ed ec e2 b9 16 08 1f 8a a0 6f b7 c9 40 27 f6 35 1d c8 42 5e a6 88 54 54 a3 13 7b 47 33 46 5c 9a a6 bd 9b 7b 78 fe 6d 44 6f cd 35 ba 85 bb cf 38 1b ef 8b 98 1e 07 2d 92 46 d1 56 a9 78 cc 45 ee 6b f4 76 a0 b2 20 ed 89 cc 30 08 0f be 31 0d 32 00 1a 69 f9 a0 e2 d0 30 75 e0 60 9a a0 ad 47 c8 c9 7f 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Sent 397 bytes: 03 00 01 8d 02 f0 80 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 2c 21 96 fb 9a e5 3f 30 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 fa e7 48 07 b1 f8 fa 40 28 68 07 35 b9 66 b1 00 ee 4a b4 af 37 82 0b 80 dd a5 a9 55 8d 40 3e 1f 14 74 ed ec e2 b9 16 08 1f 8a a0 6f b7 c9 40 27 f6 35 1d c8 42 5e a6 88 54 54 a3 13 7b 47 33 46 5c 9a a6 bd 9b 7b 78 fe 6d 44 6f cd 35 ba 85 bb cf 38 1b ef 8b 98 1e 07 2d 92 46 d1 56 a9 78 cc 45 ee 6b f4 76 a0 b2 20 ed 89 cc 30 08 0f be 31 0d 32 00 1a 69 f9 a0 e2 d0 30 75 e0 60 9a a0 ad 47 c8 c9 7f 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=32 payload (28 bytes): 02 f0 80 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:=== SetupSession === received (25 bytes): 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:SetupSession response: function=0x0542
INFO:s7.connection:Session setup completed successfully
INFO:s7.connection:S7CommPlus connected to 192.168.0.1:102, version=V1, session=923, tls=False
connected via S7CommPlus
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x054C seq=3 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 05 4c 00 00 00 03 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (44 bytes): 00 00 00 00 01 06 00 88 d0 b8 80 07 03 93 76 01 02 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00
DEBUG:s7.connection:  Full frame (99 bytes): 72 03 00 5b 20 ac 7e e8 1d 36 a6 ad 45 8c 10 0c fe c9 c6 95 72 dd 4a ad 8e e0 2c af ca ed ad 3b 05 c0 47 ab 78 31 00 00 05 4c 00 00 00 03 00 00 03 9b 36 00 00 00 00 01 06 00 88 d0 b8 80 07 03 93 76 01 02 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 106 bytes: 03 00 00 6a 02 f0 80 72 03 00 5b 20 ac 7e e8 1d 36 a6 ad 45 8c 10 0c fe c9 c6 95 72 dd 4a ad 8e e0 2c af ca ed ad 3b 05 c0 47 ab 78 31 00 00 05 4c 00 00 00 03 00 00 03 9b 36 00 00 00 00 01 06 00 88 d0 b8 80 07 03 93 76 01 02 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=209 payload (205 bytes): 02 f0 80 72 fe 00 c6 00 00 00 00 00 00 02 a3 00 00 00 00 00 00 00 00 00 00 00 17 00 00 9d 6c 00 00 9d 6d 00 00 00 08 00 00 00 02 00 00 9d 6e 00 00 00 04 00 00 03 9b 00 00 9d 6f 00 00 00 04 00 00 05 4c 00 00 9d 70 00 00 00 03 00 03 00 00 9d 71 00 00 00 09 a2 01 3b 00 01 39 ff 88 00 00 9d 72 00 00 00 04 00 00 00 00 00 00 9d 73 00 00 00 04 00 00 05 4c 00 00 9d 74 00 00 00 04 00 00 00 e9 00 00 9d 75 00 00 00 04 00 00 00 00 00 00 9d 76 00 00 00 03 00 05 00 00 9d 77 00 00 00 03 00 00 00 00 9d 78 00 00 00 03 10 00 00 00 9d 79 00 00 00 03 10 11 00 00 9d 7a 00 00 00 03 08 01 00 00 9d 7b 00 00 00 03 10 29 00 00 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (202 bytes): 72 fe 00 c6 00 00 00 00 00 00 02 a3 00 00 00 00 00 00 00 00 00 00 00 17 00 00 9d 6c 00 00 9d 6d 00 00 00 08 00 00 00 02 00 00 9d 6e 00 00 00 04 00 00 03 9b 00 00 9d 6f 00 00 00 04 00 00 05 4c 00 00 9d 70 00 00 00 03 00 03 00 00 9d 71 00 00 00 09 a2 01 3b 00 01 39 ff 88 00 00 9d 72 00 00 00 04 00 00 00 00 00 00 9d 73 00 00 00 04 00 00 05 4c 00 00 9d 74 00 00 00 04 00 00 00 e9 00 00 9d 75 00 00 00 04 00 00 00 00 00 00 9d 76 00 00 00 03 00 05 00 00 9d 77 00 00 00 03 00 00 00 00 9d 78 00 00 00 03 10 00 00 00 9d 79 00 00 00 03 10 11 00 00 9d 7a 00 00 00 03 08 01 00 00 9d 7b 00 00 00 03 10 29 00 00 00 00
DEBUG:s7.connection:  Frame header: version=V254, data_length=198, header_size=4
DEBUG:s7.connection:  V254 frame: returning raw data (198 bytes)
Traceback (most recent call last):
  File "\python-snap7-research-harpo-port-incomplete-f67f39d\main.py", line 9, in <module>
    data = client.db_read(7, 0, 2)
  File "\python-snap7-research-harpo-port-incomplete-f67f39d\s7\_s7commplus_client.py", line 129, in db_read
    raise RuntimeError("Read returned no data")
RuntimeError: Read returned no data

db_read.zip

@gijzelaerr
Copy link
Copy Markdown
Owner Author

db_read also gets V254 — it's not just EXPLORE, it's all data operations. The PLC requires a post-auth legitimation step before unlocking data access. In TIA Portal's pcap, frames 18-30 do a SET_VARIABLE + GET_VAR_SUBSTREAMED exchange right after the SessionKey handshake — that's what unlocks data ops.

The HMAC framing is correct (PLC accepts the packets), but data access is gated on this legitimation. This is the same password-auth mechanism that already exists in our authenticate() method, just triggered automatically even for PLCs with no password.

I'll analyze the legitimation sequence from the TIA pcap and add it.

V1-initial PLCs gate all data operations behind a legitimation
handshake after the SessionKey blob is accepted. Without it, every
request (EXPLORE, GET_MULTI_VARIABLES, etc.) gets a V254 response.

The sequence matches TIA Portal's behavior:
1. SET_VARIABLE: write USINT(5) to address 323 on session
2. GET_VAR_SUBSTREAMED: read from object 50, address 7920
3. GET_VAR_SUBSTREAMED: read from session, address 1842
4. GET_VAR_SUBSTREAMED: read from object 50, address 7920 again

Derived from TIA Portal v19 ProgramBlocks.pcapng (frames 18-30).
@gijzelaerr
Copy link
Copy Markdown
Owner Author

@xBiggs f18583d adds the post-auth legitimation sequence. After the SessionKey handshake, the connection now automatically sends the SET_VARIABLE + GET_VAR_SUBSTREAMED exchanges that TIA Portal does (frames 18-30 in your pcap). This should unlock data operations.

pip install --force-reinstall git+https://github.com/gijzelaerr/python-snap7.git@research/harpo-port-incomplete

Try both db_read and browse:

from s7._s7commplus_client import S7CommPlusClient
client = S7CommPlusClient()
client.connect("192.168.0.1")
print("db_read:", client.db_read(7, 0, 2).hex())
print("browse:", client.browse())
client.disconnect()

@xBiggs
Copy link
Copy Markdown

xBiggs commented May 15, 2026

DEBUG:snap7.connection:TCP connected to 192.168.0.1:102
DEBUG:snap7.connection:Sent COTP Connection Request
DEBUG:snap7.connection:Negotiated PDU size: 1024
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc1, length=2
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc2, length=16
DEBUG:snap7.connection:Received COTP Connection Confirm
INFO:snap7.connection:Connected to 192.168.0.1:102, PDU size: 1024
DEBUG:s7.connection:=== InitSSL === sending (26 bytes): 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 33 bytes: 03 00 00 21 02 f0 80 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=38 payload (34 bytes): 02 f0 80 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== InitSSL === received (31 bytes): 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:InitSSL response: version=V1, data_length=23
DEBUG:s7.connection:InitSSL response body (27 bytes): 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === sending (192 bytes): 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 199 bytes: 03 00 00 c7 02 f0 80 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=215 payload (211 bytes): 02 f0 80 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 a4 57 cf 28 a5 75 2e 8d 41 69 07 30 c6 65 92 cc 69 f4 19 39 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === received (208 bytes): 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 a4 57 cf 28 a5 75 2e 8d 41 69 07 30 c6 65 92 cc 69 f4 19 39 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response: version=V1, data_length=200
DEBUG:s7.connection:CreateObject response body (204 bytes): 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 a4 57 cf 28 a5 75 2e 8d 41 69 07 30 c6 65 92 cc 69 f4 19 39 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response header: opcode=0x32 function=0x04CA seq=1 transport=0x36
DEBUG:s7.connection:CreateObject response: return_value=0 object_ids=['0x39b', '0x3c2']
DEBUG:s7.connection:Session created: id=0x0000039B (923), version=V1
INFO:s7.connection:Public key fingerprint captured: 01:BD426B091F08731A
INFO:s7.connection:Session challenge captured (20 bytes): a457cf28a5752e8d41690730c66592cc69f41939
INFO:s7.connection:ServerSessionVersion struct captured (84 bytes)
INFO:s7.connection:SessionKey auth blob generated (180 bytes)
INFO:s7.connection:SecurityKey blob included in session setup
DEBUG:s7.connection:=== SetupSession === sending (390 bytes): 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 b3 a5 ec 62 d9 f9 05 50 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 7c e7 51 05 89 a3 23 72 52 e8 21 51 18 3a 83 f3 a0 26 19 b8 b4 8e b1 0c 00 52 5a 46 1d 16 b8 e6 8d 40 6a c9 2f af 3c b3 7a 03 51 8c a4 a2 f9 69 48 6f 64 fa cd 19 5c 84 9f 4d 2f 50 42 47 72 e6 19 30 1f 6c af 4e ae 91 e4 3d 8d 95 41 02 42 3b 74 c8 1b 73 e6 2b d9 f6 53 90 ca 4a fc 6e 25 10 8b 5e e3 d6 ba 8b 3f d1 da ea f0 9f 23 b5 31 3b 25 62 ca f5 44 6f 61 2e 5b 10 e6 3e 70 9a 93 be b0 8a e0 4c 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Sent 397 bytes: 03 00 01 8d 02 f0 80 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 b3 a5 ec 62 d9 f9 05 50 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 7c e7 51 05 89 a3 23 72 52 e8 21 51 18 3a 83 f3 a0 26 19 b8 b4 8e b1 0c 00 52 5a 46 1d 16 b8 e6 8d 40 6a c9 2f af 3c b3 7a 03 51 8c a4 a2 f9 69 48 6f 64 fa cd 19 5c 84 9f 4d 2f 50 42 47 72 e6 19 30 1f 6c af 4e ae 91 e4 3d 8d 95 41 02 42 3b 74 c8 1b 73 e6 2b d9 f6 53 90 ca 4a fc 6e 25 10 8b 5e e3 d6 ba 8b 3f d1 da ea f0 9f 23 b5 31 3b 25 62 ca f5 44 6f 61 2e 5b 10 e6 3e 70 9a 93 be b0 8a e0 4c 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=32 payload (28 bytes): 02 f0 80 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:=== SetupSession === received (25 bytes): 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:SetupSession response: function=0x0542
INFO:s7.connection:Session setup completed successfully
DEBUG:s7.connection:Post-auth legitimation: SET_VARIABLE to address 323
INFO:snap7.connection:Disconnected from 192.168.0.1:102
Traceback (most recent call last):
  File "\python-snap7-harpo-port-incomplete-f18583d\main.py", line 7, in <module>
    client.connect("192.168.0.1")
    ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "\python-snap7-harpo-port-incomplete-f18583d\s7\_s7commplus_client.py", line 94, in connect
    self._connection.connect(
    ~~~~~~~~~~~~~~~~~~~~~~~~^
        use_tls=use_tls,
        ^^^^^^^^^^^^^^^^
    ...<2 lines>...
        tls_ca=tls_ca,
        ^^^^^^^^^^^^^^
    )
    ^
  File "\python-snap7-harpo-port-incomplete-f18583d\s7\connection.py", line 269, in connect
    self._post_auth_legitimation()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "\python-snap7-harpo-port-incomplete-f18583d\s7\connection.py", line 1190, in _post_auth_legitimation
    self.send_request(FunctionCode.SET_VARIABLE, sv_payload)
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "\python-snap7-harpo-port-incomplete-f18583d\s7\connection.py", line 492, in send_request
    raise S7ConnectionError("Not connected")
snap7.error.S7ConnectionError: Not connected

f18583d.zip

@gijzelaerr
Copy link
Copy Markdown
Owner Author

@xBiggs Fixed in 9ac80a3send_request checked _connected but it wasn't set yet during connect(). Moved the flag before the legitimation call.

@xBiggs
Copy link
Copy Markdown

xBiggs commented May 18, 2026

DEBUG:snap7.connection:TCP connected to 192.168.0.1:102
DEBUG:snap7.connection:Sent COTP Connection Request
DEBUG:snap7.connection:Negotiated PDU size: 1024
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc1, length=2
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc2, length=16
DEBUG:snap7.connection:Received COTP Connection Confirm
INFO:snap7.connection:Connected to 192.168.0.1:102, PDU size: 1024
DEBUG:s7.connection:=== InitSSL === sending (26 bytes): 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 33 bytes: 03 00 00 21 02 f0 80 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=38 payload (34 bytes): 02 f0 80 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== InitSSL === received (31 bytes): 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:InitSSL response: version=V1, data_length=23
DEBUG:s7.connection:InitSSL response body (27 bytes): 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === sending (192 bytes): 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 199 bytes: 03 00 00 c7 02 f0 80 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=215 payload (211 bytes): 02 f0 80 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 70 99 d2 dd b7 58 fe 4e a0 ce bc da 03 50 60 6c cf d2 67 a3 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === received (208 bytes): 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 70 99 d2 dd b7 58 fe 4e a0 ce bc da 03 50 60 6c cf d2 67 a3 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response: version=V1, data_length=200
DEBUG:s7.connection:CreateObject response body (204 bytes): 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 70 99 d2 dd b7 58 fe 4e a0 ce bc da 03 50 60 6c cf d2 67 a3 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response header: opcode=0x32 function=0x04CA seq=1 transport=0x36
DEBUG:s7.connection:CreateObject response: return_value=0 object_ids=['0x39b', '0x3c2']
DEBUG:s7.connection:Session created: id=0x0000039B (923), version=V1
INFO:s7.connection:Public key fingerprint captured: 01:BD426B091F08731A
INFO:s7.connection:Session challenge captured (20 bytes): 7099d2ddb758fe4ea0cebcda0350606ccfd267a3
INFO:s7.connection:ServerSessionVersion struct captured (84 bytes)
INFO:s7.connection:SessionKey auth blob generated (180 bytes)
INFO:s7.connection:SecurityKey blob included in session setup
DEBUG:s7.connection:=== SetupSession === sending (390 bytes): 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 c5 f5 3f d5 12 9d 5c de 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 7c 6c 22 29 f9 11 c0 fa b6 6f da fc b2 a1 ea d3 22 87 bb cb 25 2b e9 1a 58 c1 8e a8 68 5e a5 3b 55 fe a4 07 bb 83 c3 10 8f 99 ea ab 43 13 cd c1 76 8c 1f 2c f1 86 21 5c d6 36 80 00 73 3a 97 ba 04 5d c2 53 21 c9 1f 27 67 21 2f fd ef c0 9d 2a 01 55 db 29 d3 43 d5 e2 95 f1 9b 79 48 f1 b1 e5 ac 36 26 a0 85 77 71 aa c5 9f d6 f1 78 36 4b ad fd 4d f6 f3 f7 97 33 24 ba d8 f0 1c 5b 62 68 70 06 51 68 46 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Sent 397 bytes: 03 00 01 8d 02 f0 80 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 c5 f5 3f d5 12 9d 5c de 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 7c 6c 22 29 f9 11 c0 fa b6 6f da fc b2 a1 ea d3 22 87 bb cb 25 2b e9 1a 58 c1 8e a8 68 5e a5 3b 55 fe a4 07 bb 83 c3 10 8f 99 ea ab 43 13 cd c1 76 8c 1f 2c f1 86 21 5c d6 36 80 00 73 3a 97 ba 04 5d c2 53 21 c9 1f 27 67 21 2f fd ef c0 9d 2a 01 55 db 29 d3 43 d5 e2 95 f1 9b 79 48 f1 b1 e5 ac 36 26 a0 85 77 71 aa c5 9f d6 f1 78 36 4b ad fd 4d f6 f3 f7 97 33 24 ba d8 f0 1c 5b 62 68 70 06 51 68 46 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=32 payload (28 bytes): 02 f0 80 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:=== SetupSession === received (25 bytes): 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:SetupSession response: function=0x0542
INFO:s7.connection:Session setup completed successfully
DEBUG:s7.connection:Post-auth legitimation: SET_VARIABLE to address 323
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x04F2 seq=3 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 04 f2 00 00 00 03 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (39 bytes): 00 00 03 9b 01 82 43 00 02 05 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 03 00 00 00 00
DEBUG:s7.connection:  Full frame (94 bytes): 72 03 00 56 20 a3 44 5c b3 74 f1 af 12 66 27 3d 4e fd d1 ac 61 1f 75 e0 83 c3 b2 92 ad c0 88 b8 b2 c3 92 54 da 31 00 00 04 f2 00 00 00 03 00 00 03 9b 36 00 00 03 9b 01 82 43 00 02 05 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 03 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 101 bytes: 03 00 00 65 02 f0 80 72 03 00 56 20 a3 44 5c b3 74 f1 af 12 66 27 3d 4e fd d1 ac 61 1f 75 e0 83 c3 b2 92 ad c0 88 b8 b2 c3 92 54 da 31 00 00 04 f2 00 00 00 03 00 00 03 9b 36 00 00 03 9b 01 82 43 00 02 05 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 03 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=64 payload (60 bytes): 02 f0 80 72 03 00 31 20 0e d6 6c 36 f8 c4 7f 03 a1 bb 59 fb db 85 9b bc ba 90 2a ed 60 fe d6 26 03 fb 8e 5d 3b cd 6e 63 32 00 00 04 f2 00 00 00 03 34 00 06 00 00 00 00 72 03 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (57 bytes): 72 03 00 31 20 0e d6 6c 36 f8 c4 7f 03 a1 bb 59 fb db 85 9b bc ba 90 2a ed 60 fe d6 26 03 fb 8e 5d 3b cd 6e 63 32 00 00 04 f2 00 00 00 03 34 00 06 00 00 00 00 72 03 00 00
DEBUG:s7.connection:  Frame header: version=V3, data_length=49, header_size=4
DEBUG:s7.connection:  V3 HMAC (32 bytes): 0ed66c36f8c47f03a1bb59fbdb859bbcba902aed60fed62603fb8e5d3bcd6e63
DEBUG:s7.connection:  Response data (16 bytes): 32 00 00 04 f2 00 00 00 03 34 00 06 00 00 00 00
DEBUG:s7.connection:  Response header: opcode=0x32 function=0x04F2 seq=3 session=0x34000600 transport=0x00
DEBUG:s7.connection:  Response payload (2 bytes): 00 00
DEBUG:s7.connection:  Trailer (4 bytes): 72 03 00 00
DEBUG:s7.connection:Post-auth legitimation: GET_VAR_SUBSTREAMED from object 50, address 7920
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x0586 seq=4 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 05 86 00 00 00 04 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (39 bytes): 00 00 00 32 20 04 01 bd 70 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 01 01 00 00 00 00
DEBUG:s7.connection:  Full frame (94 bytes): 72 03 00 56 20 7c 35 63 3a 41 89 3b 10 0c 07 ca d2 82 8f dd 9d ec f9 9e 51 85 b0 42 38 03 16 85 ca 62 c8 71 4e 31 00 00 05 86 00 00 00 04 00 00 03 9b 36 00 00 00 32 20 04 01 bd 70 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 01 01 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 101 bytes: 03 00 00 65 02 f0 80 72 03 00 56 20 7c 35 63 3a 41 89 3b 10 0c 07 ca d2 82 8f dd 9d ec f9 9e 51 85 b0 42 38 03 16 85 ca 62 c8 71 4e 31 00 00 05 86 00 00 00 04 00 00 03 9b 36 00 00 00 32 20 04 01 bd 70 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 01 01 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=318 payload (314 bytes): 02 f0 80 72 03 01 2f 20 79 f3 94 2a 96 eb 35 34 61 bf a4 62 16 d4 68 85 60 5a 90 1c 10 8d f5 bf 2f 64 23 04 71 4e 6f ec 32 00 00 05 86 00 00 00 04 34 00 00 00 14 00 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 32 00 00 00 00 04 00 00 00 00 00 00 65 4e 32 cb 76 e4 9b ac 04 01 00 00 00 00 00 00 83 57 01 90 cb c5 ab cc 01 01 00 00 00 00 00 00 3c 00 00 00 29 fa 20 70 47 1e 77 fd 57 c1 68 30 68 f4 52 f4 78 f7 c0 c8 12 5b 7c 02 70 a0 db 39 be f0 75 0d 87 70 fd e5 96 08 a0 04 d4 07 9d 5a 15 e0 fa 64 9f 20 b5 85 02 65 ea e0 a5 22 c8 2a ef be ad de 00 00 00 00 30 00 00 00 2d c4 6f 59 47 a4 c9 03 a4 9c 95 cb 04 f4 a1 0c 98 f1 4e 10 27 d4 0d 11 36 ea 89 6e e4 2b eb b2 d1 a8 3e fe 5b 23 4d 10 56 7d aa 18 63 9f b9 70 ef be ad de 01 00 00 00 14 00 00 00 8b 21 bb 3c 68 53 d6 6a fc 82 2e 08 20 2e 11 51 6c 3e 3f 1b ef be ad de 02 00 00 00 00 00 00 00 5c 07 7b 5d dd 59 e5 bf c9 fe c5 61 79 1a 51 40 e0 0b db 4b 05 00 00 00 00 72 03 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (311 bytes): 72 03 01 2f 20 79 f3 94 2a 96 eb 35 34 61 bf a4 62 16 d4 68 85 60 5a 90 1c 10 8d f5 bf 2f 64 23 04 71 4e 6f ec 32 00 00 05 86 00 00 00 04 34 00 00 00 14 00 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 32 00 00 00 00 04 00 00 00 00 00 00 65 4e 32 cb 76 e4 9b ac 04 01 00 00 00 00 00 00 83 57 01 90 cb c5 ab cc 01 01 00 00 00 00 00 00 3c 00 00 00 29 fa 20 70 47 1e 77 fd 57 c1 68 30 68 f4 52 f4 78 f7 c0 c8 12 5b 7c 02 70 a0 db 39 be f0 75 0d 87 70 fd e5 96 08 a0 04 d4 07 9d 5a 15 e0 fa 64 9f 20 b5 85 02 65 ea e0 a5 22 c8 2a ef be ad de 00 00 00 00 30 00 00 00 2d c4 6f 59 47 a4 c9 03 a4 9c 95 cb 04 f4 a1 0c 98 f1 4e 10 27 d4 0d 11 36 ea 89 6e e4 2b eb b2 d1 a8 3e fe 5b 23 4d 10 56 7d aa 18 63 9f b9 70 ef be ad de 01 00 00 00 14 00 00 00 8b 21 bb 3c 68 53 d6 6a fc 82 2e 08 20 2e 11 51 6c 3e 3f 1b ef be ad de 02 00 00 00 00 00 00 00 5c 07 7b 5d dd 59 e5 bf c9 fe c5 61 79 1a 51 40 e0 0b db 4b 05 00 00 00 00 72 03 00 00
DEBUG:s7.connection:  Frame header: version=V3, data_length=303, header_size=4
DEBUG:s7.connection:  V3 HMAC (32 bytes): 79f3942a96eb353461bfa46216d46885605a901c108df5bf2f642304714e6fec
DEBUG:s7.connection:  Response data (270 bytes): 32 00 00 05 86 00 00 00 04 34 00 00 00 14 00 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 32 00 00 00 00 04 00 00 00 00 00 00 65 4e 32 cb 76 e4 9b ac 04 01 00 00 00 00 00 00 83 57 01 90 cb c5 ab cc 01 01 00 00 00 00 00 00 3c 00 00 00 29 fa 20 70 47 1e 77 fd 57 c1 68 30 68 f4 52 f4 78 f7 c0 c8 12 5b 7c 02 70 a0 db 39 be f0 75 0d 87 70 fd e5 96 08 a0 04 d4 07 9d 5a 15 e0 fa 64 9f 20 b5 85 02 65 ea e0 a5 22 c8 2a ef be ad de 00 00 00 00 30 00 00 00 2d c4 6f 59 47 a4 c9 03 a4 9c 95 cb 04 f4 a1 0c 98 f1 4e 10 27 d4 0d 11 36 ea 89 6e e4 2b eb b2 d1 a8 3e fe 5b 23 4d 10 56 7d aa 18 63 9f b9 70 ef be ad de 01 00 00 00 14 00 00 00 8b 21 bb 3c 68 53 d6 6a fc 82 2e 08 20 2e 11 51 6c 3e 3f 1b ef be ad de 02 00 00 00 00 00 00 00 5c 07 7b 5d dd 59 e5 bf c9 fe c5 61 79 1a 51 40 e0 0b db 4b 05 00 00 00 00
DEBUG:s7.connection:  Response header: opcode=0x32 function=0x0586 seq=4 session=0x34000000 transport=0x14
DEBUG:s7.connection:  Response payload (256 bytes): 00 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 32 00 00 00 00 04 00 00 00 00 00 00 65 4e 32 cb 76 e4 9b ac 04 01 00 00 00 00 00 00 83 57 01 90 cb c5 ab cc 01 01 00 00 00 00 00 00 3c 00 00 00 29 fa 20 70 47 1e 77 fd 57 c1 68 30 68 f4 52 f4 78 f7 c0 c8 12 5b 7c 02 70 a0 db 39 be f0 75 0d 87 70 fd e5 96 08 a0 04 d4 07 9d 5a 15 e0 fa 64 9f 20 b5 85 02 65 ea e0 a5 22 c8 2a ef be ad de 00 00 00 00 30 00 00 00 2d c4 6f 59 47 a4 c9 03 a4 9c 95 cb 04 f4 a1 0c 98 f1 4e 10 27 d4 0d 11 36 ea 89 6e e4 2b eb b2 d1 a8 3e fe 5b 23 4d 10 56 7d aa 18 63 9f b9 70 ef be ad de 01 00 00 00 14 00 00 00 8b 21 bb 3c 68 53 d6 6a fc 82 2e 08 20 2e 11 51 6c 3e 3f 1b ef be ad de 02 00 00 00 00 00 00 00 5c 07 7b 5d dd 59 e5 bf c9 fe c5 61 79 1a 51 40 e0 0b db 4b 05 00 00 00 00
DEBUG:s7.connection:  Trailer (4 bytes): 72 03 00 00
DEBUG:s7.connection:Post-auth legitimation: GET_VAR_SUBSTREAMED from session, address 1842
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x0586 seq=5 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 05 86 00 00 00 05 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (39 bytes): 00 00 03 9b 20 04 01 8e 32 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 01 02 00 00 00 00
DEBUG:s7.connection:  Full frame (94 bytes): 72 03 00 56 20 ff f4 5c 98 bd 9a c8 dc 02 b5 e0 48 43 46 a8 5f ef 2d b1 9b 03 50 25 49 7c d1 f5 35 a8 96 c7 f4 31 00 00 05 86 00 00 00 05 00 00 03 9b 36 00 00 03 9b 20 04 01 8e 32 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 01 02 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 101 bytes: 03 00 00 65 02 f0 80 72 03 00 56 20 ff f4 5c 98 bd 9a c8 dc 02 b5 e0 48 43 46 a8 5f ef 2d b1 9b 03 50 25 49 7c d1 f5 35 a8 96 c7 f4 31 00 00 05 86 00 00 00 05 00 00 03 9b 36 00 00 03 9b 20 04 01 8e 32 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 01 02 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=68 payload (64 bytes): 02 f0 80 72 03 00 35 20 4c 66 85 93 f5 b3 a4 0c 26 bc ca c8 86 cd 4e b3 37 be 55 62 19 35 3e f6 c4 ba 84 1d 4a 7c 02 f3 32 00 00 05 86 00 00 00 05 34 00 00 00 04 01 07 00 00 00 00 72 03 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (61 bytes): 72 03 00 35 20 4c 66 85 93 f5 b3 a4 0c 26 bc ca c8 86 cd 4e b3 37 be 55 62 19 35 3e f6 c4 ba 84 1d 4a 7c 02 f3 32 00 00 05 86 00 00 00 05 34 00 00 00 04 01 07 00 00 00 00 72 03 00 00
DEBUG:s7.connection:  Frame header: version=V3, data_length=53, header_size=4
DEBUG:s7.connection:  V3 HMAC (32 bytes): 4c668593f5b3a40c26bccac886cd4eb337be556219353ef6c4ba841d4a7c02f3
DEBUG:s7.connection:  Response data (20 bytes): 32 00 00 05 86 00 00 00 05 34 00 00 00 04 01 07 00 00 00 00
DEBUG:s7.connection:  Response header: opcode=0x32 function=0x0586 seq=5 session=0x34000000 transport=0x04
DEBUG:s7.connection:  Response payload (6 bytes): 01 07 00 00 00 00
DEBUG:s7.connection:  Trailer (4 bytes): 72 03 00 00
DEBUG:s7.connection:Post-auth legitimation: GET_VAR_SUBSTREAMED from object 50, address 7920 (2nd)
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x0586 seq=6 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 05 86 00 00 00 06 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (39 bytes): 00 00 00 32 20 04 01 bd 70 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 01 03 00 00 00 00
DEBUG:s7.connection:  Full frame (94 bytes): 72 03 00 56 20 b4 25 58 a2 e8 53 43 aa b7 be 58 fa ab d7 6e ed c8 26 68 03 61 b5 5c 64 fc cd cd 6a 2a 85 35 b6 31 00 00 05 86 00 00 00 06 00 00 03 9b 36 00 00 00 32 20 04 01 bd 70 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 01 03 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 101 bytes: 03 00 00 65 02 f0 80 72 03 00 56 20 b4 25 58 a2 e8 53 43 aa b7 be 58 fa ab d7 6e ed c8 26 68 03 61 b5 5c 64 fc cd cd 6a 2a 85 35 b6 31 00 00 05 86 00 00 00 06 00 00 03 9b 36 00 00 00 32 20 04 01 bd 70 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 01 03 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=318 payload (314 bytes): 02 f0 80 72 03 01 2f 20 b7 d9 a6 19 a7 a1 80 27 79 61 9e 5e d1 42 55 b0 cb f5 39 4b 07 f5 40 c2 a4 70 1a c1 74 1a 38 26 32 00 00 05 86 00 00 00 06 34 00 00 00 14 00 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 32 00 00 00 00 04 00 00 00 00 00 00 65 4e 32 cb 76 e4 9b ac 04 01 00 00 00 00 00 00 83 57 01 90 cb c5 ab cc 01 01 00 00 00 00 00 00 3c 00 00 00 29 fa 20 70 47 1e 77 fd 57 c1 68 30 68 f4 52 f4 78 f7 c0 c8 12 5b 7c 02 70 a0 db 39 be f0 75 0d 87 70 fd e5 96 08 a0 04 d4 07 9d 5a 15 e0 fa 64 9f 20 b5 85 02 65 ea e0 a5 22 c8 2a ef be ad de 00 00 00 00 30 00 00 00 2d c4 6f 59 47 a4 c9 03 a4 9c 95 cb 04 f4 a1 0c 98 f1 4e 10 27 d4 0d 11 36 ea 89 6e e4 2b eb b2 d1 a8 3e fe 5b 23 4d 10 56 7d aa 18 63 9f b9 70 ef be ad de 01 00 00 00 14 00 00 00 8b 21 bb 3c 68 53 d6 6a fc 82 2e 08 20 2e 11 51 6c 3e 3f 1b ef be ad de 02 00 00 00 00 00 00 00 5c 07 7b 5d dd 59 e5 bf c9 fe c5 61 79 1a 51 40 e0 0b db 4b 09 00 00 00 00 72 03 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (311 bytes): 72 03 01 2f 20 b7 d9 a6 19 a7 a1 80 27 79 61 9e 5e d1 42 55 b0 cb f5 39 4b 07 f5 40 c2 a4 70 1a c1 74 1a 38 26 32 00 00 05 86 00 00 00 06 34 00 00 00 14 00 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 32 00 00 00 00 04 00 00 00 00 00 00 65 4e 32 cb 76 e4 9b ac 04 01 00 00 00 00 00 00 83 57 01 90 cb c5 ab cc 01 01 00 00 00 00 00 00 3c 00 00 00 29 fa 20 70 47 1e 77 fd 57 c1 68 30 68 f4 52 f4 78 f7 c0 c8 12 5b 7c 02 70 a0 db 39 be f0 75 0d 87 70 fd e5 96 08 a0 04 d4 07 9d 5a 15 e0 fa 64 9f 20 b5 85 02 65 ea e0 a5 22 c8 2a ef be ad de 00 00 00 00 30 00 00 00 2d c4 6f 59 47 a4 c9 03 a4 9c 95 cb 04 f4 a1 0c 98 f1 4e 10 27 d4 0d 11 36 ea 89 6e e4 2b eb b2 d1 a8 3e fe 5b 23 4d 10 56 7d aa 18 63 9f b9 70 ef be ad de 01 00 00 00 14 00 00 00 8b 21 bb 3c 68 53 d6 6a fc 82 2e 08 20 2e 11 51 6c 3e 3f 1b ef be ad de 02 00 00 00 00 00 00 00 5c 07 7b 5d dd 59 e5 bf c9 fe c5 61 79 1a 51 40 e0 0b db 4b 09 00 00 00 00 72 03 00 00
DEBUG:s7.connection:  Frame header: version=V3, data_length=303, header_size=4
DEBUG:s7.connection:  V3 HMAC (32 bytes): b7d9a619a7a1802779619e5ed14255b0cbf5394b07f540c2a4701ac1741a3826
DEBUG:s7.connection:  Response data (270 bytes): 32 00 00 05 86 00 00 00 06 34 00 00 00 14 00 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 32 00 00 00 00 04 00 00 00 00 00 00 65 4e 32 cb 76 e4 9b ac 04 01 00 00 00 00 00 00 83 57 01 90 cb c5 ab cc 01 01 00 00 00 00 00 00 3c 00 00 00 29 fa 20 70 47 1e 77 fd 57 c1 68 30 68 f4 52 f4 78 f7 c0 c8 12 5b 7c 02 70 a0 db 39 be f0 75 0d 87 70 fd e5 96 08 a0 04 d4 07 9d 5a 15 e0 fa 64 9f 20 b5 85 02 65 ea e0 a5 22 c8 2a ef be ad de 00 00 00 00 30 00 00 00 2d c4 6f 59 47 a4 c9 03 a4 9c 95 cb 04 f4 a1 0c 98 f1 4e 10 27 d4 0d 11 36 ea 89 6e e4 2b eb b2 d1 a8 3e fe 5b 23 4d 10 56 7d aa 18 63 9f b9 70 ef be ad de 01 00 00 00 14 00 00 00 8b 21 bb 3c 68 53 d6 6a fc 82 2e 08 20 2e 11 51 6c 3e 3f 1b ef be ad de 02 00 00 00 00 00 00 00 5c 07 7b 5d dd 59 e5 bf c9 fe c5 61 79 1a 51 40 e0 0b db 4b 09 00 00 00 00
DEBUG:s7.connection:  Response header: opcode=0x32 function=0x0586 seq=6 session=0x34000000 transport=0x14
DEBUG:s7.connection:  Response payload (256 bytes): 00 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 32 00 00 00 00 04 00 00 00 00 00 00 65 4e 32 cb 76 e4 9b ac 04 01 00 00 00 00 00 00 83 57 01 90 cb c5 ab cc 01 01 00 00 00 00 00 00 3c 00 00 00 29 fa 20 70 47 1e 77 fd 57 c1 68 30 68 f4 52 f4 78 f7 c0 c8 12 5b 7c 02 70 a0 db 39 be f0 75 0d 87 70 fd e5 96 08 a0 04 d4 07 9d 5a 15 e0 fa 64 9f 20 b5 85 02 65 ea e0 a5 22 c8 2a ef be ad de 00 00 00 00 30 00 00 00 2d c4 6f 59 47 a4 c9 03 a4 9c 95 cb 04 f4 a1 0c 98 f1 4e 10 27 d4 0d 11 36 ea 89 6e e4 2b eb b2 d1 a8 3e fe 5b 23 4d 10 56 7d aa 18 63 9f b9 70 ef be ad de 01 00 00 00 14 00 00 00 8b 21 bb 3c 68 53 d6 6a fc 82 2e 08 20 2e 11 51 6c 3e 3f 1b ef be ad de 02 00 00 00 00 00 00 00 5c 07 7b 5d dd 59 e5 bf c9 fe c5 61 79 1a 51 40 e0 0b db 4b 09 00 00 00 00
DEBUG:s7.connection:  Trailer (4 bytes): 72 03 00 00
INFO:s7.connection:Post-auth legitimation completed
INFO:s7.connection:S7CommPlus connected to 192.168.0.1:102, version=V1, session=923, tls=False
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x054C seq=7 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 05 4c 00 00 00 07 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (44 bytes): 00 00 00 00 01 06 00 88 d0 b8 80 07 03 93 76 01 02 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00
DEBUG:s7.connection:  Full frame (99 bytes): 72 03 00 5b 20 b9 ae 05 ae e7 c8 a3 30 1a 6b fa 29 0a 5b 54 d3 1f 44 cb 41 8e 4f e9 2c e4 9f d9 61 6c 77 5d ba 31 00 00 05 4c 00 00 00 07 00 00 03 9b 36 00 00 00 00 01 06 00 88 d0 b8 80 07 03 93 76 01 02 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 106 bytes: 03 00 00 6a 02 f0 80 72 03 00 5b 20 b9 ae 05 ae e7 c8 a3 30 1a 6b fa 29 0a 5b 54 d3 1f 44 cb 41 8e 4f e9 2c e4 9f d9 61 6c 77 5d ba 31 00 00 05 4c 00 00 00 07 00 00 03 9b 36 00 00 00 00 01 06 00 88 d0 b8 80 07 03 93 76 01 02 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=209 payload (205 bytes): 02 f0 80 72 fe 00 c6 00 00 00 00 00 00 03 fb 00 00 00 00 00 00 00 00 00 00 00 17 00 00 9d 6c 00 00 9d 6d 00 00 00 08 00 00 00 02 00 00 9d 6e 00 00 00 04 00 00 03 9b 00 00 9d 6f 00 00 00 04 00 00 05 4c 00 00 9d 70 00 00 00 03 00 07 00 00 9d 71 00 00 00 09 a2 01 3b 00 02 36 ff 88 00 00 9d 72 00 00 00 04 00 00 00 00 00 00 9d 73 00 00 00 04 00 00 05 4c 00 00 9d 74 00 00 00 04 00 00 00 e9 00 00 9d 75 00 00 00 04 00 00 00 00 00 00 9d 76 00 00 00 03 00 06 00 00 9d 77 00 00 00 03 00 00 00 00 9d 78 00 00 00 03 10 00 00 00 9d 79 00 00 00 03 10 11 00 00 9d 7a 00 00 00 03 08 01 00 00 9d 7b 00 00 00 03 10 29 00 00 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (202 bytes): 72 fe 00 c6 00 00 00 00 00 00 03 fb 00 00 00 00 00 00 00 00 00 00 00 17 00 00 9d 6c 00 00 9d 6d 00 00 00 08 00 00 00 02 00 00 9d 6e 00 00 00 04 00 00 03 9b 00 00 9d 6f 00 00 00 04 00 00 05 4c 00 00 9d 70 00 00 00 03 00 07 00 00 9d 71 00 00 00 09 a2 01 3b 00 02 36 ff 88 00 00 9d 72 00 00 00 04 00 00 00 00 00 00 9d 73 00 00 00 04 00 00 05 4c 00 00 9d 74 00 00 00 04 00 00 00 e9 00 00 9d 75 00 00 00 04 00 00 00 00 00 00 9d 76 00 00 00 03 00 06 00 00 9d 77 00 00 00 03 00 00 00 00 9d 78 00 00 00 03 10 00 00 00 9d 79 00 00 00 03 10 11 00 00 9d 7a 00 00 00 03 08 01 00 00 9d 7b 00 00 00 03 10 29 00 00 00 00
DEBUG:s7.connection:  Frame header: version=V254, data_length=198, header_size=4
DEBUG:s7.connection:  V254 frame: returning raw data (198 bytes)
Traceback (most recent call last):
  File "\python-snap7-research-harpo-port-incomplete-9ac80a3\main.py", line 8, in <module>
    print("db_read: ", client.db_read(7, 0, 2).hex())
                       ~~~~~~~~~~~~~~^^^^^^^^^
  File "\python-snap7-research-harpo-port-incomplete-9ac80a3\s7\_s7commplus_client.py", line 129, in db_read
    raise RuntimeError("Read returned no data")
RuntimeError: Read returned no data

9ac80a3.zip

@gijzelaerr
Copy link
Copy Markdown
Owner Author

Legitimation exchange completed (all 4 steps got V3 responses with DEADBEEF blobs). But db_read still gets V254.

The issue: we're reading the legitimation challenge blobs but not solving them. The PLC expects a challenge-response — read the blob, compute a cryptographic response, write it back. TIA Portal does this in frames 28-54 of the pcap (the additional GET_VAR_SUBSTREAMED calls after the initial read).

This is the LegitimateScheme.SolveLegitimateChallengeRealPlc from HarpoS7 — a separate crypto protocol on top of the SessionKey handshake. Unfortunately the HarpoS7 repo appears to have been taken down, so we'd need to reverse-engineer the challenge-response from the pcap or find a cached copy of the code.

The good news: the transport layer is fully working (SessionKey, V3 HMAC, legitimation request/response exchange). The remaining piece is the legitimation challenge solver.

Port LegitimateScheme.SolveLegitimateChallengeRealPlc from HarpoS7.
The solver generates a 248-byte DEADBEEF blob containing an encrypted
seed + AES-CBC encrypted challenge response, reusing the existing
RealPlcAuthenticator with keys derived from the session key and
password hash.

The post-auth legitimation now:
1. Reads the challenge blob from the PLC
2. Solves it (SHA1(password) + challenge as key2)
3. Writes the solved blob back via SET_VAR_SUBSTREAMED to address 1846

Verified byte-identical against C# test vector (password "zaq1@WSX",
S7-1200 key family).
@gijzelaerr
Copy link
Copy Markdown
Owner Author

@xBiggs 5570fef adds the legitimation challenge solver. After reading the DEADBEEF challenge blob, the connection now:

  1. Generates a 248-byte solved legitimation blob (SHA1("") + challenge as key, encrypted with the session key derivatives)
  2. Writes it back to the PLC via SET_VAR_SUBSTREAMED at address 1846

This is the final piece — if the PLC accepts the solved challenge, data operations should unlock.

pip install --force-reinstall git+https://github.com/gijzelaerr/python-snap7.git@research/harpo-port-incomplete

Try db_read again:

from s7._s7commplus_client import S7CommPlusClient
client = S7CommPlusClient()
client.connect("192.168.0.1")
data = client.db_read(7, 0, 2)
print(f"db7[0:2] = {data.hex()}")
client.disconnect()

session_key: bytes,
password: str = "",
) -> bytes:
password_hash = hashlib.sha1(password.encode("utf-8")).digest()
@xBiggs
Copy link
Copy Markdown

xBiggs commented May 18, 2026

DEBUG:snap7.connection:TCP connected to 192.168.0.1:102
DEBUG:snap7.connection:Sent COTP Connection Request
DEBUG:snap7.connection:Negotiated PDU size: 1024
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc1, length=2
DEBUG:snap7.connection:Unsupported COTP parameter: code=0xc2, length=16
DEBUG:snap7.connection:Received COTP Connection Confirm
INFO:snap7.connection:Connected to 192.168.0.1:102, PDU size: 1024
DEBUG:s7.connection:=== InitSSL === sending (26 bytes): 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 33 bytes: 03 00 00 21 02 f0 80 72 01 00 12 31 00 00 05 b3 00 00 00 00 00 00 00 00 30 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=38 payload (34 bytes): 02 f0 80 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== InitSSL === received (31 bytes): 72 01 00 17 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:InitSSL response: version=V1, data_length=23
DEBUG:s7.connection:InitSSL response body (27 bytes): 32 00 00 05 a9 00 00 00 00 34 d1 80 b3 a0 80 86 b9 ff 89 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === sending (192 bytes): 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Sent 199 bytes: 03 00 00 c7 02 f0 80 72 01 00 b8 31 00 00 04 ca 00 00 00 01 00 00 01 20 36 00 00 01 1d 00 04 00 00 00 00 00 a1 00 00 00 d3 82 1f 00 00 a3 81 69 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 21 00 15 15 31 3a 3a 3a 36 2e 30 3a 3a 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 28 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 29 00 15 00 a3 82 2a 00 15 0c 70 79 74 68 6f 6e 2d 73 6e 61 70 37 a3 82 2b 00 04 01 a3 82 2c 00 12 80 c3 c9 01 a3 82 2d 00 15 00 a1 00 00 00 d3 81 7f 00 00 a3 81 69 00 15 15 53 75 62 73 63 72 69 70 74 69 6f 6e 43 6f 6e 74 61 69 6e 65 72 a2 a2 00 00 00 00 72 01 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=215 payload (211 bytes): 02 f0 80 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 b1 be 3e f1 2e 97 3b 6c 92 09 b0 fa 29 59 8a d3 7f 8f df a2 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:=== CreateObject === received (208 bytes): 72 01 00 c8 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 b1 be 3e f1 2e 97 3b 6c 92 09 b0 fa 29 59 8a d3 7f 8f df a2 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response: version=V1, data_length=200
DEBUG:s7.connection:CreateObject response body (204 bytes): 32 00 00 04 ca 00 00 00 01 36 00 02 87 1b 87 42 a1 00 00 01 20 82 1f 00 00 a3 81 69 00 15 13 30 31 3a 42 44 34 32 36 42 30 39 31 46 30 38 37 33 31 41 a3 82 2b 00 04 82 80 80 80 02 a3 82 2d 00 15 10 4f 4d 53 50 2e 52 45 4c 2e 38 30 38 39 2e 32 31 a3 82 2f 10 02 14 b1 be 3e f1 2e 97 3b 6c 92 09 b0 fa 29 59 8a d3 7f 8f df a2 a3 82 32 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 1b 31 3b 36 45 53 37 20 32 31 35 2d 31 42 47 34 30 2d 30 58 42 30 20 3b 56 34 2e 32 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 a2 00 00 00 00 72 01 00 00
DEBUG:s7.connection:CreateObject response header: opcode=0x32 function=0x04CA seq=1 transport=0x36
DEBUG:s7.connection:CreateObject response: return_value=0 object_ids=['0x39b', '0x3c2']
DEBUG:s7.connection:Session created: id=0x0000039B (923), version=V1
INFO:s7.connection:Public key fingerprint captured: 01:BD426B091F08731A
INFO:s7.connection:Session challenge captured (20 bytes): b1be3ef12e973b6c9209b0fa29598ad37f8fdfa2
INFO:s7.connection:ServerSessionVersion struct captured (84 bytes)
INFO:s7.connection:SessionKey auth blob generated (180 bytes)
INFO:s7.connection:SecurityKey blob included in session setup
DEBUG:s7.connection:=== SetupSession === sending (390 bytes): 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 5e b7 b5 5f 1f 0c d3 5e 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 a4 3a c8 61 27 ad dc 19 18 df a0 0b 96 ba 2b de 97 9a 57 e4 d8 90 d0 ac 4f 56 8b 2f a7 8f af ec 6a 5d 07 29 31 3a 75 25 66 ba c0 f0 3e 7d d9 95 fd 90 65 05 f3 49 f6 c2 b8 86 b3 a9 ab 13 81 3c 46 90 d4 0f b1 7c c2 c0 67 61 26 ae a6 84 3e 2d b3 28 96 b1 e8 e0 42 5d d7 8d 21 7c c8 b7 26 38 4f 14 8b 45 0c 96 b2 8c 80 4a f6 04 53 df 45 88 d5 82 2e 3e d6 6a 2b e1 6f 5e 32 69 0b 0f bb 8b 55 09 42 c7 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Sent 397 bytes: 03 00 01 8d 02 f0 80 72 02 01 7e 31 00 00 05 42 00 00 00 02 00 00 03 9b 34 00 00 03 9b 02 02 8e 26 82 32 01 00 17 00 00 07 08 8e 09 00 04 00 8e 0a 00 02 00 8e 0b 00 17 00 00 07 21 8e 22 00 05 de d0 cd b0 c8 fc 90 f3 1a 8e 23 00 04 82 10 8e 24 00 04 00 00 8e 0c 00 17 00 00 07 21 8e 22 00 05 d1 85 cc 83 ac b4 93 d1 42 8e 23 00 04 84 82 01 8e 24 00 04 00 00 8e 0d 00 14 00 81 34 ad de e1 fe b4 00 00 00 01 00 00 00 01 00 00 00 5e b7 b5 5f 1f 0c d3 5e 01 01 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 a4 3a c8 61 27 ad dc 19 18 df a0 0b 96 ba 2b de 97 9a 57 e4 d8 90 d0 ac 4f 56 8b 2f a7 8f af ec 6a 5d 07 29 31 3a 75 25 66 ba c0 f0 3e 7d d9 95 fd 90 65 05 f3 49 f6 c2 b8 86 b3 a9 ab 13 81 3c 46 90 d4 0f b1 7c c2 c0 67 61 26 ae a6 84 3e 2d b3 28 96 b1 e8 e0 42 5d d7 8d 21 7c c8 b7 26 38 4f 14 8b 45 0c 96 b2 8c 80 4a f6 04 53 df 45 88 d5 82 2e 3e d6 6a 2b e1 6f 5e 32 69 0b 0f bb 8b 55 09 42 c7 00 02 00 17 00 00 01 3a 82 3b 00 04 84 00 82 3c 00 04 84 00 82 3d 00 04 84 80 c2 00 82 3e 00 04 84 80 c2 00 82 3f 00 15 00 82 40 00 15 06 32 3b 31 30 38 32 82 41 00 03 00 03 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 02 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=32 payload (28 bytes): 02 f0 80 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:=== SetupSession === received (25 bytes): 72 02 00 11 32 00 00 05 42 00 00 00 02 34 00 00 00 00 00 00 00 72 02 00 00
DEBUG:s7.connection:SetupSession response: function=0x0542
INFO:s7.connection:Session setup completed successfully
DEBUG:s7.connection:Post-auth legitimation: SET_VARIABLE to address 323
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x04F2 seq=3 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 04 f2 00 00 00 03 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (39 bytes): 00 00 03 9b 01 82 43 00 02 05 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 03 00 00 00 00
DEBUG:s7.connection:  Full frame (94 bytes): 72 03 00 56 20 c2 bc 69 c6 bc 42 58 4e 94 0d eb d4 d0 d7 a2 f7 f7 d2 82 3b b8 8d 29 50 1a f2 9b 05 87 f1 7d b1 31 00 00 04 f2 00 00 00 03 00 00 03 9b 36 00 00 03 9b 01 82 43 00 02 05 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 03 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 101 bytes: 03 00 00 65 02 f0 80 72 03 00 56 20 c2 bc 69 c6 bc 42 58 4e 94 0d eb d4 d0 d7 a2 f7 f7 d2 82 3b b8 8d 29 50 1a f2 9b 05 87 f1 7d b1 31 00 00 04 f2 00 00 00 03 00 00 03 9b 36 00 00 03 9b 01 82 43 00 02 05 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 03 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=64 payload (60 bytes): 02 f0 80 72 03 00 31 20 c3 05 90 5b 5b 74 63 ce 63 96 16 57 1e 9b e4 fb 4f ba 16 c4 9d c8 61 d5 bc f8 18 d0 74 61 c7 ae 32 00 00 04 f2 00 00 00 03 34 00 06 00 00 00 00 72 03 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (57 bytes): 72 03 00 31 20 c3 05 90 5b 5b 74 63 ce 63 96 16 57 1e 9b e4 fb 4f ba 16 c4 9d c8 61 d5 bc f8 18 d0 74 61 c7 ae 32 00 00 04 f2 00 00 00 03 34 00 06 00 00 00 00 72 03 00 00
DEBUG:s7.connection:  Frame header: version=V3, data_length=49, header_size=4
DEBUG:s7.connection:  V3 HMAC (32 bytes): c305905b5b7463ce639616571e9be4fb4fba16c49dc861d5bcf818d07461c7ae
DEBUG:s7.connection:  Response data (16 bytes): 32 00 00 04 f2 00 00 00 03 34 00 06 00 00 00 00
DEBUG:s7.connection:  Response header: opcode=0x32 function=0x04F2 seq=3 session=0x34000600 transport=0x00
DEBUG:s7.connection:  Response payload (2 bytes): 00 00
DEBUG:s7.connection:  Trailer (4 bytes): 72 03 00 00
DEBUG:s7.connection:Post-auth legitimation: GET_VAR_SUBSTREAMED from object 50, address 7920
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x0586 seq=4 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 05 86 00 00 00 04 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (39 bytes): 00 00 00 32 20 04 01 bd 70 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 01 01 00 00 00 00
DEBUG:s7.connection:  Full frame (94 bytes): 72 03 00 56 20 a7 a2 4b 85 51 b7 42 e9 79 ae 70 85 41 51 30 ff 54 ba ed 54 62 d7 ac 62 5f 09 6d be b4 b5 eb c1 31 00 00 05 86 00 00 00 04 00 00 03 9b 36 00 00 00 32 20 04 01 bd 70 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 01 01 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 101 bytes: 03 00 00 65 02 f0 80 72 03 00 56 20 a7 a2 4b 85 51 b7 42 e9 79 ae 70 85 41 51 30 ff 54 ba ed 54 62 d7 ac 62 5f 09 6d be b4 b5 eb c1 31 00 00 05 86 00 00 00 04 00 00 03 9b 36 00 00 00 32 20 04 01 bd 70 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 01 01 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=318 payload (314 bytes): 02 f0 80 72 03 01 2f 20 13 d7 1a e3 e6 ab 56 e4 24 1e 8b 77 f2 96 01 17 28 fe 92 ea 15 48 ae ec ca 2d 08 70 7e 5c 2a ca 32 00 00 05 86 00 00 00 04 34 00 00 00 14 00 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 32 00 00 00 00 04 00 00 00 00 00 00 65 4e 32 cb 76 e4 9b ac 04 01 00 00 00 00 00 00 83 57 01 90 cb c5 ab cc 01 01 00 00 00 00 00 00 3c 00 00 00 29 fa 20 70 47 1e 77 fd 57 c1 68 30 68 f4 52 f4 78 f7 c0 c8 12 5b 7c 02 70 a0 db 39 be f0 75 0d 87 70 fd e5 96 08 a0 04 d4 07 9d 5a 15 e0 fa 64 9f 20 b5 85 02 65 ea e0 a5 22 c8 2a ef be ad de 00 00 00 00 30 00 00 00 2d c4 6f 59 47 a4 c9 03 a4 9c 95 cb 04 f4 a1 0c 98 f1 4e 10 27 d4 0d 11 36 ea 89 6e e4 2b eb b2 d1 a8 3e fe 5b 23 4d 10 56 7d aa 18 63 9f b9 70 ef be ad de 01 00 00 00 14 00 00 00 8b 21 bb 3c 68 53 d6 6a fc 82 2e 08 20 2e 11 51 6c 3e 3f 1b ef be ad de 02 00 00 00 00 00 00 00 5c 07 7b 5d dd 59 e5 bf c9 fe c5 61 79 1a 51 40 e0 0b db 4b 05 00 00 00 00 72 03 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (311 bytes): 72 03 01 2f 20 13 d7 1a e3 e6 ab 56 e4 24 1e 8b 77 f2 96 01 17 28 fe 92 ea 15 48 ae ec ca 2d 08 70 7e 5c 2a ca 32 00 00 05 86 00 00 00 04 34 00 00 00 14 00 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 32 00 00 00 00 04 00 00 00 00 00 00 65 4e 32 cb 76 e4 9b ac 04 01 00 00 00 00 00 00 83 57 01 90 cb c5 ab cc 01 01 00 00 00 00 00 00 3c 00 00 00 29 fa 20 70 47 1e 77 fd 57 c1 68 30 68 f4 52 f4 78 f7 c0 c8 12 5b 7c 02 70 a0 db 39 be f0 75 0d 87 70 fd e5 96 08 a0 04 d4 07 9d 5a 15 e0 fa 64 9f 20 b5 85 02 65 ea e0 a5 22 c8 2a ef be ad de 00 00 00 00 30 00 00 00 2d c4 6f 59 47 a4 c9 03 a4 9c 95 cb 04 f4 a1 0c 98 f1 4e 10 27 d4 0d 11 36 ea 89 6e e4 2b eb b2 d1 a8 3e fe 5b 23 4d 10 56 7d aa 18 63 9f b9 70 ef be ad de 01 00 00 00 14 00 00 00 8b 21 bb 3c 68 53 d6 6a fc 82 2e 08 20 2e 11 51 6c 3e 3f 1b ef be ad de 02 00 00 00 00 00 00 00 5c 07 7b 5d dd 59 e5 bf c9 fe c5 61 79 1a 51 40 e0 0b db 4b 05 00 00 00 00 72 03 00 00
DEBUG:s7.connection:  Frame header: version=V3, data_length=303, header_size=4
DEBUG:s7.connection:  V3 HMAC (32 bytes): 13d71ae3e6ab56e4241e8b77f296011728fe92ea1548aeecca2d08707e5c2aca
DEBUG:s7.connection:  Response data (270 bytes): 32 00 00 05 86 00 00 00 04 34 00 00 00 14 00 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 32 00 00 00 00 04 00 00 00 00 00 00 65 4e 32 cb 76 e4 9b ac 04 01 00 00 00 00 00 00 83 57 01 90 cb c5 ab cc 01 01 00 00 00 00 00 00 3c 00 00 00 29 fa 20 70 47 1e 77 fd 57 c1 68 30 68 f4 52 f4 78 f7 c0 c8 12 5b 7c 02 70 a0 db 39 be f0 75 0d 87 70 fd e5 96 08 a0 04 d4 07 9d 5a 15 e0 fa 64 9f 20 b5 85 02 65 ea e0 a5 22 c8 2a ef be ad de 00 00 00 00 30 00 00 00 2d c4 6f 59 47 a4 c9 03 a4 9c 95 cb 04 f4 a1 0c 98 f1 4e 10 27 d4 0d 11 36 ea 89 6e e4 2b eb b2 d1 a8 3e fe 5b 23 4d 10 56 7d aa 18 63 9f b9 70 ef be ad de 01 00 00 00 14 00 00 00 8b 21 bb 3c 68 53 d6 6a fc 82 2e 08 20 2e 11 51 6c 3e 3f 1b ef be ad de 02 00 00 00 00 00 00 00 5c 07 7b 5d dd 59 e5 bf c9 fe c5 61 79 1a 51 40 e0 0b db 4b 05 00 00 00 00
DEBUG:s7.connection:  Response header: opcode=0x32 function=0x0586 seq=4 session=0x34000000 transport=0x14
DEBUG:s7.connection:  Response payload (256 bytes): 00 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 32 00 00 00 00 04 00 00 00 00 00 00 65 4e 32 cb 76 e4 9b ac 04 01 00 00 00 00 00 00 83 57 01 90 cb c5 ab cc 01 01 00 00 00 00 00 00 3c 00 00 00 29 fa 20 70 47 1e 77 fd 57 c1 68 30 68 f4 52 f4 78 f7 c0 c8 12 5b 7c 02 70 a0 db 39 be f0 75 0d 87 70 fd e5 96 08 a0 04 d4 07 9d 5a 15 e0 fa 64 9f 20 b5 85 02 65 ea e0 a5 22 c8 2a ef be ad de 00 00 00 00 30 00 00 00 2d c4 6f 59 47 a4 c9 03 a4 9c 95 cb 04 f4 a1 0c 98 f1 4e 10 27 d4 0d 11 36 ea 89 6e e4 2b eb b2 d1 a8 3e fe 5b 23 4d 10 56 7d aa 18 63 9f b9 70 ef be ad de 01 00 00 00 14 00 00 00 8b 21 bb 3c 68 53 d6 6a fc 82 2e 08 20 2e 11 51 6c 3e 3f 1b ef be ad de 02 00 00 00 00 00 00 00 5c 07 7b 5d dd 59 e5 bf c9 fe c5 61 79 1a 51 40 e0 0b db 4b 05 00 00 00 00
DEBUG:s7.connection:  Trailer (4 bytes): 72 03 00 00
DEBUG:s7.connection:Legitimation response: 256 bytes
INFO:s7.connection:Legitimation blob generated (248 bytes)
DEBUG:s7.connection:Post-auth legitimation: SET_VAR_SUBSTREAMED with solved blob
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x057C seq=5 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 05 7c 00 00 00 05 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (288 bytes): 00 00 03 9b 01 01 8e 36 01 00 14 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 8c fc ae 1a 4a 30 78 79 01 00 00 00 00 00 00 00 3c 00 00 00 ef 92 ac 5d 10 49 40 ad 46 11 0a ec ab a8 91 0f 69 e4 d3 a6 66 46 86 2d 48 84 1d 64 44 53 45 96 ee 27 21 a6 fd 17 1f 47 40 f0 eb 67 6c 23 e5 fb 87 4f b7 d8 c9 d1 e6 99 41 0d 26 d2 ef be ad de 00 00 00 00 40 00 00 00 45 a9 cc 68 b5 50 72 d2 8a 15 d1 0e 47 89 8f 13 e3 e4 f3 23 7e 78 50 20 30 50 d4 44 5e 27 5a 5d 9c 9b 10 ad 9b 68 88 e6 ce d2 5e 13 0c 92 12 a7 4c 07 a0 87 61 3e 86 51 59 d6 6f ff 51 3c 93 32 ef be ad de 01 00 00 00 18 00 00 00 6e f5 2e e8 88 b3 e9 4a 60 ab bf 84 d1 7b 79 ca 62 2e dc 4c 18 91 a2 76 ef be ad de 02 00 00 00 00 00 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00
DEBUG:s7.connection:  Full frame (343 bytes): 72 03 01 4f 20 65 fb fa b6 6a 6e c8 c9 be 86 da 36 56 61 1b 97 8f b8 5b e2 fc 4a 46 15 88 fa d2 47 df d7 01 bf 31 00 00 05 7c 00 00 00 05 00 00 03 9b 36 00 00 03 9b 01 01 8e 36 01 00 14 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 8c fc ae 1a 4a 30 78 79 01 00 00 00 00 00 00 00 3c 00 00 00 ef 92 ac 5d 10 49 40 ad 46 11 0a ec ab a8 91 0f 69 e4 d3 a6 66 46 86 2d 48 84 1d 64 44 53 45 96 ee 27 21 a6 fd 17 1f 47 40 f0 eb 67 6c 23 e5 fb 87 4f b7 d8 c9 d1 e6 99 41 0d 26 d2 ef be ad de 00 00 00 00 40 00 00 00 45 a9 cc 68 b5 50 72 d2 8a 15 d1 0e 47 89 8f 13 e3 e4 f3 23 7e 78 50 20 30 50 d4 44 5e 27 5a 5d 9c 9b 10 ad 9b 68 88 e6 ce d2 5e 13 0c 92 12 a7 4c 07 a0 87 61 3e 86 51 59 d6 6f ff 51 3c 93 32 ef be ad de 01 00 00 00 18 00 00 00 6e f5 2e e8 88 b3 e9 4a 60 ab bf 84 d1 7b 79 ca 62 2e dc 4c 18 91 a2 76 ef be ad de 02 00 00 00 00 00 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 350 bytes: 03 00 01 5e 02 f0 80 72 03 01 4f 20 65 fb fa b6 6a 6e c8 c9 be 86 da 36 56 61 1b 97 8f b8 5b e2 fc 4a 46 15 88 fa d2 47 df d7 01 bf 31 00 00 05 7c 00 00 00 05 00 00 03 9b 36 00 00 03 9b 01 01 8e 36 01 00 14 81 78 ef be ad de 7c 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 1a 73 08 1f 09 6b 42 bd 10 01 00 00 00 00 00 00 8c fc ae 1a 4a 30 78 79 01 00 00 00 00 00 00 00 3c 00 00 00 ef 92 ac 5d 10 49 40 ad 46 11 0a ec ab a8 91 0f 69 e4 d3 a6 66 46 86 2d 48 84 1d 64 44 53 45 96 ee 27 21 a6 fd 17 1f 47 40 f0 eb 67 6c 23 e5 fb 87 4f b7 d8 c9 d1 e6 99 41 0d 26 d2 ef be ad de 00 00 00 00 40 00 00 00 45 a9 cc 68 b5 50 72 d2 8a 15 d1 0e 47 89 8f 13 e3 e4 f3 23 7e 78 50 20 30 50 d4 44 5e 27 5a 5d 9c 9b 10 ad 9b 68 88 e6 ce d2 5e 13 0c 92 12 a7 4c 07 a0 87 61 3e 86 51 59 d6 6f ff 51 3c 93 32 ef be ad de 01 00 00 00 18 00 00 00 6e f5 2e e8 88 b3 e9 4a 60 ab bf 84 d1 7b 79 ca 62 2e dc 4c 18 91 a2 76 ef be ad de 02 00 00 00 00 00 00 00 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 03 00 00       
DEBUG:snap7.connection:Received TPKT: version=3 length=27 payload (23 bytes): 02 f0 80 72 fe 00 10 00 00 00 00 00 00 02 f4 00 00 00 00 00 00 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (20 bytes): 72 fe 00 10 00 00 00 00 00 00 02 f4 00 00 00 00 00 00 00 00
DEBUG:s7.connection:  Frame header: version=V254, data_length=16, header_size=4
DEBUG:s7.connection:  V254 frame: returning raw data (16 bytes)
INFO:s7.connection:Post-auth legitimation completed
INFO:s7.connection:S7CommPlus connected to 192.168.0.1:102, version=V1, session=923, tls=False
DEBUG:s7.connection:=== SEND REQUEST === function_code=0x054C seq=6 session=0x0000039B
DEBUG:s7.connection:  Request header (14 bytes): 31 00 00 05 4c 00 00 00 06 00 00 03 9b 36
DEBUG:s7.connection:  Request payload (44 bytes): 00 00 00 00 01 06 00 88 d0 b8 80 07 03 93 76 01 02 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00
DEBUG:s7.connection:  Full frame (99 bytes): 72 03 00 5b 20 65 74 59 b1 5a bc 73 2b 3a ac 45 5d cd 46 f9 6e 64 da 7f 28 cb 3a 61 24 47 d8 bc 38 bb 48 37 27 31 00 00 05 4c 00 00 00 06 00 00 03 9b 36 00 00 00 00 01 06 00 88 d0 b8 80 07 03 93 76 01 02 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Sent 106 bytes: 03 00 00 6a 02 f0 80 72 03 00 5b 20 65 74 59 b1 5a bc 73 2b 3a ac 45 5d cd 46 f9 6e 64 da 7f 28 cb 3a 61 24 47 d8 bc 38 bb 48 37 27 31 00 00 05 4c 00 00 00 06 00 00 03 9b 36 00 00 00 00 01 06 00 88 d0 b8 80 07 03 93 76 01 02 00 00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00 89 6b 00 04 00 00 00 00 00 00 72 03 00 00
DEBUG:snap7.connection:Received TPKT: version=3 length=243 payload (239 bytes): 02 f0 80 72 03 00 e4 20 7f da 5c 60 c5 53 a6 db c7 99 85 fb 88 a9 52 ca 2d 4c b8 5c e6 62 73 3e 4a 9d 27 a1 39 ea 65 99 32 00 00 05 7c 00 00 00 05 36 e1 c6 91 90 80 86 e7 ff fe 05 a1 00 00 00 d2 84 08 00 00 a3 81 69 00 15 12 52 65 73 70 6f 6e 73 65 45 78 74 65 6e 73 69 6f 6e 73 a1 00 00 00 d2 84 0a 00 00 a3 81 69 00 15 11 52 65 73 70 6f 6e 73 65 45 78 74 65 6e 73 69 6f 6e a3 84 0b 00 09 c1 c6 81 90 80 86 e7 ff fe a3 84 57 00 15 23 52 65 71 75 65 73 74 20 53 65 74 56 61 72 69 61 62 6c 65 53 75 62 72 61 6e 67 65 53 74 72 65 61 6d 65 64 a3 84 0c 00 01 00 a3 84 0d 00 01 00 a3 84 0e 00 04 87 1b a3 84 0f 00 04 00 a3 84 10 00 04 00 a3 84 12 00 04 00 a3 84 13 00 04 00 a3 84 15 00 04 00 a2 a2 00 00 00 00 72 03 00 00
DEBUG:s7.connection:=== RECV RESPONSE === raw frame (236 bytes): 72 03 00 e4 20 7f da 5c 60 c5 53 a6 db c7 99 85 fb 88 a9 52 ca 2d 4c b8 5c e6 62 73 3e 4a 9d 27 a1 39 ea 65 99 32 00 00 05 7c 00 00 00 05 36 e1 c6 91 90 80 86 e7 ff fe 05 a1 00 00 00 d2 84 08 00 00 a3 81 69 00 15 12 52 65 73 70 6f 6e 73 65 45 78 74 65 6e 73 69 6f 6e 73 a1 00 00 00 d2 84 0a 00 00 a3 81 69 00 15 11 52 65 73 70 6f 6e 73 65 45 78 74 65 6e 73 69 6f 6e a3 84 0b 00 09 c1 c6 81 90 80 86 e7 ff fe a3 84 57 00 15 23 52 65 71 75 65 73 74 20 53 65 74 56 61 72 69 61 62 6c 65 53 75 62 72 61 6e 67 65 53 74 72 65 61 6d 65 64 a3 84 0c 00 01 00 a3 84 0d 00 01 00 a3 84 0e 00 04 87 1b a3 84 0f 00 04 00 a3 84 10 00 04 00 a3 84 12 00 04 00 a3 84 13 00 04 00 a3 84 15 00 04 00 a2 a2 00 00 00 00 72 03 00 00
DEBUG:s7.connection:  Frame header: version=V3, data_length=228, header_size=4
DEBUG:s7.connection:  V3 HMAC (32 bytes): 7fda5c60c553a6dbc79985fb88a952ca2d4cb85ce662733e4a9d27a139ea6599
DEBUG:s7.connection:  Response data (195 bytes): 32 00 00 05 7c 00 00 00 05 36 e1 c6 91 90 80 86 e7 ff fe 05 a1 00 00 00 d2 84 08 00 00 a3 81 69 00 15 12 52 65 73 70 6f 6e 73 65 45 78 74 65 6e 73 69 6f 6e 73 a1 00 00 00 d2 84 0a 00 00 a3 81 69 00 15 11 52 65 73 70 6f 6e 73 65 45 78 74 65 6e 73 69 6f 6e a3 84 0b 00 09 c1 c6 81 90 80 86 e7 ff fe a3 84 57 00 15 23 52 65 71 75 65 73 74 20 53 65 74 56 61 72 69 61 62 6c 65 53 75 62 72 61 6e 67 65 53 74 72 65 61 6d 65 64 a3 84 0c 00 01 00 a3 84 0d 00 01 00 a3 84 0e 00 04 87 1b a3 84 0f 00 04 00 a3 84 10 00 04 00 a3 84 12 00 04 00 a3 84 13 00 04 00 a3 84 15 00 04 00 a2 a2 00 00 00 00
DEBUG:s7.connection:  Response header: opcode=0x32 function=0x057C seq=5 session=0x36E1C691 transport=0x90
DEBUG:s7.connection:  Response payload (181 bytes): 80 86 e7 ff fe 05 a1 00 00 00 d2 84 08 00 00 a3 81 69 00 15 12 52 65 73 70 6f 6e 73 65 45 78 74 65 6e 73 69 6f 6e 73 a1 00 00 00 d2 84 0a 00 00 a3 81 69 00 15 11 52 65 73 70 6f 6e 73 65 45 78 74 65 6e 73 69 6f 6e a3 84 0b 00 09 c1 c6 81 90 80 86 e7 ff fe a3 84 57 00 15 23 52 65 71 75 65 73 74 20 53 65 74 56 61 72 69 61 62 6c 65 53 75 62 72 61 6e 67 65 53 74 72 65 61 6d 65 64 a3 84 0c 00 01 00 a3 84 0d 00 01 00 a3 84 0e 00 04 87 1b a3 84 0f 00 04 00 a3 84 10 00 04 00 a3 84 12 00 04 00 a3 84 13 00 04 00 a3 84 15 00 04 00 a2 a2 00 00 00 00
DEBUG:s7.connection:  Trailer (4 bytes): 72 03 00 00
ERROR:s7._s7commplus_client:_parse_read_response: PLC returned error: 1828716293
Traceback (most recent call last):
  File "\python-snap7-harpo-port-incomplete-cddb4db\main.py", line 8, in <module>
    print("db_read: ", client.db_read(7, 0, 2).hex())
                       ~~~~~~~~~~~~~~^^^^^^^^^
  File "\python-snap7-harpo-port-incomplete-cddb4db\s7\_s7commplus_client.py", line 129, in db_read
    raise RuntimeError("Read returned no data")
RuntimeError: Read returned no data

cddb4db.zip

…EAMED format

Two issues with the legitimation flow:
1. Challenge source: should come from GET_VAR_SUBSTREAMED to address
   303 (ServerSessionRequest) on the session object, not from the
   DEADBEEF blob or the session challenge from CreateObject
2. SET_VAR_SUBSTREAMED payload: needs 0x20 0x04 prefix and extra
   0x00 in BLOB encoding, matching the HarpoS7 PoC template
@gijzelaerr
Copy link
Copy Markdown
Owner Author

@xBiggs 0b9a088 fixes two issues with the legitimation:

  1. Wrong challenge source — was using the session challenge from CreateObject. Now reads the legitimation challenge from GET_VAR_SUBSTREAMED at address 303 (matching the HarpoS7 PoC)
  2. Wrong SET_VAR_SUBSTREAMED format — now matches the PoC template (0x20 0x04 prefix, extra 0x00 in BLOB encoding)
pip install --force-reinstall git+https://github.com/gijzelaerr/python-snap7.git@research/harpo-port-incomplete

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Research: S7CommPlus session-key handshake (P2/P3) on V1-initial S7-1200 S7-1200 Session Setup Incomplete

3 participants