Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6670f16
Relocations high-adj work
malx-labs Aug 31, 2026
1460d72
tls parser reason-code documentation review
malx-labs Aug 31, 2026
f36b82d
Delay-load import DLL name regex tighening and mutually exclusive rea…
malx-labs Aug 31, 2026
74786f3
Debug parser documentation addtions following review
malx-labs Aug 31, 2026
117b15f
Add closing paragraph sentence
malx-labs Aug 31, 2026
0f7c630
Add missing rva_zero and empty_read error codes to exports validator.
malx-labs Aug 31, 2026
ad5c0c7
Exports tests to bring project coverage to 100%
malx-labs Aug 31, 2026
ca384fc
Initial commit of imports parser, validator, tests and documentation
malx-labs Sep 1, 2026
1ab1835
Fill in tests for imports parser and validator. Coverage back at 100%
malx-labs Sep 1, 2026
7fb7a30
Static tag testing. Six pairs of parsers/validators are tested static…
malx-labs Sep 1, 2026
bac4b90
Remove _index tombstone suffix, defaulting to a hard non-suffixed code
malx-labs Sep 1, 2026
915219a
Update documentation: tag-contract
malx-labs Sep 1, 2026
3cd8b53
Certificates parser/validator pair now tag-contract tested. This comm…
malx-labs Sep 1, 2026
696963f
Add exception directory pair to tag contract test. Resulted in removi…
malx-labs Sep 2, 2026
5abf4a6
Fix tag contract script, and write tests for it
malx-labs Sep 2, 2026
fedcf6e
Pe_resources tag contract pair added. This resulted in an analysis of…
malx-labs Sep 2, 2026
5d9a1e5
Add crash handling to pe_resources and tighten tests
malx-labs Sep 2, 2026
8a00492
Version info tag contract pairs added, resulted in validator refactor…
malx-labs Sep 2, 2026
888edf5
Pe_version_info: Hard cap on children walked
malx-labs Sep 2, 2026
71c8f34
(chore)Pe_parser: Remove base64, _shannon entropy imports. Rename str…
malx-labs Sep 2, 2026
319add3
Since ddir offset bug fix, update contract test that was inflating a…
malx-labs Sep 2, 2026
4da7bb2
Add a test to ensure analysis sections retain raw_address and virtual…
malx-labs Sep 2, 2026
e69458c
Add load_config and optional_header tag contract pairs: the checker d…
malx-labs Sep 2, 2026
3a03db6
Tidy up test_tag_contract notes. All parsers/validators now have tag …
malx-labs Sep 2, 2026
bed3c13
Pe_parser bounds checking
malx-labs Sep 2, 2026
75a8e47
Add _PARSERLESS_VALIDATORS and _TAGLESS_PARSERS to test_tag_contract
malx-labs Sep 2, 2026
194a9f3
Final version of test_tag_contract
malx-labs Sep 2, 2026
e8f5000
_Parse_resources return object has changed shape, so fixed tests to r…
malx-labs Sep 7, 2026
6a82557
Add resources_string tests to pe_parser and document additional tombs…
malx-labs Sep 7, 2026
bac6d52
Add bounds checks for rva, size in pe_version_info
malx-labs Sep 7, 2026
37b72bf
Pre-version info reason reorder
malx-labs Sep 7, 2026
c391a0e
Version-info metadata addition to snapshots
malx-labs Sep 8, 2026
cbc9dad
Add clean_version_info fixtures (core and full) and snapshots. Four t…
malx-labs Sep 8, 2026
52d60c0
Version info projection
malx-labs Sep 8, 2026
2d0f216
Version info projection tests
malx-labs Sep 8, 2026
2621d7d
Version info reason code additions
malx-labs Sep 8, 2026
35b3b64
Bump version. CLI version now includes art and provenance. Help menu …
malx-labs Sep 8, 2026
a06dc4e
Fix CLI unit test
malx-labs Sep 9, 2026
402d413
Fix vi fuzz tests
malx-labs Sep 9, 2026
93fe959
v0.7.6.2 release documentation
malx-labs Sep 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,96 @@
# **v0.7.6.2 — Import Table Structural Validator, and VERSIONINFO projection**
**Released: 2026‑09‑09**

## Added
- Import table structural validator: new `pe_imports` parser
(`iocx/parsers/pe_imports.py`) and `imports` validator
(`iocx/validators/imports.py`) emitting `IMPORT_DIRECTORY_INVALID_HEADER`,
`IMPORT_TABLE_TRUNCATED`, `IMPORT_DESCRIPTOR_INVALID`,
`IMPORT_DLL_NAME_INVALID`, `IMPORT_ENTRY_INVALID`.
- Public `version_info` projection (`version_info_projection.py`),
present in every result at every analysis level; closed 8-key
shortlist by default (`CompanyName`, `FileDescription`, `FileVersion`,
`InternalName`, `LegalCopyright`, `OriginalFilename`, `ProductName`,
`ProductVersion`), open key set under `-a full`.
- New reason codes: `RESOURCE_DIRECTORY_ENTRY_UNREADABLE`,
`RESOURCE_STRING_TABLE_UNREADABLE`.
- Branded `--version` CLI output (ASCII art shown only on an interactive
terminal) including `python` and `pefile` dependency versions.
- Static tag-contract CI check (`tests/contract/tag_contract.py`,
`test_tag_contract.py`) statically verifying every parser tombstone
tag has a validator consumer, closing a class of silent-drop bugs.
- `HIGHADJ` relocation-entry pairing support: new `adjustment` field on
paired entries, `highadj_missing_adjustment` tombstone for an unpaired
trailing entry.
- Bounds on resource-tree output (`_MAX_RESOURCE_STRINGS`,
`_MAX_RESOURCE_ENTRIES`, `_MAX_RESOURCE_DEPTH`) and on version-info
blob size (1 MB) / child count (256), so hostile input can no longer
scale parser output or recursion depth.
- New VS_VERSIONINFO test fixture generator and
matching C/RC fixture pair for end-to-end version-info coverage.

## Changed
- `build_version_info` renamed to `build_version_info_structure`; now
called unconditionally in the engine pipeline instead of only under
`-a full`.
- CLI: `-m/--min-length` moved from Detector Options to Engine Options;
`-a/--analyse` help text now documents what each analysis level
unlocks; `--list-transformers`/`--list-enrichers` help text made
consistent with `--list-detectors`.
- Delay-import and export-forwarder validation split into distinct
empty / non-printable / too-long checks instead of a single boolean,
each with its own reason-code sub-reason.
- `RELOCATION_TABLE_TRUNCATED` region values split into
`relocation_entries_exceed_directory` (declared size clamped to the
directory window) vs. `relocation_entries_truncated` (the clamped
read itself came back short) — previously conflated under one tag.
- `_MAX_ENTRIES_PER_BLOCK` corrected to 8,192 (previously documented and
sized for 2,048) to account for `HIGHADJ` occupying two WORD slots
per relocation.
- Machine-specific relocation type 9 renamed `MIPS_JMPADDR16` →
`MACHINE_SPECIFIC_9` for architecture-neutral naming.

## Fixed
- `NameError` on `_RELOC_TYPE_HIGHADJ`, reachable from decoding *any*
relocation entry (not only `HIGHADJ` ones), capable of aborting an
entire analysis on a single malformed entry.
- `_parse_data_directories_raw` read PE32+ images at the PE32 (96-byte)
rather than the correct 112-byte `DataDirectory` offset, silently
misreading every data directory on a 64-bit image; now also tolerates
a missing/empty `__data__` and a truncated optional header without
raising.
- Export forwarder-string decode errors were discarded rather than
surfaced on the entry; `name_rva` was hard-coded `None` instead of
being resolved via the name-pointer cross-reference; two name
pointers resolving to the same EAT index silently overwrote one
another (now tagged `ordinal_index_duplicate`).
- Forwarder regex accepted over-long ordinals (e.g.
`Dll.#99999999999`) as ordinary symbol names.
- `pe_resources.build_resource_structure` and `pe_parser._parse_resources`
could propagate an exception, or silently drop entries, on a malformed
subtree; both now tombstone the failure (`entry_decode_failed`,
`directory_entries_unavailable`, `string_table_walk_failed`,
`resources_unavailable`, `resources_map_read_failed`) and never raise.
- Per-index parser tags (`*_unpack_failed_at_{index}`) that never
matched any validator priority list, because the embedded index made
every occurrence unique, deduplicated to a stable form.

## Documentation
- `docs/specs/reason-codes.md`: new **Import Anomalies** section, new
**Resource Directory Entry Unreadable** section, expanded TLS /
delay-import / export / relocation / debug sub-reason tables.
- `docs/specs/structural-validation-deterministic-heuristics.md`: new
**§2.16 Imports Validator** section; documents the tag-contract check.

## Testing
- Test suite: **2,136 → 2,802 tests.** Major new coverage for the
import parser/validator, the version-info projection, resource-tree
robustness, relocation `HIGHADJ` handling, and the tag-contract
checker itself (including deliberate regression fixtures for eight
previously-found silent-drop bugs).

---

# **v0.7.6.1 — Exception Directory Validator, and a Silent Output Defect**
**Released: 2026‑08‑27**

Expand Down
18 changes: 11 additions & 7 deletions README-pypi.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,24 @@ If you need predictable, automatable IOC extraction — IOCX is built for you.

---

## Version highlights

### v0.7.6.2 — Import Table Validator

- New deterministic **import table structural validator** (`IMPORT_*` reason codes).
- `version_info` now parsed and surfaced at **every** analysis level (not just `-a full`), via a new bounded public projection.
- Rebuilt CLI: branded `--version` output, clearer `--help` text, reorganised argument groups.
- Fixed a relocation-parser crash reachable from any entry, a PE32+ data-directory offset bug, and several silent export/resource error drops.
- New static CI check that prevents parser error tags from silently going unconsumed by validators.
- Test suite: 2,136 → 2,802 tests. Coverage: 100%.

### v0.7.6.1 — Exception Directory Validator

- Adds deep semantic validation of the PE exception (`.pdata`) directory; 14 new reason codes; 15 validators total.
- Fixes a defect that had been suppressing structural findings across the engine.
- **Output-visible:** findings previously suppressed or mislabelled will now appear.
- Tests: 1620 → 2136. Coverage: 100%.

## Version highlights (v0.7.6)

- Added new PE structural validators for relocations and debug directories
- WIN_CERTIFICATE and tls validators now have pefile-independent struct parsers
- Never crashes on malformed input - byte-level parsing with structured error tombstones
- 1620 tests at 100% coverage - deterministic output, snapshot-stable

---

## **Performance**
Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<p align="center">
<a href="https://pypi.org/project/iocx/"><img src="https://img.shields.io/pypi/v/iocx?logo=pypi&logoColor=white"></a>
<img src="https://img.shields.io/badge/tests-2136_passed-brightgreen">
<img src="https://img.shields.io/badge/tests-2802_passed-brightgreen">
<img src="https://img.shields.io/badge/coverage-100%25-brightgreen">
<img src="https://img.shields.io/badge/python-3.12-blue">
<a href="https://github.com/iocx-dev/iocx/actions"><img src="https://img.shields.io/github/actions/workflow/status/iocx-dev/iocx/ci.yml?label=build"></a>
Expand Down Expand Up @@ -202,6 +202,17 @@ Fast path — no PE parsing.
<summary><strong>Show Version History</strong></summary>
<br>

### v0.7.6.2 — Import Table Validator

- New deterministic **import table structural validator** (`IMPORT_*` reason codes).
- `version_info` now parsed and surfaced at **every** analysis level (not just `-a full`), via a new bounded public projection.
- Rebuilt CLI: branded `--version` output, clearer `--help` text, reorganised argument groups.
- Fixed a relocation-parser crash reachable from any entry, a PE32+ data-directory offset bug, and several silent export/resource error drops.
- New static CI check that prevents parser error tags from silently going unconsumed by validators.
- Test suite: 2,136 → 2,802 tests.

---

### v0.7.6.1 — Exception Directory Validator

- Adds deep semantic validation of the PE exception (`.pdata`) directory; 14 new reason codes; 15 validators total.
Expand Down
Loading
Loading