Aller au contenu
Top-Metin2.org - Vous êtes à la recherche d'un serveur Metin 2 ? ×
×
×
  • Créer...

C++ - Protéger son Client


Messages recommandés

  • Robot

Bonjour.

 

On dit toujours que la protection ne doit pas être exclusive... Elle l'est souvent. Je n'ai pas des grosses connaissances en ce sujet, je ne joue pas souvent à Metin2, j'ai juste regardé une après midi les sources et comment est fait le client, pour essayer de faire une protection basique, dont le contenu est compréhensible par tout le monde afin de faire progresser les personnes avec des connaissances assez modestes comme les miennes.

 

Je suis pas codeuse, je ne travaille pas là de dans, mon code n'est peut-être pas très optimisé, si vous faites mieux allez-y, ça me fera plaisir de voir comment j'aurai pu faire autrement ;)

 

Avant n'importe quelle manipulation se trouvant dans ce tutoriel, vous devez faire une sauvegarde. Ne vous dites pas "je vais suivre à la lettre c'est bon". Je n'ai pas du tout envie que vous soyez obligé de recommencer quelques choses car je me suis mal exprimée.

L'avertissement étant donné, nous pouvons commencer.

 

Vérification de certains fichiers par les sources client :

Nous allons ici utiliser l'encodage MD5. Je sais que des collisions sont possibles, et que je devrais utiliser le sha-256. Mais je considère que le risque de collision entre deux fichiers sachant qu'un doit avoir plus de contenu tout en restant fonctionnel... Je considère que la probabilité est nulle.

 

Bien, commencer, vous allez devoir ajouter un fichier dans votre UserInterface, pour cela vous avez plusieurs méthodes, la plus simple reste encore (à mon goût) celle-ci :

042529Screenshot-2.png

Vous allez ensuite nommé ce fichier comme bon vous semble, mais je vous conseil de l'appelé mh5.h comme ça, pas de confusion possible.

Vous allez ensuite copier l'intégralité de ceci dans le fichier : https://pastebin.com/0UNriMYE

Vous pouvez ensuite sauvegarder votre fichier.

 

Ouvrez ensuite votre Locale_inc.h :

Ajoutez en dehors de toute boucle :

#define ENABLE_CHECK_FILES_MD5

Je vous explique ceci à la fin, c'est très simple à comprendre vous allez voir, je vous mettrai une petite note explicative.

 

Ensuite, rendez-vous dans votre UserInterface.cpp :

Ajoutez avec les autres includes :

#ifdef ENABLE_CHECK_FILES_MD5
	#include md5.h
	#include windows.h
#endif

Ici, nous ajoutons des fichiers nécessaire au script. On inclue les données de ce fichier dans UserInterface.cpp.

 

Cherchez ensuite :

static const char * sc_apszPythonLibraryFilenames[] =

Vous trouverez normalement une liste qui ressemble à celle-ci :

static const char * sc_apszPythonLibraryFilenames[] =
{
	"UserDict.pyc",
	"__future__.pyc",
	"copy_reg.pyc",
	"linecache.pyc",
	"ntpath.pyc",
	"os.pyc",
	"site.pyc",
	"stat.pyc",
	"string.pyc",
	"traceback.pyc",
	"types.pyc",
	"\n",
};

Vous allez ajouter en bas :

#ifdef ENABLE_CHECK_FILES_MD5
	#define MAX_ROWS_MD5 21
	static char * ar_szMD5FileNames[MAX_ROWS_MD5][2] =
	{
		{ "lib/__future__.pyc", "d2505c6e64dc44a1745dda0905f4e787" },
		{ "lib/copy_reg.pyc",   "5e996d35b598676b253dd25fa3809ef2" },
		{ "miles/mssdsp.flt",   "cb71b1791009eca618e9b1ad4baa4fa9" },
		{ "miles/msssoft.m3d",  "bdc9ad58ade17dbd939522eee447416f" },
		{ "miles/mssa3d.m3d",   "e089ce52b0617a6530069f22e0bdba2a" },
		{ "miles/mss32.dll",    "6400e224b8b44ece59a992e6d8233719" },
		{ "pack/uiscript.eix",	"d211c0a83ff2c771946d73554916bd9a" },
		{ "python27.dll",       "d219c0a8aff2c771946d73554916bd9a" }
	};
#endif

Vous allez ici devoir ici déjà :

  • Mettre les fichiers que vous désirez,
  • Ajouter une virgule à toutes les lignes sauf à la dernière
  • Changer les hash md5 "d2505c6e64dc44a1745dda0905f4e787" selon vos fichiers.

Faites bien attention à ajouter la destination dans le nom de fichier, par exemple pour les packs vous voyez bien que j'ai ajouté pack/uiscript.eix car mes packs se trouvent dans le dossier packs.

Pour hash vos fichiers, je ne vous laisse pas dans la nature, voici un petit programme que j'ai recodé de façon à pouvoir vos permettre de :

  • Voir le MD5 de vos fichiers
  • Changer le hash md5.

 

Vous allez ensuite chercher :

bool __IsLocaleVersion(LPSTR lpCmdLine)
{
	return (strcmp(lpCmdLine, "--perforce-revision") == 0);
}

Puis ajouter en dessous :

#ifdef ENABLE_CHECK_FILES_MD5
	void CheckMD5Filenames()
	{
		MD5 md5;
		for (int it = 0; it < _countof(ar_szMD5FileNames); it++)
		{
			if (strcmp(md5.digestFile(ar_szMD5FileNames[it][0]), ar_szMD5FileNames[it][1]))
			{
				char szBuf[512 + 1];
				snprintf(szBuf, sizeof(szBuf), "Le fichier %s est corrumpu.", ar_szMD5FileNames[it][0]);
				MessageBoxA(NULL, szBuf, "#Metin2", NULL);
				exit(0);
			}
		}
	}
#endif

 

Enfin, cherchez :

	if (strstr(lpCmdLine, "--hackshield") != 0)
		return 0;

Ajoutez après :

#ifdef ENABLE_CHECK_FILES_MD5
	CheckMD5Filenames();
#endif

 

Félicitations ! Vous n'avez plus qu'à compiler vos sources à nouveau.

Petite explication sur le code :

Révélation
  • #define : Sert à définir quelque chose. Nous pourrons ensuite déterminer si oui ou non cela a été fait.
  • #ifdef :  Si cela a été défini alors :
  • #else : Si un ifdef n'est pas respecté alors...
  • #endif : Fin de boucle
  • #ifndif : Si cela n'a pas été définie, exacte contraire de #ifdef.

 

 

 

Nous allons maintenant voir comment exécuter un scripte de sécurité en Python.

Trois problèmes se posent à nous :

  • Que faire ?
  • Comment le faire ?
  • Où le faire ?

Nous allons commençons par le plus simple "Où ?" :

Et bien, sachant qu'en Python, le premier fichier chargé est le system.py cependant... Il ne dispose pas encore à ce stade de toutes les fonctions dont nous allons avoir besoin, nous allons par conséquence prendre le deuxième fichier : prototype.py

Vous allez donc mettre en toute première ligne de ce fichier :

import akihira

Note : Remplacez akihira par ce que vous voulez.

 

Vous allez ensuite créer un fichier du même nom que celui que vous avez importer dans notre root, par exemple ici, akihira.py.

Bien, commençons à éditer notre fichier.

 

Vous allez commençons par ajouter ces imports :

import os
import thread
import time
import app
import dbg
  • os : Il va nous permettre de nous balader dans les destinations et d'utiliser les fichiers.
  • thread : Il va nous permettre quant à lui de créer des instances, et donc de faire plusieurs choses en même temps.
  • time : Il va bien falloir donner une fréquence à la répétition de la vérification, la voici.
  • app : C'est un module généré par C++ dans les sources client. Nous allons ici nous en servir pour "faire planter" le client.
  • dbg : DialogBoxGenerator, il me semble... Il permet de créer des boites de dialogue, ici il nous servira pour des fenêtres d'erreur.

 

Bien, nous allons d'abord créer une liste, dans celle-ci, nous allons écrire la liste des programmes "parasites". C'est à dire ceux que nous ne voulons pas.

Pour créer une liste en python, rien de plus simple ! Nous allons aimer ça syntaxe simple :

black_list = []

Votre liste est crée... Je vous l'accorde, il faut la remplir ! Pour cela nous allons ajouter le nom des programmes en tant que chaine de caractère, donc entre guillemet(/apostrophe) et les séparer entre eux par une virgule. Voici un exemple :

black_List = ["injector.exe","cheatengine-x86_64.exe"]

Bien, je vous laisserai remplir la liste comme vous le souhaitez, de toute façon, nous allons adapter notre code pour qu'il s'adapte à n'importe quelle liste.

 

Nous allons ensuite devoir dire à notre programme :

  • Pour chaque membre de la liste (que l'on va nommé "membre") :
    • Récupère la liste des programmes.
    • Si un deux  est le même que 'membre'
      • Tu fermes le client
    • Sinon :
      • Tu recommences

Nous n'allons en fait pas exactement respecter cette architecture, nous allons mettre exactement :

  • Répète à l'infini :
    • Pour chaque processus 'p' du gestionnaire de tâche :
      • Pour chaque membre de la liste
        • Si dans le processus tu trouves "membre":
        • On arrête le processus
        • On attend 5 secondes

Bon  est bien... On a du pain sur la planche !

 

Pour répéter à l'infini, nous allons utiliser une évidence. Mais d'abord, nous allons contenir tout ça dans une fonction afin de pouvoir la démarrer en tant qu'instance (thread) :

def __process():
	pass

Bien, je vous ai parlé d'une évidence, vous vous demandez peut être ce que c'est, et bien... si je vous dis que 1 est égale à 1, vous me dit quoi ? "Bah oui" Et bien voilà, on va dire à Python : "Le temps que 1 = 1 :" Nous utilisons pour ça la structure while.

Cela donne :

def __process():
	while 1 ==1:
		pass

Bien... Continuons ! '¨pour chaque processus... Vous ne pouvez pas deviner ceci si vous débutez, je vous le donne :

def __process():
	while 1 == 1:
		for p in os.popen("tasklist"):

Bien, ensuite "Pour chaque membre de la liste :

def __process():
	while 1 == 1:
		for p in os.popen("tasklist"):
			for Member in black_List:

"Si tu trouves de dans "Member" :

def __process():
	while 1 == 1:
		for p in os.popen("tasklist"):
			for Member in black_List:
				if process.find(Member) !=1:

Nous allons ensuite écrire ceci, je vous explique après :

def __process():
	try:
		while 1 == 1:
			for p in os.popen("tasklist"):
				for Member in black_List:
					if process.find(Member) !=1:
						p = process.slip()
						os.popen("taskkill /im %s /f" %p[0])
						time.sleep(5)

	except:
		time.sleep(5)

"MAIS T'AS TOUT CHANGÉ ÇA VA PAS DANS TA TÊTE ?"

Mais nous, résumons, qu'est-ce que j'ai fais ?

  • j'ai entouré le code de :
    • try:
      • Traduction : Essaye de...
    • except :
      • Traduction : Si tu n'y arrives pas :

S'il n'y arrive pas, je lui ai dis ici d'attendre 5 secondes.

J'ai ensuite rajouté le fait de lancer une commande pour "tuer"/arrêter le processus, puis attendre 5 secondes.

Bien, il ne nous reste plus qu'une chose à faire ! Lancer la fonction grâce à une instance(thread), pour cela je vous donne la façon de faire :

thread.start_new_thread(__process, ())

Mettez ceci à la fin de votre fichier, sans aucune tabulation.

Félicitations ! Vous avez maintenant une boucle qui scanne les processus en permanence ! Vous devenez un champion !

 

 

Bien, maintenant nous allons faire la même chose pour chaque fichier du client avec des extensions et une liste, vous avez compris le principe, je peux vous donner directement la boucle :

BanExt = [".m3d", ".py", ".fld", ".mix", ".asi"]
Dest = os.listdir('.')
Dest.sort()
for Member in BanExt:
	for File in Dest:
		if File.find(Member) != -1:
			dbg.LogBox("Une erreur est survenue: " + str(File) + "")
			try:
				os.remove(File)
			except:
				dbg.LogBox("Erreur !")
				dbg.LogBox("Fichier: " + str(File))
				app.Abort()

A vous de choisir, si vous voulez refaire une boucle avec une évidence et une instance, pour lancer ce scan en permanence.

 

Nous repassons du côté de vos sources clients pour la suite, ne vous faites pas avoir !

 

Bien, nous allons maintenant ajouter une protection très simple, le principe est aussi très simple :

  • Quand un joueur attaque :
    • Si il n'attaque pas (c'est assez contradictoire je sais)
      • On annule l'action.

 

Pour cela, nous allons juste ajouter deux minables lignes dans le PythonNetworkStreamPhaseGame.cpp

Cherchez :

TPacketCGAttack kPacketAtk;

Ajoutez juste en dessous :

if (!__IsPlayerAttacking())	
  return true;

Nous vérifions ici que le joueur est bien entrain d'attaquer.

 

 

 

Cette modification est réservée aux personnes ayant un minimum de connaissance en Python.

Nous allons maintenant changer le premier fichier Python chargé afin de pouvoir gérer au maximum les erreurs en cas de besoin :

Rendez-vous dans UserInterface.cpp :

if (!pyLauncher.RunFile("system.py"))

Changez comme vous le souhaitez le nom, et vous pouvez commencer à taper des scripts avant de lancer véritablement le client.

Vous pouvez dans le même fichier changer le premier pack chargé afin de perturber les nouveaux apprentis pirates :

Toujours dans UserInterface.cpp :

CEterPackManager::Instance().RegisterRootPack((stFolder + std::string("root")).c_str());

 

 

Modifier vos clés de compressions :

Cette manipulation s'adresse aux personnes n'ayant pas changer leur compression et fonctionnant toujours sous LZO.

Dans vos sources clients, rendez-vous dans Eterpack.cpp :

Vous trouverez :

static DWORD s_adwEterPackKey[] =
{
45129401,
92367215,
681285731,
1710201,
};

static DWORD s_adwEterPackSecurityKey[] =
{
78952482,
527348324,
1632942,
486274726,
};

Vous pourrez ensuite les modifications comme bon vous sembles le temps que vous pouvez les convertir en hexadécimal grâce à un petit script python disponible ici :

import struct
print "Exemple de clé: b99eb0026f69810563989b2879181a00\n"
string=raw_input("Clé héxadécimal: ")
lista=struct.unpack("LLLL", string.decode('hex'))
n=0
print "\nGenerateur: \n"
for i in lista:
  n+=1
  i=str(i)
  i=i.replace("L", "")
  print "A" + str(n) + " = " + i

 

Vous devrez ensuite entrées ces valeurs dans votre packer afin de l'adapté.

Vous devrez ensuite repacker tout vos packs avec la nouvelle compression !

 

Changer les extensions de vos packs :

 

Vous pouvez effectivement changer les extensions de vos packs grâce à une méthode très simple.

Rendez vous dans Eterpack.cpp :

	strncpy(m_indexFileName, dbname, MAX_PATH);
	strcat(m_indexFileName, ".eix");

	m_stDataFileName = dbname;
	m_stDataFileName += ".epk";
	

Changez comme bon vous semble en conservant 3 caractères après le point.

Vous devrez ensuite changer l'option sur votre packer, puis utiliser ceci (IF) pour changer les extensions de vos packs :

main
@echo OFF
@echo Modifiez l'extension
@echo de vos fichiers

:rename
set EIX=
set /P EIX=Choisissez l'extension de vos futurs fichiers EIX: %=%
@ren *.eix *.%EIX%
@echo Succès .%EIX%
if "%EIX%" == "" GOTO errore
set EPK=
set /P EPK=Choisissez l'extension de vos futurs fichiers EPK:  : %=%
if "%EPK%" == "" GOTO errore
@ren *.epk *.%EPK%
@echo Succès .%EPK%
@echo ---
GOTO fine
:errore
@echo Erreur !
@echo L'extension n'est pas valide !
@echo ---
GOTO esciprogramma
:fine
@echo Le changement est terminé ! Quittez le programme.
:esciprogramma
@pause
:rename
set EIX=
set /P EIX=Choisissez l'extension de vos futurs fichiers EIX: %=%
@ren *.eix *.%EIX%
@echo Succès .%EIX%
if "%EIX%" == "" GOTO errore
set EPK=
set /P EPK=Choisissez l'extension de vos futurs fichiers EPK:  : %=%
if "%EPK%" == "" GOTO errore
@ren *.epk *.%EPK%
@echo Succès .%EPK%
@echo ---
GOTO fine
:errore
@echo Erreur !
@echo L'extension n'est pas valide !
@echo ---
GOTO esciprogramma
:fine
@echo Le changement est terminé ! Quittez le programme.
:esciprogramma
@pause

 

 

Bien, je pense qu'on peut s'arrêter là, j'ai plus de temps... Et je n'ai plus vraiment d'idée je vais compléter plus tard si nécessaire.

je suis consciente que des tutoriels ont déjà été publiés sur ce sujet, mais il fallait bien les regrouper au lieu d'en faire 9000 partout, si quelqu'un à donc d'autre proposition je suis preneuse. Je suis pas forcément limitée au niveau de la programmation surtout au niveau C++, donc n'hésitez pas si vous avez besoin, je connais mal le jeu, je ne sais pas quels sont les plus gros cheats, comment ils fonctionnent etc...

 

Bonne soirée ! ;)

 

On ne doit pas avoir accès aux box d'alertes, c'est dommage, ça m'a cassé toute ma mise en page...

  • Good 1
  • Love 8

french_banner.gif

Lien vers le commentaire
Partager sur d’autres sites

  • Développeur

Bonsoir,

 

Merci pour ce regroupement de tutoriaux, certains scripts sont probablement partagés ici (notamment le dernier script italien à la fin) voire même l'anti-wait hack partagé ici :

Mais en tout cas merci pour ce regroupement ! :D

+1

 

PS : Oui nous n'avons pas d'accès aux box d'alerte ! C'est bien dommage et ça m'a aussi fait cafouiller une présentation :(

Modifié par Gurgarath
Lien vers le commentaire
Partager sur d’autres sites

Hum, hum hum, je viens de lire le tout...

 

Bon merci du regroupement, j'ai pas grand chose à dire de plus que Gurga, sauf te dire que tu peux si t'es pas limitée en C++ expliquer comment marche la compression et possiblement comment la modifier, afin de bloquer tous les packers sauf le sien (en adaptant par exemple les sources d'eternexus).

 

Merci !

Lien vers le commentaire
Partager sur d’autres sites

  • Robot

C'est justement car il est partagé que j'ai pas tout traduit, et que j'ai laissé "lista" etc... 

 

@Takuma C'est assez compliqué pour moi de ce côté, je suis plus en LZO comme la plus part du temps, et clairement j'ai pas le courage de retourner sous LZO juste pour ça. J'étais entrain d'y penser, je pourrais limite faire un tuto pour forcer le démarrage du client par le launcher, grâce à des arguments et le lanceur en ressources du launcher.

Je me vois pas de recoder un launcher entier et recoder l'UserInterface pour qu'il ne se lance qu'à ce moment, etc... J'ai carrément la flemme !  Merci ;)

french_banner.gif

Lien vers le commentaire
Partager sur d’autres sites

  • Développeur

Bonjour,

 

Premièrement, les clefs d'encryption des packs comme "s_adwEterPackKey" ne sont pas limitées qu'à LZO, c'est juste un système additionnel de clef de protection et tu peux très bien garder ce système avec un autre algorithme de protection, ce n'est donc pas réservé à LZO mais c'est bel et bien un système à part à tout algorithme de compression, j'ai personnellement changé 4 fois d’algorithme de compression (le premier changement était vers LZOPro et le dernier vers un autre que LZO) et j'ai à chaque fois gardé ce fameux système.

 

Bien entendu, il est mieux de changer et l’algorithme & les clefs de cryptage mais aussi tout le système de clefs (c'est actuellement du TEA donc rien qu'un passage en XTEA ou SHA256-SHA512 serait une énorme avancée). Sans parler de l’obfuscation de cette clef et l’encryption totale des packs, à savoir Header & Index dans un même fichier.

 

J'en profite aussi pour préciser qu'adapter Eternexus à un autre algorithme n'est pas spécialement un gain de temps en matière de compression, personnellement, j'ai mon propre packer et je peux compresser mon client bien plus rapidement qu'avec EterNexus, certes, c'est pas aussi joli, mais la limitation du "buffer" d'EterNexus donne ce petit temps d'attente lors de la compression d'un pack. Bien entendu c'est du chipotage car c'est actuellement le meilleur packer sur le marché, mais c'est bon de le préciser ! :P

 

Bonne journée !

 

Lien vers le commentaire
Partager sur d’autres sites

Merci à toi pour ce regroupement de tutoriels !

 

je précise que concernant le MD5, il y a déjà un fichier source pour le MD5 dans les sources, ça éviterait de mettre deux fois le MD5 dans le client ;)

 

Merci pour ces tutoriels ! :D

Lien vers le commentaire
Partager sur d’autres sites

  • Robot
Il y a 21 heures, Gurgarath a dit :

Bonjour,

 

Premièrement, les clefs d'encryption des packs comme "s_adwEterPackKey" ne sont pas limitées qu'à LZO, c'est juste un système additionnel de clef de protection et tu peux très bien garder ce système avec un autre algorithme de protection, ce n'est donc pas réservé à LZO mais c'est bel et bien un système à part à tout algorithme de compression, j'ai personnellement changé 4 fois d’algorithme de compression (le premier changement était vers LZOPro et le dernier vers un autre que LZO) et j'ai à chaque fois gardé ce fameux système.

 

Bien entendu, il est mieux de changer et l’algorithme & les clefs de cryptage mais aussi tout le système de clefs (c'est actuellement du TEA donc rien qu'un passage en XTEA ou SHA256-SHA512 serait une énorme avancée). Sans parler de l’obfuscation de cette clef et l’encryption totale des packs, à savoir Header & Index dans un même fichier.

 

J'en profite aussi pour préciser qu'adapter Eternexus à un autre algorithme n'est pas spécialement un gain de temps en matière de compression, personnellement, j'ai mon propre packer et je peux compresser mon client bien plus rapidement qu'avec EterNexus, certes, c'est pas aussi joli, mais la limitation du "buffer" d'EterNexus donne ce petit temps d'attente lors de la compression d'un pack. Bien entendu c'est du chipotage car c'est actuellement le meilleur packer sur le marché, mais c'est bon de le préciser ! :P

 

Bonne journée !

 

 

Je n'utilise plus là LZO, c'est trop obsolète, je te laisse le constater ici d'ailleurs :

https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO

Tu as du choix, LZ4, etc... De plus j'ai réuni mes eix et epk dans un même fichier.

J'ai également changé tout le système de cryptage, voilà pourquoi je n'ai plus ses parties de client, j'ai c/c d'un autre forum le code je ne sais plus le quel.

 

Il y a 16 heures, Kijaru a dit :

Merci à toi pour ce regroupement de tutoriels !

 

je précise que concernant le MD5, il y a déjà un fichier source pour le MD5 dans les sources, ça éviterait de mettre deux fois le MD5 dans le client ;)

 

Merci pour ces tutoriels ! :D

Oupss j'ai du passé à côté alors ?! 

Sans problème !

Modifié par FBot
  • Love 2

french_banner.gif

Lien vers le commentaire
Partager sur d’autres sites

  • Développeur

Moi aussi j'ai fait pareil, j'utilise un autre algorithme depuis maintenant presque 3 ans, je disais juste que la partie des clefs restait la même, peu importe si tu changes le système de cryptage ou non :D

Lien vers le commentaire
Partager sur d’autres sites

Concernant la compression, le mieux reste un système hybride, le LZ4 est très bon pour les fichiers qui ont tendance à se répéter, mais très mauvais pour les fichiers un peu plus "aléatoires" pour lesquels le LZMA est largement meilleur :)

@Gurgarath pour le cryptage, XTea se comporte comme Tea sur le principe, un buffer d'entrée, un de sortie, et voilà, avec l'avantage que XTea ou XXTea sont beaucoup moins vulnérables, à condition de planquer les clés (voire même les envoier depuis le serveur au lancement du client ;) )

  • Love 1
Lien vers le commentaire
Partager sur d’autres sites

  • Développeur

Non tu n'es pas à la bourre ! Il n'est jamais trop tard ! :o

 

Sinon, c'est vrai Kijaru ! C'est pour ça que je parlais d'une nouvelle méthode de clefs et aussi par ailleurs d'obfuscation de ces dernières, personnellement, la communication de cette clef via la méthode serveur -> client peut être problématique selon moi. Premièrement car ça implique que le client soit déjà dans sa phase de réception des packets et donc que divers packs soit déjà lus (root & partie graphique), ce qui implique au moins une méthode différente de lecture pour les packs root, uiscript & etc (au moins). Après, ça implique aussi une sécurité potentiellement moindre, car là il suffirait de faire un sniff des packets reçus pour voir qu'une clef supplémentaire a transité pour la prendre par la suite (ce qui est une méthode de sniff utilisable et utilisée pour la pong) plus qu'un reverse engineering assez long si l'obfuscation a été faite de manière propre.

Sinon il y a aussi la méthode d'obfuscation ET de transit de clef pour les autres packs, comme l'utilisation du cshybridcrypt ou du panama. Là, ça devient bien plus compliqué d'extraire les packs car il faut là encore intercepter la clef de chaque pack unique mais aussi de trouver la clef globale et la méthode de compression du client pour créer son propre dépacker. Ce qui rendrait la méthode connue de depack du client officiel fonctionnelle (un script python à injecter) mais bien plus compliquée à utiliser. C'est une concession à voir là aussi.

 

Après, dans les deux cas, voire dans tous les cas, ça va éloigner la majorité des gens qui veulent prendre le contenu du client sans spécialement s'y connaître ou en se servant de contenu partagé, ce qui éloigne beaucoup de potentielles attaques ! :P

Lien vers le commentaire
Partager sur d’autres sites

Drapeau blanc ! J'ai pas votre niveau, je me permet juste d'émettre deux supposions :

  • Déjà on peut convertir tous les scripts Python en binaire, ce qui rends leur lecture très compliqué/voir impossible par l'homme (fichier compilé .pyc) Pour le tutoriel.
  • Les clés une fois cryptées avec un assez gros script c'est toujours problématique ? D'accord c'est pas sûr à 900% mais c'est quand même dur de partir de quelque chose, arrivé à un truc si on sait même pas à on doit arriver...

 

Et c'est bien beau tout ça, mais si vous laissez une seule fails python pour injecter dans le programme on peut extraire hein ? :o

 

 

 

Modifié par Takuma
Lien vers le commentaire
Partager sur d’autres sites

il y a une heure, Takuma a dit :

Drapeau blanc ! J'ai pas votre niveau, je me permet juste d'émettre deux supposions :

  • Déjà on peut convertir tous les scripts Python en binaire, ce qui rends leur lecture très compliqué/voir impossible par l'homme (fichier compilé .pyc) Pour le tutoriel.
  • Les clés une fois cryptées avec un assez gros script c'est toujours problématique ? D'accord c'est pas sûr à 900% mais c'est quand même dur de partir de quelque chose, arrivé à un truc si on sait même pas à on doit arriver...

 

Et c'est bien beau tout ça, mais si vous laissez une seule fails python pour injecter dans le programme on peut extraire hein ? :o

 

 

 

Justement on peut pas crypter les clés, on peut juste tenter de les planquer.

Pour le script, oui et non, les scripts se basent sur des fonctions client en c++, il suffit de les rendre inaccessibles en Python pour corriger la faille.

Lien vers le commentaire
Partager sur d’autres sites

  • Développeur

Au sujet du .pyc, ce n'est même pas une sécurité à proprement parler, c'est répandu depuis longtemps et avec un simple décrypteur tu arrives à le contourner, vu que ça ne rend pas le pack plus compliquer à extraire, ça rajoute juste une étape pour décrypter les fichiers .pyc en des simples fichiers .py ! ^^

Sinon, au sujet des clefs cryptées, oui il est possible de les cacher, ça s'appelle de l'obfuscation et c'est toujours utile d'en utiliser, après selon la qualité et la méthode pour la cacher tu peux t'en tirer avec une clef invisible dans l'hexadécimal mais visible dans des logiciels de Reverse E. ou des Debuggers ! C'est toujours compliqué de bien le faire :/

 

Sinon, les scripts pythons peuvent sembler archaïque pour dépacker un client, enfin, ça peut fonctionner, la preuve avec le client officiel, mais si tu as effectué autant de travail pour dépacker, il y a peu de chances que le script arrive à s'injecter et qu'il arrive à faire quoi que ce soit au client !

 

 

Lien vers le commentaire
Partager sur d’autres sites

Bonne initiative, surtout au niveau des explications.

Je pense que pas mal de personnes ne prennent pas la peine d'essayer de comprendre ce qu'ils font en suivant un tuto, au moins ici, chaque chose est expliquée.

 

Niveau compression du client, je crois qu'il faut pas chercher trop loin.

Après quelques comparaisons, je suis passé sous LZ4 surtout pour ne plus utiliser l'algo de base et compliquer la tâche à quelqu'un qui voudrait faire un depacker.

Le client est légèrement plus lourd qu'en LZO (+8% environ). Le premier chargement est plus rapide (-15%) environ. La fluidité en jeu reste la même, à l'oeil nu on ne voit pas beaucoup la différence sur quelques centièmes de seconde.

Il y a beaucoup d'outils pour compresser. Moi je suis parti vers LZ4 qui a été celui qui offrait les meilleurs performances en terme de décompression pour le client.

La compression en LZMA est plus optimale, mais la décompression est plus longue.

Faut peser le pour et le contre et voir ce qui compte le plus.

 

Je ne me suis pas encore tourné sur l'encryption des fichiers, mais oui, regrouper les packs et index ou compiler les index dans le lanceur est un bon moyen d'empêcher de les avoir.

Les clés de cryptages sont jamais très sûres, peu importe les efforts que vous fournirez à les cacher. Le mieux est de refaire un algo unique. C'est beaucoup plus dur à reverse.

Il faudra par contre, comme l'a dit Kijaru, penser à désactiver / retirer les fonctions pack du python dans le lanceur au cas où quelqu'un injecterait un script python dans le client.

Comme d'habitude, il faut éviter de trop compter sur l'anti cheat pour ce genre de choses.

 

Au lieu des pyc, compiler son root / uiscript en C avec cython ? Y'a des tutos depuis pas mal de temps.

Les fichiers python sont convertis en C puis compilés en lib qui finit dans le lanceur.

On gagne environ 10% de performance globale sur l'interface du jeu. Même si certains fichiers en C font + de 50.000 lignes, c'est bien plus rapide qu'en python.

Là encore, à l'oeil nu, à moins d'avoir une fenêtre d'interface très chargées, on ne remarque pas vraiment la différence, mais y'a pas mieux pour obfusquer ses scripts. (A moins d'oublier de le faire avant de faire une mise à jour, comme l'a fait l'offi il y a peu...)

 

C'est tout ce qui me vient pour l'instant !

Le mieux, c'est de ne pas batifoler dans tous les sens. Gardez un jeu à peu près fluide et réfléchissez avant de vous lancer dans de grosses modifications comme ça. Voyez si ça vaut le coup, comparez différentes méthodes etc... Bon chance !

 

  • Love 1
Lien vers le commentaire
Partager sur d’autres sites

  • Développeur

Exact Cassegrain, tu as tout dit et résumé ! Personnellement j'ai utilisé Cython assez tôt, le seul inconvénient reste le temps de la compilation, mais jamais je ne me passerai de cet outil. Pareil pour le LZ4, qui est selon moi le meilleur algorythme de compression / décompression pour Metin2, surtout avec sa version HC. Le couple LZ4 + Cython est un pré-requis dans la majorité des serveurs sérieux car il éloigne la majorité des scriptkiddos et demande peu de modifications comparé à des modifications plus lourdes des packs comme les gros serveurs (ex. Rubinuum & WoM2) qui ont le désavantage d'utiliser un un système de pack se dépackant facilement lorsque l'on a l'outil adapté, au final ils se retrouvent avec la même vague de dépack que lorsque la majorité de l'émulation avait découvert Enigma et les outils permettant de le dépacker.

 

Sinon forcément, compter sur un anti-cheat pour ne pas que son client se fasse dépack est une grosse erreur et c'est surtout une preuve que le client n'est pas si bien protégé que ça.

Lien vers le commentaire
Partager sur d’autres sites

  • 2 mois après...


  • brilliantdiscord_widget
  • Flux d'Activité

    1. 37
    2. 21

      Metin2 en 2020 peut-on en parler?

    3. 0

      METIN2Project

    4. 3

      Ressources - UnPack - Metin2 Client - Officiel

    5. 0

      Barre des tâches d'argent étendue

    6. 16

      Redémarrage automatique des channels

    7. 16

      Multi Logo GM / SGM / GA

  • En ligne récemment

    • Aucun utilisateur enregistré regarde cette page.

Information importante

Conditions d’utilisation / Politique de confidentialité / Règles / Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer.