frames,jar,passes: verifier-driven hardening from real jars
Proven by paranoid runs over lorep (17 classes, fully green), LoVisual (4081 classes) and oc2r (1278 classes) with per-class java -Xverify:all, each fix first reproduced as a red test: - merge: Top absorbs instead of Top-wins (javac declares Top for slots unwritten on some inflow; precise types reject those edges). Regression: loop_head_keeps_top_for_loop_local. - emit: collapse [Long|Double, Top] pairs on operand stacks (javac writes one entry; the pair is rejected). Regression: wide_stack_join_emits_single_entries. - xfer ArrayLoad: push the wide pair, fixing lcmp underflow. Regression: array_load_wide_pushes_pair. - xfer <init>: convert only the receiver's own allocation site instead of every Uninitialized (nested construction clobbered the outer object). Regression: nested_construction_keeps_outer. - xfer ANewArray: array operands gain one dimension ([B] -> [[B) instead of an illegal L-wrap ([L[B;). Covered by the same test. - jar load: duplicate class names (multi-release module-info twins) keep the first occurrence instead of crashing save. Test: duplicate_class_names_keep_first. - strings/constants: skip methods past MAX_METHOD_INSNS (8000) so giants cannot overflow the 64KB writer ceiling. Tests: oversized_methods_are_skipped in both passes. - merge errors now name both types being merged. Also: em-dash removed repo-wide (724 spots, rule added to todo.md), allow-lints only in tests (scratch example deleted), code comments migrated to English in every file this change touches.
This commit is contained in:
parent
2172206e83
commit
139aea9a8f
96 changed files with 1053 additions and 831 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# Документация noxis
|
||||
|
||||
Обфускатор JVM/Java-байткода на Rust. Этот файл — индекс.
|
||||
Обфускатор JVM/Java-байткода на Rust. Этот файл - индекс.
|
||||
|
||||
## Что где
|
||||
|
||||
|
|
@ -10,34 +10,34 @@
|
|||
| [`techniques.md`](techniques.md) | как работает каждая техника + плюсы/минусы/цена |
|
||||
| [`stack.md`](stack.md) | почему свой IR, какой backend, `StackMapTable`, PRNG, генерация рантайма |
|
||||
| [`learnings/lessons.md`](learnings/lessons.md) | уроки из разбора EvoVis: что защита сделала плохо и чего мы не делаем |
|
||||
| [`learnings/reference.md`](learnings/reference.md) | разбор референсного обфускатора (Java/ASM) — что берём, что нет |
|
||||
| [`learnings/reference.md`](learnings/reference.md) | разбор референсного обфускатора (Java/ASM) - что берём, что нет |
|
||||
| [`learnings/priorities.md`](learnings/priorities.md) | что улучшим: стратегия и приоритеты |
|
||||
| [`learnings/ai-resistance.md`](learnings/ai-resistance.md) | новые техники обфускации и устойчивость к LLM-анализу |
|
||||
|
||||
План выполнения — [`../todo.md`](../todo.md). Исходный материал разбора —
|
||||
План выполнения - [`../todo.md`](../todo.md). Исходный материал разбора -
|
||||
[`../info/`](../info/README.md).
|
||||
|
||||
## Структурные правила проекта
|
||||
|
||||
Правила — **только про Rust-код**: `crates/*/src`, `crates/*/tests`,
|
||||
Правила - **только про Rust-код**: `crates/*/src`, `crates/*/tests`,
|
||||
`crates/*/benches`. Документация (`docs/**`, корневые `.md`) и `info/` вне
|
||||
гейта: писать подробно там, где это документация, а не ограничивать объём
|
||||
искусственно. Не учитываются также `Cargo.lock`, `.gitignore`, корень крейта
|
||||
(в нём всегда лежат `Cargo.toml` + `build.rs`).
|
||||
|
||||
1. **Не больше 250 строк кода** в одном `.rs` файле. Пустые строки и
|
||||
полно-строчные комментарии (`//`, `///`, `//!`) не считаются —
|
||||
полно-строчные комментарии (`//`, `///`, `//!`) не считаются -
|
||||
измеряется объём кода, а не документации.
|
||||
2. **Не больше 4 `.rs`-файлов** в одной директории. Подпапки не ограничены:
|
||||
`src/` может содержать `lib.rs` и три модуля-директории, каждая из которых
|
||||
в свою очередь содержит не больше четырёх файлов.
|
||||
|
||||
`tests/` и `benches/` не исключены намеренно — иначе правило
|
||||
`tests/` и `benches/` не исключены намеренно - иначе правило
|
||||
«250 строк» обходится выносом кода в тесты.
|
||||
|
||||
Правило 2 — это не косметика: файл из тысячи строк означает, что в нём
|
||||
Правило 2 - это не косметика: файл из тысячи строк означает, что в нём
|
||||
смешаны разные причины к изменению (нарушение KISS/DRY/SOLID), а команда из
|
||||
восьми файлов в одной папке — что модуль перестал быть модулем.
|
||||
восьми файлов в одной папке - что модуль перестал быть модулем.
|
||||
|
||||
### Как проверяется
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ fn main() {
|
|||
|
||||
`noxis-structure-check` обходит деревья `src/`, `tests/` и `benches/` **этого
|
||||
крейта** и **падает со стопкой ошибок**, если лимит нарушен. Поэтому
|
||||
`cargo build` не соберёт нарушение — специально запускать проверку не нужно.
|
||||
`cargo build` не соберёт нарушение - специально запускать проверку не нужно.
|
||||
Деревья регистрируются через `cargo:rerun-if-changed`, чтобы гейт не
|
||||
срабатывал на правки вне проверяемых путей.
|
||||
|
||||
|
|
@ -64,9 +64,9 @@ fn main() {
|
|||
### Что делать при нарушении
|
||||
|
||||
- файл разрослся → разрезать по одной ответственности на файл:
|
||||
`mod.rs` = публичный контракт модуля, соседние файлы — внутренности;
|
||||
`mod.rs` = публичный контракт модуля, соседние файлы - внутренности;
|
||||
- папка переполнилась → завести подпапку и вынести подфункцию целиком,
|
||||
а не «чтобы влезло».
|
||||
|
||||
Каждый модуль получает `mod.rs` с `//!`-документацией — это точка входа,
|
||||
Каждый модуль получает `mod.rs` с `//!`-документацией - это точка входа,
|
||||
читающаяся вместо пяти файлов.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue