emi
emi

Reputation: 757

Is it possible to avoid breaking on a debugger statement in Chrome?

I'm trying to reverse engineer a heavily obfuscated JS and one of the tricks the author does is to continuously call the debugger statement from within an anonymous function:

demo

Unfortunately, I cannot right click and Never pause it, because each time the function is called a new anonymous function is spawned. The only way for me to inspect the code with DevTools open is to toggle the Disable all breakpoints button, but that disables my breakpoints too.

Is there any way to disable exclusively all debugger statements in Chrome?

In case there isnt, what could be done to bypass this anti-tampering trick?

Upvotes: 20

Views: 8805

Answers (3)

oriadam
oriadam

Reputation: 8539

Right-click the in the gutter on the line with the debugger statement and select "Never pause here".

enter image description here

Upvotes: 5

woxxom
woxxom

Reputation: 73506

This answer is for an old Chrome prior to 2021 where we could hack the internals of devtools itself by using devtools-on-devtools:

  1. undock devtools into a separate window
  2. press the full devtools hotkey - CtrlShifti or i
  3. paste the following code in this new devtools window console and run it

{
  const rx = /\bdebugger\b/y;
  const eventSymbol = SDK.DebuggerModel.Events.DebuggerPaused;
  const original = [...SDK.targetManager._modelListeners.get(eventSymbol)]
    .find(v => v.listener.name === '_debuggerPaused');
  const debuggerModel = SDK.targetManager.models(SDK.DebuggerModel)[0];

  SDK.targetManager.removeModelListener(
    SDK.DebuggerModel,
    eventSymbol,
    original.listener,
    original.thisObject);

  SDK.targetManager.addModelListener(
    SDK.DebuggerModel,
    eventSymbol,
    async function({data}) {
      if (data._debuggerPausedDetails.reason === 'other') {
        const frame = data._debuggerPausedDetails.callFrames[0];
        const code = await frame._script.requestContent();
        let {columnNumber: x, lineNumber: y} = frame._location;
        let pos = 0;
        while (y--)
          pos = code.indexOf('\n', pos) + 1;
        rx.lastIndex = Math.max(0, pos + x);
        if (rx.test(code)) {
          debuggerModel.resume();
          return;
        }
      }
      original.listener.apply(original.thisObject, arguments);
    });
}

Notes:

  • You can save this code as a snippet in devtools to run it later.
  • To quickly switch docking mode in the main devtools press CtrlShiftD or D
  • Theoretically, it's not that hard to put this code into resources.pak file in Chrome application directory. There are several tools to decompile/build that file so just add the code to any script that has something like SDK.DebuggerModel.Events.DebuggerPaused inside. One can even write a tool that does that automatically on Chrome update.

Upvotes: 5

Reactgular
Reactgular

Reputation: 54741

Download the offending webworker.js file to your local drive, and use a text editor to replace all occurrences of "debugger" with ";".

Then use a Chrome extension to replace the remote resource with your local modified version.

https://chrome.google.com/webstore/detail/resource-override/pkoacgokdfckfpndoffpifphamojphii?hl=en

FYI: I do not endorse the above extension. It was just the first I found via Google.

Upvotes: 10

Related Questions