Używam Unity do stworzenia gry 2D, która będzie całkowicie offline (co jest problemem), rozgrywka wymaga wprowadzenia pewnych ciągów znaków na określonych poziomach i kompilacji Unity do bibliotek DLL, które można łatwo poddać inżynierii wstecznej, więc jest istnieje sposób na ochronę tych ciągów (gra jest offline, więc nie mogę pobrać z innego źródła)?
Gra w dużej mierze opiera się na tych ciągach i tak, jestem świadomy zaciemniania, ale chcę czegoś bardziej solidnego. I wiem, że najłatwiejszym wyjściem byłoby zrobienie wszystkiego online ze źródła danych, ale zastanawiałem się, czy to możliwe.
unity
c#
anti-cheat
TheBinaryGuy
źródło
źródło
strings
program.Odpowiedzi:
Nie przechowuj tych ciągów, przechowuj ich (kryptograficzny) skrót.
(Kryptograficzna) funkcja skrótu, taka jak szyfrowanie, jest sposobem na przekształcenie łańcucha w „bełkot” (zwany hashem), ale w przeciwieństwie do szyfrowania, nie można uzyskać oryginalnego łańcucha z tego skrótu (chyba że można użyć siły lub skrótu funkcja jest zepsuta). Większość (jeśli nie wszystkie) funkcji skrótu pobiera ciąg o dowolnej długości i zwraca ciąg o stałej długości (w zależności od funkcji).
Jak sprawdzić, czy ciąg, który wprowadził użytkownik, jest poprawny? Ponieważ nie można uzyskać poprawnego ciągu z skrótu, jedyne, co można zrobić, to skasować przypuszczenie użytkownika i porównać go z poprawnym skrótem.
Ostrzeżenie (autor: Eric Lippert): NIE UŻYWAJ wbudowanej funkcji
GetHashCode
jako takiej - jej wynik może się różnić w zależności od wersji i platformy .NET, dzięki czemu Twój kod działa tylko na określonych wersjach i platformie .NET.źródło
To, co próbujesz zrobić, jest zarówno daremne, jak i bezcelowe.
Jest to daremne, ponieważ nie ma sposobu, aby poprawnie ukryć informacje znajdujące się na komputerze użytkownika. Każdy, kto poświęci wystarczająco dużo czasu, znajdzie to. Możesz to utrudnić, ale nigdy nie możesz temu zapobiec. Jeśli go zaszyfrujesz, musisz gdzieś przechowywać klucz szyfrujący i algorytm. Bez względu na to, ile warstw szyfrowania dodasz, najwyższa warstwa zawsze musi być niezaszyfrowana, aby gra mogła działać.
Jest to również bezcelowe, ponieważ żyjemy w erze Internetu. Kiedy Twoja gra stanie się po prostu popularna, hasła zostaną opublikowane w Internecie.
Wszystko, co możesz zrobić, to zaufać graczowi, że nie zrujnuje własnego doświadczenia w grze, wyszukując informacje, których gra nie powinna mu jeszcze powiedzieć. Zdecydowana większość graczy i tak nie rozpocznie inżynierii wstecznej. A jeśli nieliczni, którzy posiadają niezbędne umiejętności, robią to, to z własnej winy.
źródło
Jeśli taka rzecz jest naprawdę pożądana, to zamiast mieszania, możesz rozważyć zbudowanie ciągów z numerycznej wartości wejściowej w czasie wykonywania.
Zaletą jest to, że jak wskazał @Philipp, próba ukrycia kodów w pliku wykonywalnym jest nieco bezcelowa, jeśli można się spodziewać, że zostaną opublikowane w Internecie. Zaszyfrowane czy nie, to samo słowo znalezione w Internecie i wprowadzone do gry da ten sam skrót i będzie działało tak czy inaczej.
Z wyjątkiem ... chyba że kod innej osoby nie działa dla ciebie. Co możesz w prosty sposób zrobić - nie w 100% odporne na manipulacje, ale dość trudne do obejścia dla przeciętnego użytkownika. Wszystko, co jest tak proste, jak „Generator nazw elfów online”, może zrobić (może być dowolnie proste, naprawdę nie wymaga dużo silnika tekstowego genov markov, wystarczy pobrać 4-5 sylab z losowej listy).
Po prostu wygeneruj liczbę specyficzną dla użytkownika lub maszyny, nie musi ona nawet być całkowicie unikalna ani bardzo odporna na manipulacje. Coś, co prawdopodobnie różni się u większości ludzi i jest mało prawdopodobne, aby zmieniało się regularnie, np. Nazwa sieciowa komputera, adres MAC lub identyfikator GUID dysku systemowego, cokolwiek (numer seryjny karty graficznej może być bardzo złypomysł, ponieważ użytkownicy prawdopodobnie uaktualnią procesory graficzne). Dodaj do tego kod numeryczny, do którego odnosi się kod odblokowujący, i wprowadź go do generatora słów. Ale bądź przygotowany na udzielenie odpowiedzi na pytania wsparcia, gdy gracze korzystają z dwóch komputerów lub zmieniają kartę sieciową (co jest niezwykłe, ale nie niemożliwe). Dobrym pomysłem może być wygenerowanie losowego identyfikatora tylko raz i zapisanie go z ustawieniami gry. W ten sposób przynajmniej nie psuje istniejących instalacji na tym samym komputerze, jeśli coś się zmieni.
Możesz też użyć numeru seryjnego gry, który jest unikalny i zadziała, jeśli użytkownik zmieni sprzęt (jak na ironię może to promować piractwo, ponieważ wspólne kody odblokowujące działają w przypadku pirackich seriali, ale nie dla legalnych klientów!).
Pamiętaj, że zapobieganie oszustwom nie musi być dobrą rzeczą. W trybie offline (tj. W grze niekonkurencyjnej) zazwyczaj nie ma problemu, jeśli użytkownik oszukuje i pobiera kody gdzieś, a nie z gry. Oszukuje tylko siebie. Kogo to obchodzi.
Z drugiej strony, zbyt wiele im przeszkadza, jeśli naprawdę chcą oszukiwać, to świetna okazja do pełnego wkurzania płacących klientów.
Więc ... zanim zrobisz coś w ten sposób, zastanów się dokładnie, czy naprawdę tego chcesz i czego chcesz. Całkiem możliwe, że ciągi czytelne dla człowieka (lub w trywialny sposób „nieczytelne” za pomocą xor) są po prostu wystarczająco dobre i rzeczywiście preferowane.
źródło
hash(serial + 1)
aby uzyskać liczbę odpowiadającą pierwszemu kodowi. Następnie podaj to do generatora słów, który pobiera, powiedzmy, jedną sylabę z listy 16 na każde 4 bity wejściowe. Proszę bardzo, poszczególne „słowa” dla każdego użytkownika.hash(serial+1)
po pobraniu, co powstrzyma użytkownika przed obliczeniemhash(serial+1)
? Po pobraniu programu użytkownik ma dostęp do wszystkiego, co robi program.hash(serial + 1)
. Więc co? To nie jest problem. Spójrz, jeśli ktoś zainwestuje od jednej do dwóch godzin (prawdopodobnie 6-8 godzin dla typowego „użytkownika” bez doświadczenia programisty) tylko po to, aby się oszukiwać, no cóż… pozwól mu. Chodzi o to, że działa to dla jednej osoby, ale nie dla wszystkich i nie jest konkurencyjne ... więc nie ma problemu.Jeśli nie musisz pokazywać ciągów, prawdopodobnie masz pomysł na haszowanie. Z drugiej strony, jeśli musisz pokazać je użytkownikowi, istnieje kilka innych sposobów, aby uniknąć ich bezpośredniego wyświetlania w bibliotece DLL.
Jednym ze sposobów radzenia sobie z tym oprócz szyfrowania lub innego zaciemniania łańcuchów jest ich rozbicie. Może po prostu masz posortowany alfabetycznie słownik wszystkich możliwych słów ze wszystkich ciągów w grze. Następnie umieść gdzieś tablicę, która pozwala ci poskładać słowa w potrzebny ciąg przez indeksowanie do tablicy słów. W ten sposób nie masz kompletnych ciągów nigdzie w grze. Do odszyfrowania ciągów nie jest potrzebny klucz główny. Dane określające ich kolejność mogą znajdować się w całym źródle, jeśli na przykład każda funkcja, która użyła łańcucha, ma tablicę indeksów lokalnych dla funkcji. Nie jestem pewien, jak praktyczne jest to w twoim konkretnym przypadku, ale jest to jeden ze sposobów na zrobienie tego.
Być może łańcuch składa się z kilku słów, ale ostatecznie są ułożone w różnych porządkach. Na przykład mogą być potrzebne następujące 2 ciągi:
Twoja lista fraz zawierałaby zarówno „niedźwiedzia”, jak i „mojego domu”, ale miałbyś dużą listę innych fraz, które można by umieścić między nimi, więc zastanawianie się, który z nich byłby tak samo trudny, jak faktyczne puzzle w grze (lub cokolwiek innego). Na przykład, zwroty akcji mogą być „przechodzone”, „spalone”, „przepchnięte”, „chronione przed”, „oddzielone od”, „magicznie wyprodukowane” itp.
Możesz to wykorzystać w swojej grze, ustawiając indeksy na podstawie tego, co gracz zebrał lub zrobił. Dlatego w grze nie będzie głównej listy indeksów. Zostaną one wygenerowane przez gracza grającego w grę.
źródło
strings
z pliku wykonywalnego.