Skip to content

Commit 322e44d

Browse files
committed
updating CLAUDE.md
1 parent 60d3522 commit 322e44d

1 file changed

Lines changed: 21 additions & 13 deletions

File tree

CLAUDE.md

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,29 @@ Looks for `byte[]` and `int[]` fields initialised with a `FilledNewArrayNode` of
5353

5454
### Detection logic (`B64Detector`)
5555

56-
`B64Detector.detect(String, B64DeobfuscateOptions)` applies a pipeline of filters (all thresholds configurable via options):
56+
`B64Detector.detect(String, B64DeobfuscateOptions)` runs an ordered pipeline (all thresholds configurable via options). The pre-decode filters live in the `INPUT_FILTERS` array and short-circuit on the first rejection:
5757

5858
1. Blocklist check (`B64FalsePositives`) — known false positives (e.g. Android class names) rejected first
59-
2. Minimum encoded length (`minInputLength`, default 8)
60-
3. Require valid Base64 length (`requireValidLength`, default false) — total length must be divisible by 4
61-
4. Skip camelCase identifiers (`skipCamelCase`, default true) — rejects strings matching `^[a-z]+([A-Z][a-z]+)+$` under 40 chars
62-
5. Charset validation — must match standard or URL-safe Base64 alphabet
63-
6. Attempt decode with `Base64.getDecoder()`, then `Base64.getUrlDecoder()`; MIME decoder used if string contains `\n`/`\r`
64-
7. Strict UTF-8 decode (`CodingErrorAction.REPORT`)
65-
8. Minimum printable-ASCII ratio (`minPrintablePercent`, default 90%)
66-
9. Minimum alphanumeric ratio (`minAlphanumericPercent`, default 35%)
67-
10. Minimum decoded length (`minDecodedLength`, default 0 = disabled)
68-
11. Truncation (`maxCommentLength`, default 100; 0 = unlimited)
69-
70-
`B64Detector.decodeForced(String, int)` skips steps 1–9 and uses `CodingErrorAction.REPLACE` instead of `REPORT`. Used when the string is an explicit arg to a `Base64.decode` call.
59+
2. Valid Base64 length (`requireValidLength`, default true) — length *excluding* `\n`/`\r` must be divisible by 4 (line breaks are stripped via `significantLength` so PEM/MIME-wrapped strings aren't rejected for their wrapping)
60+
3. Identifier-shape skips, only applied to strings under 40 chars:
61+
- `skipCamelCase` (default true) — `^[a-z]+([A-Z][a-z]+)+$`
62+
- `skipPascalCase` (default true) — `^[A-Z][a-z]+([A-Z][a-z0-9]+)+$`
63+
- `skipSnakeCase` (default true) — all-caps (`FOO_BAR`) or all-lower (`foo_bar`)
64+
- `skipDictionaryWords` (default true) — every camelCase/underscore segment is a known word (`B64DictionaryFilter` / `words.txt`)
65+
4. Charset validation — must match the standard or URL-safe Base64 alphabet (`\n`/`\r` permitted)
66+
67+
Then decode and apply post-decode heuristics:
68+
69+
5. Decode with `Base64.getDecoder()`, then `Base64.getUrlDecoder()`; the MIME decoder is also tried when the string contains `\n`/`\r`
70+
6. Strict UTF-8 decode (`CodingErrorAction.REPORT`)
71+
7. Minimum printable-ASCII ratio (`minPrintablePercent`, default 90%)
72+
8. Minimum alphanumeric ratio (`minAlphanumericPercent`, default 35%)
73+
9. Minimum decoded length (`minDecodedLength`, default 4; 0 = disabled)
74+
10. Truncation (`maxCommentLength`, default 100; 0 = unlimited)
75+
76+
Two helpers bypass parts of the pipeline:
77+
- `B64Detector.decodeForced(String, int)` — skips all charset and heuristic filters and uses `CodingErrorAction.REPLACE` instead of `REPORT`. Used when the string is an explicit arg to a `Base64.decode`-like call (recognised by `B64DecodeCalls.isDecodeCall`).
78+
- `B64Detector.decodeIfValid(String, int)` — applies only the charset check + strict UTF-8 decode, no heuristic filters. Used for sibling array elements once one element in the array has passed full detection (the "anchor").
7179

7280
### False-positive prevention
7381

0 commit comments

Comments
 (0)