fe2a6db786
rust / build / test / clippy / fmt (push) Has been cancelled
Layout:
- src/ .NET 10 x64 reference: MxNativeCodec, MxNativeClient,
MxAsbClient, probes, tests, harnesses. Executable spec.
- design/ Architectural plan for the Rust port (M0–M6), error
model, protocol invariants, risks (R1–R16), adversarial
review log (review.md).
- rust/ Rust workspace. M0 skeleton + M1 codec parity.
mxaccess-codec: 215 unit tests + 2 cross-implementation
parity tests (byte-identical against .NET reference).
Other crates are M0 stubs awaiting M2+.
- captures/ Frida + netsh + pcap evidence per CLAUDE.md
("captures are evidence, not throwaway logs").
- analysis/ Decompiled C# (frida/proxy/decompiled-*),
Ghidra exports for native DLLs (`exports/` only —
working state at `projects/` and AVEVA's input
binaries at `input/` are gitignored).
- docs/ Reverse-engineering reference docs.
- tools/ Setup-LiveProbeEnv.ps1 (Infisical credential fetcher),
Compute-Crc.ps1 (.NET parity helper).
- .github/workflows/ Rust CI: fmt + build + test + clippy on Windows.
- LICENSE MIT (Joseph Doherty, 2026).
Verified:
- cargo test --workspace → 217 passed (215 unit + 2 .NET parity), 0 failed
- cargo clippy --workspace -- -D warnings → clean
- cargo fmt --all -- --check → clean
- cargo publish --dry-run -p mxaccess-codec → packages cleanly
Excluded from history (see .gitignore):
- **/bin, **/obj, **/target — build artifacts
- analysis/ghidra/projects/ — Ghidra working state (regenerable)
- analysis/ghidra/input/ — AVEVA proprietary DLLs (vendor IP)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
153 lines
4.9 KiB
SQL
153 lines
4.9 KiB
SQL
/*
|
|
Find deployed runtime attributes with security classifications that should
|
|
exercise LMXProxy WriteSecured / WriteSecured2 paths.
|
|
|
|
Connection:
|
|
sqlcmd -S localhost -d ZB -E -i analysis/sql/select_secured_write_candidates.sql
|
|
*/
|
|
SET NOCOUNT ON;
|
|
|
|
;WITH deployed_package_chain AS (
|
|
SELECT
|
|
g.gobject_id,
|
|
p.package_id,
|
|
p.derived_from_package_id,
|
|
0 AS depth
|
|
FROM gobject g
|
|
INNER JOIN package p
|
|
ON p.package_id = g.deployed_package_id
|
|
WHERE g.is_template = 0
|
|
AND g.deployed_package_id <> 0
|
|
UNION ALL
|
|
SELECT
|
|
dpc.gobject_id,
|
|
p.package_id,
|
|
p.derived_from_package_id,
|
|
dpc.depth + 1
|
|
FROM deployed_package_chain dpc
|
|
INNER JOIN package p
|
|
ON p.package_id = dpc.derived_from_package_id
|
|
WHERE dpc.derived_from_package_id <> 0
|
|
AND dpc.depth < 10
|
|
),
|
|
ranked_dynamic AS (
|
|
SELECT
|
|
dpc.gobject_id,
|
|
g.tag_name,
|
|
CAST('' AS nvarchar(255)) AS primitive_name,
|
|
da.attribute_name,
|
|
g.tag_name + '.' + da.attribute_name
|
|
+ CASE WHEN da.is_array = 1 THEN '[]' ELSE '' END AS full_tag_reference,
|
|
da.mx_data_type,
|
|
dt.description AS data_type_name,
|
|
da.is_array,
|
|
CASE WHEN da.is_array = 1
|
|
THEN CONVERT(int, CONVERT(varbinary(2),
|
|
SUBSTRING(da.mx_value, 15, 2) + SUBSTRING(da.mx_value, 13, 2), 2))
|
|
ELSE NULL
|
|
END AS array_dimension,
|
|
da.mx_attribute_category,
|
|
da.security_classification,
|
|
CAST('dynamic' AS varchar(16)) AS attribute_source,
|
|
ROW_NUMBER() OVER (
|
|
PARTITION BY dpc.gobject_id, da.attribute_name
|
|
ORDER BY dpc.depth
|
|
) AS rn
|
|
FROM deployed_package_chain dpc
|
|
INNER JOIN dynamic_attribute da
|
|
ON da.package_id = dpc.package_id
|
|
INNER JOIN gobject g
|
|
ON g.gobject_id = dpc.gobject_id
|
|
INNER JOIN template_definition td
|
|
ON td.template_definition_id = g.template_definition_id
|
|
LEFT JOIN data_type dt
|
|
ON dt.mx_data_type = da.mx_data_type
|
|
WHERE td.category_id IN (1, 3, 4, 10, 11, 13, 17, 24, 26)
|
|
AND da.attribute_name NOT LIKE '[_]%'
|
|
AND da.attribute_name NOT LIKE '%.Description'
|
|
AND da.mx_attribute_category IN (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 24)
|
|
),
|
|
all_attributes AS (
|
|
SELECT
|
|
g.gobject_id,
|
|
g.tag_name,
|
|
pi.primitive_name,
|
|
ad.attribute_name,
|
|
CASE WHEN pi.primitive_name = ''
|
|
THEN g.tag_name + '.' + ad.attribute_name
|
|
ELSE g.tag_name + '.' + pi.primitive_name + '.' + ad.attribute_name
|
|
END + CASE WHEN ad.is_array = 1 THEN '[]' ELSE '' END AS full_tag_reference,
|
|
ad.mx_data_type,
|
|
dt.description AS data_type_name,
|
|
ad.is_array,
|
|
CASE WHEN ad.is_array = 1
|
|
THEN CONVERT(int, CONVERT(varbinary(2),
|
|
SUBSTRING(ad.mx_value, 15, 2) + SUBSTRING(ad.mx_value, 13, 2), 2))
|
|
ELSE NULL
|
|
END AS array_dimension,
|
|
ad.mx_attribute_category,
|
|
ad.security_classification,
|
|
CAST('primitive' AS varchar(16)) AS attribute_source
|
|
FROM gobject g
|
|
INNER JOIN instance i
|
|
ON i.gobject_id = g.gobject_id
|
|
INNER JOIN template_definition td
|
|
ON td.template_definition_id = g.template_definition_id
|
|
AND td.runtime_clsid <> '{00000000-0000-0000-0000-000000000000}'
|
|
INNER JOIN package p
|
|
ON p.package_id = g.deployed_package_id
|
|
INNER JOIN primitive_instance pi
|
|
ON pi.package_id = p.package_id
|
|
AND pi.property_bitmask & 0x10 <> 0x10
|
|
INNER JOIN attribute_definition ad
|
|
ON ad.primitive_definition_id = pi.primitive_definition_id
|
|
AND ad.attribute_name NOT LIKE '[_]%'
|
|
AND ad.mx_attribute_category IN (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 24)
|
|
LEFT JOIN data_type dt
|
|
ON dt.mx_data_type = ad.mx_data_type
|
|
WHERE td.category_id IN (1, 3, 4, 10, 11, 13, 17, 24, 26)
|
|
AND g.is_template = 0
|
|
AND g.deployed_package_id <> 0
|
|
|
|
UNION ALL
|
|
|
|
SELECT
|
|
gobject_id,
|
|
tag_name,
|
|
primitive_name,
|
|
attribute_name,
|
|
full_tag_reference,
|
|
mx_data_type,
|
|
data_type_name,
|
|
is_array,
|
|
array_dimension,
|
|
mx_attribute_category,
|
|
security_classification,
|
|
attribute_source
|
|
FROM ranked_dynamic
|
|
WHERE rn = 1
|
|
)
|
|
SELECT TOP (100)
|
|
full_tag_reference,
|
|
data_type_name,
|
|
mx_data_type,
|
|
is_array,
|
|
array_dimension,
|
|
security_classification,
|
|
CASE security_classification
|
|
WHEN 2 THEN 'SecuredWrite'
|
|
WHEN 3 THEN 'VerifiedWrite'
|
|
ELSE 'Other'
|
|
END AS security_name,
|
|
mx_attribute_category,
|
|
attribute_source
|
|
FROM all_attributes
|
|
WHERE security_classification IN (2, 3)
|
|
AND mx_data_type IN (1, 2, 3, 4, 5, 6, 7)
|
|
ORDER BY
|
|
CASE WHEN tag_name LIKE 'Test%' OR tag_name LIKE '%Test%' THEN 0 ELSE 1 END,
|
|
security_classification,
|
|
is_array,
|
|
full_tag_reference
|
|
OPTION (MAXRECURSION 20);
|