Les mod menus RedM : comment ils se chargent, et comment en repérer un sans connaître son nom
Ce que fait vraiment un mod menu sur un serveur RedM, les trois signaux qui le trahissent sans liste noire ni nom connu, et ce qu’aucun anticheat ne verra.
Un mod menu RedM ne s’annonce pas. Il n’apparaît dans aucune liste de ressources, ne lève aucune erreur au démarrage, et le joueur qui l’utilise se comporte normalement pendant les trois quarts de sa session. Quand vous finissez par le remarquer, c’est généralement parce qu’un autre joueur a filmé quelque chose d’impossible. Cet article explique par où le menu entre, ce qu’il offre à celui qui le paie, et quels signaux l’identifient, sans jamais avoir besoin de savoir comment il s’appelle.
Par où le menu entre
La première étape est un programme externe. Il se lance avant ou pendant le jeu, ouvre le processus et écrit son propre code dans l’espace mémoire du jeu. À partir de cet instant, le menu n’est plus un logiciel posé à côté du jeu : il est dedans, avec sur le jeu les mêmes droits que le jeu a sur lui-même. Il peut appeler des fonctions du moteur, lire votre Lua client une fois arrivé sur la machine, et rendre la main sans que rien n’ait visiblement cessé de fonctionner. Les loaders sérieux sont protégés (binaires packés, fonctions du jeu résolues par leurs symboles de débogage) précisément pour que cette étape ne laisse aucune trace lisible.
La seconde étape est celle qui nous intéresse, parce qu’elle touche votre serveur. Pour exécuter du Lua avec les droits d’une ressource, et donc pouvoir déclencher vos événements réseau, appeler vos exports, passer pour votre propre code, le menu détourne une ressource déjà en cours d’exécution. Il pousse ses propres valeurs dans l’espace global de cette ressource, puis son code s’y réveille comme s’il lui avait toujours appartenu. Un cas réel que nous avons observé : le menu dépose quatre variables (un identifiant utilisateur, un jeton, une clé) dans la table globale d’une ressource légitime, avant même que sa propre couche d’obfuscation ne démarre. Ces quatre variables sont sa poignée de porte, et elles sont aussi sa signature comportementale.
Il existe une troisième voie, bien plus bruyante : démarrer une ressource qui vous appartient. Cela demande un accès au serveur, pas au client. Si un menu tourne comme ressource déclarée, votre problème n’est pas un tricheur, c’est un membre du staff.
Une fois à l’intérieur, voici ce que reçoit l’acheteur :
L’état du personnage : invincibilité, munitions infinies, traversée des murs, vitesse. Ce sont des appels de fonctions du moteur, gratuits quand on est à l’intérieur.
L’apparition d’entités : peds, chevaux, véhicules, objets, par rafales. C’est la nuisance visible, celle dont votre communauté se plaint auprès de vous.
Vos événements réseau : le menu lit vos scripts client, en extrait les noms d’événements serveur, et les rejoue avec les arguments qu’il veut. C’est de loin le plus coûteux pour vous (argent, objets, rôles), et cela ne ressemble pas à de la triche dans les logs : cela ressemble à votre propre économie.
Le dump : lire et exfiltrer vos ressources. Le menu ne cherche pas seulement à tricher, il cherche à copier votre serveur.
Pourquoi une liste noire de noms ne vaut rien
La réaction naturelle est de tenir une liste : noms de menus connus, noms de ressources suspects, noms d’événements, empreintes de fichiers. Elle attrape la première version, pour une semaine. Puis l’auteur renomme. Certains menus affichent explicitement un bouton « changer le nom », d’autres tirent un nom au hasard à chaque lancement, et les valeurs déposées dans l’espace global sont générées à la volée. Une liste noire ne décrit pas une capacité, elle décrit une orthographe, et l’orthographe est la chose la moins chère du monde à changer.
Trois signaux qui ne dépendent pas du nom
1. L’appelant anonyme. Sur RedM, chaque appel de fonction du moteur vient d’un contexte. Quand le code appelant appartient à une ressource en cours d’exécution, le moteur sait laquelle. Quand c’est du code injecté, il n’y a aucune ressource à nommer : l’appelant est inconnu. Le principe tient en une phrase : ce n’est pas la fonction appelée qui est suspecte, c’est le fait qu’aucune ressource ne la revendique. Créer un cheval, activer l’invincibilité, devenir invisible : un serveur roleplay fait les trois toute la journée, mais toujours depuis un script identifiable.
Ce signal seul ferait des dégâts, nous le tempérons donc : nous exigeons observations distinctes avant qu’une alerte ne parte, nous ignorons une fenêtre de tolérance pendant que le joueur se charge (où le moteur lui-même appelle sans contexte), et l’écran noir d’un voyage rapide désarme temporairement la famille « état ». Les valeurs restent en interne : publiées, elles deviendraient la marge dans laquelle le menu se glisse.
Non publié/Les seuils de détection ne sont jamais publiés : une valeur connue est une valeur sous laquelle un cheat se règle.
2. L’écriture dans l’espace global d’une autre ressource. C’est le geste de chargement lui-même. Une ressource n’écrit pas dans la table globale d’une autre ressource : ce n’est pas ainsi que les ressources se parlent, et aucun framework roleplay n’a de raison de le faire. Nous surveillons donc cette écriture. De notre côté, elle est avalée : la valeur est acceptée en apparence, puis renvoyée corrompue en gardant la même forme, si bien que le loader croit avoir réussi et s’effondre plus loin, et le jeton d’origine remonte dans le dossier. Ce jeton n’est pas anonyme : c’est le compte qui a payé le menu.
3. La lecture massive de fichiers de ressources. Un dump se cache assez mal : il lit beaucoup, vite, et il lit des choses qu’aucun script n’ouvre jamais en jeu. Nous mesurons la rafale plutôt que le fichier, et nous plaçons des fichiers qui n’ont aucune raison d’être lus : un script légitime les ignore, un dumper les avale avec le reste et se désigne lui-même. La limite est claire et nous la disons : cette protection vit dans le jeu, elle voit donc les dumps qui passent par le jeu. Un outil qui copie votre cache depuis le disque, hors du processus, ne la rencontrera jamais. La seule vraie réponse à celui-là est contractuelle, pas technique.
Ce que cette famille de détection ne voit pas
Tout ce qui précède suppose que le cheat parle au moteur. Un cheat entièrement externe ne le fait pas : il lit la mémoire du jeu depuis un autre processus, parfois depuis une seconde machine, il n’appelle aucune fonction, n’écrit dans aucun état Lua, et se contente de dessiner sur votre écran ou de bouger votre souris. Aucun de nos trois signaux ne se déclenche, et aucun anticheat qui tourne dans le jeu ne peut prétendre le contraire. Un ESP en lecture seule est dans la même situation : il ne change rien, il ne se contredit donc nulle part.
Ce qui reste alors, c’est l’effet : un tir qui suit une trajectoire qu’aucun humain ne produit, une visée qui saute et se fige, la connaissance de positions que le joueur ne devrait pas avoir. On ne détecte plus le programme, on détecte sa trace : c’est le sujet de notre article sur le silent aim. Et parce que la question revient toujours : oui, la décision finale doit être prise ailleurs que sur la machine du joueur, ce qui est tout l’argument client contre serveur.
Si vous voulez voir à quoi ressemble un dossier de chargement de menu (l’appelant inconnu, le jeton récupéré, l’horodatage), le panel de démo est ouvert sans inscription, notre anticheat RedM montre où cette famille se place parmi les autres, et les principes généraux sont exposés dans comment fonctionne un anticheat RedM.