Wednesday, February 28, 2024
Google search engine
HomeUncategorizedUnlocking Discord Nitro features for free

Unlocking Discord Nitro features for free

There are several modded Discord clients available that allow you to tweak the appearance or add certain features. However, some plugins can even unlock certain functionalities that require a paid subscription to Discord Nitro.

How is this possible?

Discord is developed using Electron, a framework that allows the development of cross-platform applications using web technologies. This means that the application runs within a web browser, similar to any website. Discord is essentially a Chromium window, which makes it possible to open the development tools. However, this functionality is disabled by default because many users have their accounts compromised by copying malicious commands provided by a threat actor through some form of social engineering.

But. if you understand the risks, you can enable the development tools by adding this parameter to the Discord configuration file located at %appdata%/discord/settings.json

1
2
3
{
    "DANGEROUS_ENABLE_DEVTOOLS_ONLY_ENABLE_IF_YOU_KNOW_WHAT_YOURE_DOING": true
}

Afterwards, you simply need to press ctrl + shift + i to open the development console.

Patching a Discord Function

In order to optimize the initial loading of the application, the code is divided into multiple chunks that can be loaded in parallel or on demand (lazy-loaded) using the code splitting feature from Webpack.

All loaded chunks are stored in the webpackChunkdiscord_app variable:

The webpackChunkdiscord_app variable in the development console The webpackChunkdiscord_app variable in the development console

If you want to execute code that uses Discord’s variables or calls its functions, it’s necessary to inject the code into this variable in this manner.

1
2
3
4
5
6
7
8
9
10
window.webpackChunkdiscord_app.push(
  [
    [Math.random()], // chunk ID
    {},
    (a)=>{
        /* Code to execute */
        console.log(a.c)
    }
  ]
)

The variable a.c is an object containing all the modules. Each module looks like this:

1
2
3
4
5
6
7
{
    "chunk_id": 1234,
    "loaded": true,
    "exports": {
        # The exported functions, objects, or primitive values from the module
    }
}

It is then possible to search for functions through the different JavaScript modules. For example, you can find and call the getCurrentUser() function in this way.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let modules = window.webpackChunkdiscord_app.push([[Math.random()], {}, (a) => { return a.c }]);

function find(query) {
    for (const module of Object.values(modules)) {

        let exports = module.exports;
        if (!exports || exports === window || exports === document.documentElement || exports[Symbol.toStringTag] === "DOMTokenList")
            continue;

        if (typeof (exports) === "object") {
            for (const element of Object.values(exports)) {
                if (element && element[query])
                    return element;
            };
        }
    }
}

find("getCurrentUser").getCurrentUser();

Finally, we can modify the behaviour of a function simply by replacing it.

1
2
3
4
5
6
7
8
9
10
11
12
13
let UserStore = find("getCurrentUser");
let originalFunction = UserStore.getCurrentUser;

UserStore.getCurrentUser = () => {
    
    console.log("before getCurrentUser()")
    let result = originalFunction();
    console.log("after getCurrentUser()")
    
    return result;
}

UserStore.getCurrentUser();

We now have the required knowledge to be able to explore and make direct modifications within the code of Discord.

Unlocking High Quality Streaming

From here on, everything that is shown is clearly against Discord’s Terms of Service and could result in your account being banned. Proceed at your own risk.

There are two interesting functions canStreamMidQuality and canStreamHighQuality, that check the user’s current subscription tier. These functions are called just before displaying the screen that allows the user to choose the quality of their screen sharing.

We can modify the returned value like this:

1
2
find("canStreamMidQuality").canStreamMidQuality = (e) => true;
find("canStreamHighQuality").canStreamHighQuality = (e) => true;

As a result, we can choose to screen share at the source resolution and at 60 FPS even if we are not subscribed to Nitro.

An example of screen sharing at full resolution and 60 FPS. An example of screen sharing at full resolution and 60 FPS.

Currently, Discord doesn’t appear to validate on their servers whether the stream being transmitted truly adheres to the criteria of a non-subscribed user. However, they are likely capable of detecting this, as Discord doesn’t yet use End-to-End encryption. This article mentions that Discord already inspects audio and video content from their users. It wouldn’t be surprising if, in the future, they decide to also perform server-side validations before allowing screen sharing.

Unlocking Premium Themes

Similarly to the functions controlling the screen sharing quality, there is a function that returns whether the user can use the themes provided by a Discord Nitro subscription.

1
find("canUseClientThemes").canUseClientThemes = (e) => true;

This will effectively unlock the buttons allowing the selection of different premium themes.

The screen allowing you to choose a premium theme The screen allowing you to choose a premium theme

However, the theme will only apply for a fraction of a second before reverting back to one of the default themes. This is because Discord attempts to save that the user has modified their theme, but the server validates that the user shouldn’t be able to use a premium theme. When the client receives the response from the server, it immediately reapplies one of the default themes.

It’s necessary to patch another function in order to block the theme synchronization:

1
2
3
4
5
6
7
8
9
10
let PersistedStore = find("shouldSync");
let originalFunction = PersistedStore.shouldSync; 

// We only want to block synchronization for the appearance settings
PersistedStore.shouldSync = (e) => {
    if (e === "appearance")
        return false;
    else
        originalFunction(e)
};

But after that, we can finally change the theme.

The Sunset theme applied The Sunset theme applied

It’s not really possible for Discord to block this. Themes are entirely managed on the client side, and it’s always possible to manually change the CSS directly to get the desired style.

Conclusion

This piece of code makes it easy to deploy all the demonstrated hacks, but it’s important to be cautious before making modifications to your Discord client or using mods. Discord can always ban accounts that violate their terms of use, and running untrusted code with access to your account can be quite risky.

1
eval(atob("Ly8gSGVyZSdzIGEgY2FrZSBpZiB5b3UgdGhvdWdodCBhYm91dCBpbnNwZWN0aW5nIHRoZSBjb2RlIGJlZm9yZSBleGVjdXRpbmcgaXQ6IPCfjoIKCmxldCBjc3MgPSAnZm9udC1zaXplOiAzNnB4OyBmb250LXdlaWdodDogYm9sZDsgY29sb3I6IHJlZCc7CiAKY29uc29sZS5sb2coIiVjTkVWRVIgcGFzdGUgY29kZSB5b3UgZG9uJ3QgdW5kZXJzdGFuZCBpbnRvIHRoZSBkZXZlbG9wbWVudCBjb25zb2xlLiIsIGNzcyk7CmNvbnNvbGUubG9nKCIlY1RoaXMgaXMgdGhlIGJlc3Qgd2F5IHRvIGNvbXByb21pc2UgeW91ciBhY2NvdW50LiIsIGNzcyk7"))

Finally, as references, here are the source code of different plugins for Discord client mod that use the techniques demonstrated in this article.

Vencord
https://github.com/Vendicated/Vencord/blob/main/src/plugins/fakeNitro.ts
Replugged
https://github.com/cafeed28/replugged-nitrospoof/blob/main/src/index.ts
BetterDiscord
https://github.com/riolubruh/YABDP4Nitro/blob/main/YABDP4Nitro.plugin.js

p

Read More

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments