@@ -148,6 +148,11 @@ the map already scanned.
148148- ** Warnings, never silence** — unreadable files, unsupported languages and
149149 permission problems show up as ⚠ badges and in the warnings list, never
150150 hidden. Secrets found in config files are always masked.
151+ - ** De-obfuscation, inline** — hex/octal escapes, ` chr() ` -style
152+ character-code math, base64 blobs, and dead "chaff" statements get
153+ statically decoded and highlighted right in the code viewer — hover a
154+ 🔓-underlined span to see what it originally said. See
155+ [ De-obfuscation] ( #de-obfuscation ) below.
151156
152157## Language support
153158
@@ -184,6 +189,51 @@ Only Python's `ast`-based parser captures real parameter type annotations,
184189return types, and docstrings — every regex-based parser above extracts
185190parameter * names* only.
186191
192+ ## De-obfuscation
193+
194+ Some codebases — commercial/nulled PHP scripts especially — ship with
195+ constant-literal obfuscation: hex/octal escape sequences, ` chr() ` -style
196+ character-code arithmetic, base64-encoded string constants, and dead
197+ "chaff" statements built and thrown away purely to make the file harder to
198+ read. CodeBread finds and decodes these ** statically** and highlights the
199+ decoded value inline in the code viewer (dashed underline — hover to see
200+ the original), plus a 🔓 badge on any file with findings.
201+
202+ ** The one rule that matters: nothing here is ever executed.** Every
203+ decoder in [ ` codebread/deobfuscate.py ` ] ( codebread/deobfuscate.py ) only
204+ resolves * constant* expressions — integer literals combined with
205+ ` + - * / % << >> | & ^ ` , inside a recognized decode call (` chr(...) ` ,
206+ ` base64_decode(...) ` , ...). A restricted AST walker
207+ (` safe_eval_int_expr ` ) is the enforcement point: if an expression touches
208+ a variable, a function call, a float, or anything else that isn't a bare
209+ integer literal or one of those operators, it's refused and left alone —
210+ never guessed at, never evaluated by actually running the target
211+ language. That's what makes it safe to point at code you don't trust yet,
212+ which is the same posture as the rest of CodeBread (read-only static
213+ analysis, nothing scanned is ever run).
214+
215+ | Language | Hex ` \xHH ` | Octal ` \NNN ` | Unicode ` \uHHHH ` / ` \u{HHHH} ` | Char-code math | Base64 literals | Dead "chaff" statements |
216+ | ---| :---:| :---:| :---:| :---:| :---:| :---:|
217+ | Python | ✅ | ✅ | ✅ ` \uHHHH ` | ✅ ` chr(...) ` | ✅ ` base64.b64decode(...) ` | –³ |
218+ | JavaScript / TypeScript / Vue / Svelte | ✅ | ✅ | ✅ both forms | ✅ ` String.fromCharCode ` / ` fromCodePoint ` | ✅ ` atob(...) ` | ✅ (` + ` concat) |
219+ | Java | – | ✅ | ✅ ` \uHHHH ` | ✅ ` (char)(...) ` cast | ✅ ` Base64.getDecoder().decode(...) ` | ✅ (` + ` concat) |
220+ | C# | ✅ | – | ✅ ` \uHHHH ` | ✅ ` (char)(...) ` cast | ✅ ` Convert.FromBase64String(...) ` | ✅ (` + ` concat) |
221+ | Go | ✅ | ✅ | ✅ ` \uHHHH ` | ✅ ` string(rune(...)) ` | ✅ ` base64.StdEncoding.DecodeString(...) ` | ✅ (` + ` concat) |
222+ | PHP | ✅ | ✅ | ✅ ` \u{HHHH} ` only | ✅ ` chr(...) ` | ✅ ` base64_decode(...) ` | ✅ (` . ` concat) |
223+ | Ruby | ✅ | ✅ | ✅ both forms | ✅ ` <int>.chr ` | ✅ ` Base64.decode64(...) ` | –³ |
224+
225+ Decoded base64 output is re-checked against the same credential-masking
226+ rule used on config files (` URL_CREDS_RE ` ) — revealing a hidden literal
227+ can't be used to route around the "credentials always masked" guarantee
228+ elsewhere in the tool.
229+
230+ ³ Chaff detection needs a reliable statement boundary to prove "this
231+ literal chain is the * entire* statement, nothing else on either side" —
232+ the ` ; ` -terminated languages above have one. Python and Ruby don't require
233+ a terminator, so v1 intentionally reports nothing there rather than guess
234+ and risk false positives; the escape/char-code/base64 decoders still work
235+ fully on both.
236+
187237## How it classifies layers
188238
189239Score-based heuristics combining framework import signatures
0 commit comments