Max-Eee/NeoPass · error · Error

You bad!

Error message

You bad!

What it means

This library hooks window.Function.prototype.constructor and intercepts any dynamic function whose source contains a 'debugger' statement — a common anti-debugging trick used by scripts to break DevTools. Normally it silently strips the debugger statement out, but it keeps a rolling counter (debugCount) that increments on each detection and decays via setTimeout after 1ms. If more than 100 debugger-bearing functions are constructed within that window, it throws new Error("You bad!") as an explicit signal that aggressive anti-debugging code is running.

Source

Thrown at data/inject/anti-anti-debug.js:128

    window.console.clear = wrapFn(() => {
        if (shouldLog("table")) {
        }
    }, Originals.clear);

    let debugCount = 0;
    window.Function.prototype.constructor = wrapFn((...args) => {
        const originalFn = Originals.functionConstructor.apply(this, args);
        var fnContent = args[0];
        if (fnContent) {
            if (fnContent.includes('debugger')) { // An anti-debugger is attempting to stop debugging
                if (shouldLog("debugger")) {
                }
                debugCount++;
                if (debugCount > 100) {
                    if (shouldLog("debuggerThrow")) {
                    }
                    throw new Error("You bad!");
                } else {
                    setTimeout(() => {
                        debugCount--;
                    }, 1);
                }
                const newArgs = args.slice(0);
                newArgs[0] = args[0].replaceAll("debugger", ""); // remove debugger statements
                return new Proxy(Originals.functionConstructor.apply(this, newArgs),{
                    get: function (target, prop) {
                        if (prop === "toString") {
                            return originalFn.toString;
                        }
                        return target[prop];
                    }
                });
            }
        }
        return originalFn;

View on GitHub (pinned to a0944782ce)

Solutions

  1. Remove or reduce debugger statements in dynamically constructed functions — the counter only triggers when they contain the literal substring 'debugger'.
  2. Space out or batch Function() constructions so fewer than 100 debugger-bearing calls occur before debugCount decays (setTimeout decrements it after ~1ms).
  3. Use eval or another evaluation path that does not go through the patched Function.prototype.constructor if you legitimately need debugger statements.
  4. In DevTools, use the 'Deactivate breakpoints' setting instead of emitting debugger statements from code.
  5. Patch or disable this injection script's throw at data/inject/anti-anti-debug.js:128 if it is your own tooling firing on benign code.

Example fix

// before
for (let i = 0; i < 500; i++) {
  new Function('debugger; return ' + i)();
}
// after
for (let i = 0; i < 500; i++) {
  new Function('return ' + i)(); // no 'debugger' substring, no counter increment
}
Defensive patterns

Strategy: try-catch

Validate before calling

const src = 'debugger; return 1';
// avoid the error entirely: strip the debugger substring before invoking the patched constructor
if (src.includes('debugger')) {
  src = src.replaceAll('debugger', '');
}
new Function(src);

Type guard

function isDebuggerFreeFnSource(src) {
  return typeof src === 'string' && !src.includes('debugger');
}

Try / catch

try {
  const fn = new Function(source);
} catch (e) {
  if (e && e.message === 'You bad!') {
    // anti-anti-debug guard tripped: strip debugger statements and retry
    const fn2 = new Function(source.replaceAll('debugger', ''));
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Constructing more than 100 functions via new Function(...) or Function(...) whose source text includes the substring 'debugger' within a ~1ms decay window (debugCount > 100). Example: new Function('debugger; return 1') called in a tight loop, or any obfuscation/bundler-generated code that repeatedly emits debugger statements through the patched Function constructor.

Common situations: Running the page with this anti-anti-debug injection active while a site's own obfuscated anti-debugging loop (e.g. the classic setInterval + Function('debugger') guard) fires rapidly; bundling/minifying code that contains many debugger statements; leaving leftover debugger statements in production code; debugging tools or test harnesses that dynamically build functions containing 'debugger'.


AI-assisted analysis of Max-Eee/NeoPass@a0944782ce (2026-08-31). Data as JSON: /api/errors/7dd3b46cbbe1137f. Report an issue: GitHub.