Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new scriptlet that prevents some anti-debugging #3378

Closed
9 tasks done
D4niloMR opened this issue Sep 16, 2024 · 28 comments
Closed
9 tasks done

Add new scriptlet that prevents some anti-debugging #3378

D4niloMR opened this issue Sep 16, 2024 · 28 comments
Labels
enhancement New feature or request fixed issue has been addressed

Comments

@D4niloMR
Copy link

D4niloMR commented Sep 16, 2024

Prerequisites

  • I verified that this is not a filter list issue. Report any issues with filter lists or broken website functionality in the uAssets issue tracker.
  • This is NOT a YouTube, Facebook or Twitch report. These sites MUST be reported by clicking their respective links.
  • This is not a support issue or a question. For support, questions, or help, visit /r/uBlockOrigin.
  • I performed a cursory search of the issue tracker to avoid opening a duplicate issue.
  • The issue is not present after disabling uBO in the browser.
  • I checked the documentation to understand that the issue I am reporting is not normal behavior.

I tried to reproduce the issue when...

  • uBO is the only extension.
  • uBO uses default lists and settings.
  • using a new, unmodified browser profile.

Description

Mostly for websites that has obfuscated code with anti-debugging. Maybe in the future it will be possible to replace the snippet below with trusted-replace-argument .

Only the proxy is necessary.

window.Function.prototype.constructor = new Proxy(window.Function.prototype.constructor, {
  apply: function(target, thisArg, args) {
    if (typeof args[0] === "string" && args[0].includes("debugger")) {
      return;
    }
    return Reflect.apply(target, thisArg, args);
    }
  });
window.console.clear = function () {};
Object.defineProperties(Object.prototype, { devtoolsDetector:{}, Debugger:{} });

A specific URL where the issue occurs.

https://veev.to/d/4vz566d3awg0
https://www.japscan.lol/
https://animet2.net/
https://binged.to/watch/movie/365177

Steps to Reproduce

  1. Disable annoyances lists.
  2. Choose one of the URLs above.
  3. Navigate to the site and open devtools.
  4. Boom, debugger statement

Expected behavior

Visiting site with obfuscated code the debugger statement is not executed.

Actual behavior

Visiting site with obfuscated code and anti debugger, the debugger statement is executed.

uBO version

1.59.1b22

Browser name and version

Firefox Developer Edition 131.0b6

Operating System and version

Windows 10

@uBlock-user
Copy link
Contributor

uBlock-user commented Sep 16, 2024

@D4niloMR ##+js(trusted-replace-argument, Function.prototype.constructor, 0, undefined, condition, debugger) ?

@D4niloMR
Copy link
Author

Doesn't work, I don't see nothing logged with ##+js(trusted-replace-argument, Function.prototype.constructor) either.

@uBlock-user
Copy link
Contributor

uBlock-user commented Sep 16, 2024

Well it's based on

window.Function.prototype.constructor = new Proxy(window.Function.prototype.constructor, {
  apply: function(target, thisArg, args) {
    if (typeof args[0] === "string" && args[0].includes("debugger")) {
      return;
    }
    return Reflect.apply(target, thisArg, args);
    }
  });

If that works, then this should also work...

Maybe trusted-suppress-native-method is needed

@gorhill
Copy link
Member

gorhill commented Sep 16, 2024

There is this extension specialized in defusing anti-devtools: https://github.com/Andrews54757/Anti-Anti-Debug

AMO: https://addons.mozilla.org/en-US/firefox/addon/anti-anti-debug/
CWS: https://chromewebstore.google.com/detail/anti-anti-debug/mnmnmcmdkigakhlfkcdimghndnmomfeo

@D4niloMR
Copy link
Author

That extension seems good. Still it would be handy to have a scriptlet to trap Function.prototype.constructor, or better, using trusted-replace-argument on it.

@gorhill
Copy link
Member

gorhill commented Sep 16, 2024

trusted-replace-argument should work but doesn't because the trapped target ends up being construct, which is problematic for Function since it can be called either through new Function(...) or directly through Function(...). Also, if I end up fixing this somehow, the function argument can be a different position than 0, so the scriptlet might need a way to provide argument position relative to the end, and/or a way to scan all arguments.

@uBlock-user
Copy link
Contributor

same reason for trusted-suppress-native-method not working ?

@gorhill
Copy link
Member

gorhill commented Sep 16, 2024

trusted-suppress-native-method uses the same internal helper to trap, so probably the same issue.

gorhill added a commit to gorhill/uBlock that referenced this issue Sep 17, 2024
@gorhill
Copy link
Member

gorhill commented Sep 17, 2024

##+js(trusted-replace-argument, Function.prototype.constructor, 0, , condition, debugger) works in 1.59.1rc0.

@uBlock-user
Copy link
Contributor

what about ##+js(trusted-replace-argument, Function.prototype.constructor, 0, undefined, condition, debugger) ?

@gorhill
Copy link
Member

gorhill commented Sep 17, 2024

Why not try it?

@D4niloMR
Copy link
Author

It works, but seems to take a lot of resources, especially on Firefox.

Screenshots

image

image

https://share.firefox.dev/3ZoT6tD

@gorhill
Copy link
Member

gorhill commented Sep 17, 2024

seems to take a lot of resources, especially on Firefox

At https://veev.to/d/4vz566d3awg0, this happens without the filter too, just opening the dev console?

@D4niloMR
Copy link
Author

Yes, but I wasn't with devtools opened while profiling and it still used a lot of resources.

I can't reproduce this issue anymore on that site though. I can on japscan.lol.

@gorhill
Copy link
Member

gorhill commented Sep 17, 2024

Looks like it's related to the scriptlet sending logging information to uBO's background process -- might be an issue when a site does something very fast non-stop which is being trapped by uBO.

@garry-ut99

This comment was marked as abuse.

gorhill added a commit to gorhill/uBlock that referenced this issue Sep 17, 2024
@D4niloMR
Copy link
Author

D4niloMR commented Sep 18, 2024

Now it becomes unresponsive, more noticeable when the logger/devtools is open. Firefox still freezes if wait long enough.

@gorhill
Copy link
Member

gorhill commented Sep 18, 2024

I am going to need all the details of what I need to do to reproduce.

I could reproduce performance issue only when the logger was opened when navigating to https://veev.to/d/4vz566d3awg0 while using the filter veev.to##+js(trusted-replace-argument, Function.prototype.constructor, 0, , condition, debugger), and this was squarely a issue with sending too much logging information to the logger from the page context -- as the page probably keep creating debugger functions non-stop in a tight loop. Once I added the throttling code to prevent repeatedly reporting thesame information to the logger, the issue went away. The profiling data you shared also show the issue was the logging overhead.

Now if you have another scenario causing issue, I will need all the details on how to reproduce on my side, and profiling data is welcome.

@D4niloMR
Copy link
Author

D4niloMR commented Sep 18, 2024

The issue of the resources is fixed. Now I'm reporting that on my end, navigating through the devtools tabs is unresponsive, like network tab, sources/debugger and expanding nodes in inspector.

But this is probably the site's own issue, I didn't notice that the snippet in the description and the Anti Anti Debug extension was throwing error and stopping the debugger call. Once I added veev.to##+js(trusted-replace-argument, Function.prototype.constructor, 0, noopFunc, condition, debugger) the issue went away.

@gorhill
Copy link
Member

gorhill commented Sep 18, 2024

veev.to##+js(trusted-replace-argument, Function.prototype.constructor, 0, noopFunc, condition, debugger)

You shouldn't be using noopFunc, the argument is supposed to be a string representing the body of the function to create and using noopFunc causes an exception -- try Function.prototype.constructor(function(){}) in dev console of https://example.com/).

This doesn't throw:

veev.to##+js(trusted-replace-argument, Function.prototype.constructor, 0, /* debugger */, condition, debugger)

You can try at https://example.com/ console: Function.prototype.constructor('/* debugger */')

@D4niloMR
Copy link
Author

Yes, but on my end if it doesn't throw I suffer from the issue above.

@garry-ut99

This comment was marked as abuse.

@stephenhawk8054
Copy link
Member

stephenhawk8054 commented Sep 18, 2024

How about this:

veev.to##+js(trusted-replace-argument, Function.prototype.constructor, 0, {"value": "/* debugger */"}, condition, debugger)

@uBlock-user
Copy link
Contributor

Why not try it?

I cannot reproduce debugger statement, so need someone to test.

@gwarser gwarser added the enhancement New feature or request label Sep 19, 2024
@garry-ut99

This comment was marked as abuse.

@gorhill
Copy link
Member

gorhill commented Sep 19, 2024

Yes, but on my end if it doesn't throw I suffer from the issue above.

Right, I didn't realize an exception worked better. In that case, this filter might be a better match:

veev.to##+js(trusted-suppress-native-method, Function.prototype.constructor, '"debugger"', abort)

@garry-ut99

This comment was marked as abuse.

@D4niloMR
Copy link
Author

Also works fine for me.

@uBlock-user uBlock-user added the fixed issue has been addressed label Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fixed issue has been addressed
Projects
None yet
Development

No branches or pull requests

6 participants