Comment le système fonctionne, dans l'ordre où on en a besoin.
Prise en main
-
Crée ton compte
La connexion passe par Discord, juste pour savoir qui tu es. Ensuite tout se fait sur le site : tu crées tes PIN, tu suis les scans et tu lis les rapports, sans rien faire de plus.
-
Choisis un jeu et génère un PIN
Le jeu décide quel compte le scanner va chercher, et rien d'un autre jeu n'est ouvert. Tu récupères six chiffres et un lien.
-
Envoie le lien, pas le fichier
Le lien fabrique l'exécutable au moment où on l'ouvre. Renvoyer un exécutable déjà téléchargé ne sert à rien : il contient le PIN d'une vérification déjà utilisée.
-
Lis le rapport
Il arrive sur ton dashboard dès que le scanner l'a envoyé, en général une à trois minutes après le lancement.
Concepts
Les deux scores, et pourquoi on ne les mélange pas
Le score de risque dit ce qui a été trouvé : la somme pondérée des indices retenus, sur 100. Ce n'est pas une probabilité de triche.
Le score d'intégrité forensique dit ce qui restait de l'historique de la machine au moment du scan. Journaux effacés, Prefetch désactivé, dates réécrites : chaque chose le fait baisser.
Si on les additionnait, tout le monde lirait le résultat comme « les chances que ce joueur triche », alors qu'aucun des deux ne dit ça. Un risque de 0 avec une intégrité de 20 ne veut rien dire. Le même 0 avec une intégrité de 95 veut dire beaucoup. Sous 35 d'intégrité, un résultat vide devient preuves insuffisantes au lieu d'aucun indicateur.
Ce que la signature d'un rapport prouve, et ce qu'elle ne prouve pas
Au début de la session, le scanner génère en mémoire une paire de clés ECDSA P-256 et signe son rapport avec la clé privée. Ça prouve deux choses : le rapport vient bien du processus qui a validé le PIN, et personne ne l'a modifié en route.
Ça ne prouve pas quel programme tournait de l'autre côté. Un client écrit de zéro génère sa propre clé et signe ce qu'il veut, et sa signature sera parfaitement valide. Ce n'est pas un bug de la vérification : c'est ce que veut dire signer avec une clé qu'on a choisie soi-même.
Le protocole v2 ne règle pas ça, et aucun serveur ne peut le régler sans attestation matérielle. Il règle tout le reste : le serveur envoie un défi à l'ouverture, la signature le couvre, et le rapport devient le résultat d'un échange en direct, lié à une seule session et utilisable une seule fois.
Un exécutable par PIN
Il n'y a pas de Sentinel.exe à télécharger. Chaque lien produit une copie du binaire, avec la configuration de la vérification ajoutée à la fin du fichier : adresse de l'API, PIN, jeu, date d'expiration. Windows ignore ce qui suit la dernière section d'un PE, et Linux fait de même pour un ELF : le programme lui-même n'est pas touché.
La contrepartie : la signature Authenticode du binaire de base ne couvre plus tout le fichier. C'est pour ça que la page de téléchargement affiche l'empreinte SHA-256 du fichier généré. Elle joue le rôle de la signature et prouve que le fichier reçu est bien celui qui a été envoyé.
Une fois le rapport envoyé, l'exécutable programme sa propre suppression. De son côté, le lien n'accepte qu'un seul téléchargement et finit par expirer.
Pourquoi le serveur recalcule le verdict
Le scanner envoie sa propre conclusion et on l'enregistre. Mais ce n'est jamais elle qui compte : le programme tourne sur la machine examinée, et son propriétaire contrôle tout. Le serveur recalcule le verdict à partir des détections qu'il a vraiment reçues.
Quand les deux ne collent pas, le rapport le dit. Soit les jeux de règles n'ont pas la même version, soit le client n'est pas celui qu'on a distribué.
Format des règles
Tes règles s'ajoutent à celles du serveur pour tes propres scans. Elles ont la même forme que le jeu de règles Sentinel.
- Un groupe de chaînes est une liste de mots recherchés dans les octets d'un fichier, en ASCII et en UTF-16. Jamais dans son nom : renommer un fichier ne le cache pas.
- Une règle composite exige plusieurs groupes présents en même temps. C'est ce qui la différencie d'un simple mot-clé, et ça évite d'accuser un joueur juste parce qu'un de ses fichiers contient « aura ».
- Une règle qui marque des points doit exiger au moins deux groupes. Une règle à un seul groupe est acceptée si son score vaut zéro : elle sert alors juste à documenter une observation.
- Chaque règle doit expliquer pourquoi elle existe et ce qu'elle ne prouve pas. Ces deux textes apparaissent tels quels dans le rapport, que le joueur peut demander à voir.
- Une empreinte SHA-256 est une détection directe : elle vaut pour un fichier exact et rien d'autre.
{
"stringGroups": {
"client_brand": ["MyCheatClient", "mycheatclient.gg"],
"injection": ["CreateRemoteThread", "WriteProcessMemory", "LdrLoadDll"]
},
"compositeRules": [
{
"id": "MSV-001",
"title": "Client de triche interne connu",
"severity": "High",
"score": 45,
"appliesTo": "executable",
"platform": "any",
"requires": [
{ "group": "client_brand", "min": 1 },
{ "group": "injection", "min": 2 }
],
"why": "Le binaire porte la marque d'un client qu'on a déjà croisé sur ce serveur, et il importe les fonctions qui servent à injecter du code dans un autre processus.",
"caveat": "Un vrai outil de débogage peut importer les mêmes fonctions. C'est la présence de la marque en même temps qui rend la règle utile.",
"plain": "Ce fichier ressemble à un client de triche déjà vu sur notre serveur."
}
],
"hashes": []
}
Limites
| 256 Ko par jeu de règles | 256 Ko |
| 60 règles composites | 60 |
| 40 groupes de chaînes | 40 |
| 500 empreintes | 500 |
| 4 caractères minimum par chaîne recherchée | 4 |
Une regex écrite par quelqu'un et exécutée sur la machine de quelqu'un d'autre, c'est un moyen simple de la faire planter. La recherche de texte exact suffit pour tout ce que ces règles doivent décrire.
API
L'API utilisée par le scanner, servie par le service de vérification sur http://45.145.166.173:19137. Elle ne dépend pas de ce site.
| Méthode | Chemin | Authentification | À quoi ça sert |
|---|---|---|---|
| GET | /api/v1/health | aucune | État du service |
| GET | /api/v1/scanner/latest | aucune | Version actuelle du scanner |
| GET | /api/v1/rules/latest | aucune | Version du jeu de règles |
| POST | /api/v1/scan/start | PIN | Échange un PIN contre un jeton et un défi |
| GET | /api/v1/rules/bundle | Bearer | Jeu de règles, une fois par scan |
| POST | /api/v1/scan/report | Bearer | Envoie le rapport signé |
| GET | /api/v1/scan/:id | x-api-secret | Relit un scan |
curl -s http://45.145.166.173:19137/api/v1/scan/start \
-H 'content-type: application/json' \
-d '{
"pin": "482913",
"scannerVersion": "1.0.2.0",
"rulesetVersion": "2026.08.18-proto5",
"publicKey": "<64 octets X||Y en base64>"
}'
Auto-hébergement
Le site et le service de vérification sont deux processus séparés. En dev, chacun peut avoir sa propre base. En prod, ils partagent la même MariaDB : c'est comme ça qu'un PIN créé sur le site est reconnu par le scanner.
# le service de vérification (l'API que le scanner contacte)
cd server && npm install && npm start # écoute sur :8080
# le site
cd web && npm install && npm run setup && npm start # écoute sur :3000
API_SECRET doivent être identiques
C'est lui qui sert à hacher le PIN. S'ils sont différents, le scanner refusera chaque PIN créé sur le site avec « PIN invalide », sans autre explication.