Как что-то сделать, при этом ничего не делая
Мания чисел
Вообще я опечатался. Хотел сначала "магия" написать. Но вроде и так ничего =)
Сразу оговорюсь, что ничего сверхъестественного ниже не написано.
Суть и предыстория, коротко и по пунктам:
- мы делали игрушку
- мы постарались защитить ее от взлома
- мы даже писали нечитаемый код (да-да, пусть враги боятся =))
...
- пришел Вася и все сломал через ArtMoney или что-то подобное.
Просто подменил значения в памяти и стал молодцом. Ну, Вы же знаете как это работает - запускаем программку, выбираем процесс (в случае с Firefox это будет PluginContainer), и сканируем память, выделенную этому процессу, на предмет интересующего числа (ну или строки, что, вообще-то, экзотика). Далее несколько раз фильтруем и находим нужный нам адрес. Далее просто подменяем значение по этому адресу - и вот мы чемпионы!
По сути дела, защититься от подмены значений в адресе памяти можно только одним способом - это не хранить это значение в памяти.
Epic fail, скажете Вы? - а вот и нет.
Первое же что пришло в голову - это хранить 2 левых значения, сумма или разность которых в итоге даст нам значение, которое мы хотим спрятать. Таким образом на свет появились 3 класса:
- HiddenInt
- HiddenUint
- HiddenNumber
Можно создать новый объект-хранилище (например HiddenInt) и по необходимости задавать/получать значение через геттер-сеттер. Само значение в памяти не хранится. Смысл работы, я думаю, всем понятен, если интересует реализация - милости прошу заглянуть во вложения.
ЗЫ
Туда же закинул битовую маску - ну просто так, чтобы не скучно было. Мало ли Вам захочется хранить 32 булевых переменных в одном числе =)
Всего комментариев 55
Комментарии
![]() ![]() |
|
Артмани/оматик разве не умеет ещё искать "число, которое выросло на 10"? По-моему можно было что-то такое делать.
Я когда-то думал, что если такое делать, то надо множить ещё на рандомное число. Хотя сейчас наверное взял бы два/n чисел и попеременно складывал с нужным. UPD: да, можно задампить память, а потом искать "число, которое выросло на n". UPD2: посмотрел код - не прокатит искать "число, выросшее на n". Рандом правда не самая быстрая функция, но там не нужна скорость, идея оч. даже =) |
|
Обновил(-а) -De- 08.12.2010 в 23:26
|
![]() ![]() |
|
А какой практический толк? Что такое нужно защитить в клиенте?
|
![]() ![]() |
|
Есть еще возможность замедлять время - может быть критично для некоторых игр. Не помню как прога называется...
|
![]() ![]() |
|
Это уже делает нормальный подход к играм, где рендер построен на дельте от getTimer.
|
![]() ![]() |
|
Кстати, кривовато написан HiddenNumber (походу вообще не тестили) - Number.MIN_VALUE вообще-то положительный, ну и прибавление Number.MIN_VALUE бывает, не изменяет число вообще, а вот отнимание Number.MAX_VALUE может устроить пц числу. Там надо степень искать и от неё уже там плясать, чтоб точность не уменьшить (прям даже и не напишу сам сходу %)
Шоп понять о чем я, шайтан-код: |
|
Обновил(-а) -De- 09.12.2010 в 00:08
|
![]() ![]() |
|
Цитата:
прибавление Number.MIN_VALUE бывает, не изменяет число вообще
Цитата:
Number.MIN_VALUE вообще-то положительный
Цитата:
Что такое нужно защитить в клиенте
Сейчас под пользователя заводится сессия и есть некий теоритический максимум очков, который можно получить за эту сессию. Если игрок его каким-то образом вычислит, он будет слать их при каждой возможности. В данном случае, без декомпила флешки ему это будет сделать несколько сложнее. |
|
Обновил(-а) gloomyBrain 09.12.2010 в 00:19
|
![]() ![]() |
|
Обычно на сервер шлется промежуточные результаты, а сервер сам считает количество очков. Но в целом мысль уловил.
|
![]() ![]() |
|
Цитата:
Делает из единички 0, см. код выше
Цитата:
В половине случаев, когда value больше 0, ровно оно получится
Цитата:
если приспичит, то декомпильнёт
|
|
Обновил(-а) gloomyBrain 09.12.2010 в 00:36
|
![]() ![]() |
|
Цитата:
Number.MIN_VALUE * Math.random() таки в половине случаев равен Number.MIN_VALUE
Там проблема была в другом месте. Перезалил. Решается путем использования только MIN_VALUE в качестве дельты |
|
Обновил(-а) gloomyBrain 09.12.2010 в 01:31
|
![]() ![]() |
|
Тогда оно не шифрует и от артмани не защищает...
trace(1 - Number.MIN_VALUE == 1 + Number.MIN_VALUE);//true Числа с плавающей запятой знать бывает не лишне вообще %) http://docs.sun.com/source/806-3568/ncg_goldberg.html Лучше, например, так. Могут быть какие-то приколы с потерей точности на округлении, а могут даже и не быть %) public function set value(value:Number):void { _delta = -Math.random() * value; _storedValue = value + _delta; } |
|
Обновил(-а) -De- 09.12.2010 в 01:50
|
![]() ![]() |
|
Цитата:
при желании можно менять адрес переменной в памяти по мере необходимости
|
![]() ![]() |
|
Цитата:
А не поделитесь - как именно?
Можно попробовать так: пакуем набор критических переменных в ByteArray. Потом, случайным образом "перемещаем" его в памяти путем создания нового массива с копированием данных из прежнего. В ас-коде доставать их можно по прежнему указатлю, а вот физически они будут в другом месте. import flash.utils.ByteArray; class MemMove { private var actualMemPtr:ByteArray; private static const NEEDED_SIZE:uint; .... public function MemMove():void { actualMemPtr = new ByteArray(); actualMemPtr.length = NEEDED_SIZE; // тут actualMemPtr указывает на адрес типа 0х003315000 // пакуем данные в массив } private function memMove():void { var tmp:ByteArray = new ByteArray(); tmp.length = NEEDED_SIZE; // тут tmp указывает на адрес типа 0х00D80000 // пакуем данные в массив tmp.writeBytes(actualMemPtr, 0, NEEDED_SIZE); actualMemPtr.clear();// старый массив при этом нисколько не трется, оставляя в памяти дополнительный мусор actualMemPtr = tmp; // вуаля! actualMemPtr указывает на адрес 0х00D80000 } } |
|
Обновил(-а) iNils 09.12.2010 в 15:42
|
![]() ![]() |
|
А зачем мусорить фейки, если можно изменить все переменные и нужная переменная поменяется точно также, а изменение фейков не повлияет на работу программы, надо так чтобы при изменении фейка происходил краш.
|
|
Обновил(-а) Tr1te 09.12.2010 в 12:33
|
![]() ![]() |
|
Не понял. Вот мы рассовали одну и туже строку(пусть) по разным адресам. Так? Потом актуальное значение поменялось, вместе поменялись и фейки. Как ты отследишь, по какому адресу лежит актуал?
Крэш зачем? Впрочем, после реалока массива и перезаписи его старой области из-под сканера, когда она уже под другие данные была перевыделена, может и уронить. Важно, что ты актуал не сможешь вычислить. И это, фейки - это совсем не обязательно var a, b, c.... Можно создать пару массивов и писать туда байтиками эти самые фейки. Сканер на них все-равно споткнется. ЗЫ. Да можно даже в пределах одного массива блок актуальных данных перемещать, дробить, склеивать обратно по какому то алгоритму. |
|
Обновил(-а) alexcon314 09.12.2010 в 12:48
|
![]() ![]() |
|
@Tr1te
Цитата:
Так что это не работает
@alexcon314 Да, интересная идея |
![]() ![]() |
|
Вообще "нельзя производить расчёты на клиенте" не из-за артманей в основном, а из-за декомпиляции, так что опасайтесь как и опасались.
|
![]() ![]() |
|
И что даст декомпиляция, люди узнают формулу? Мне не страшно.
|
![]() ![]() |
|
Вообще-то из за снифферов, но да ладно.
|
![]() ![]() |
|
Там тоже есть свои методы. Но это уже другая история.
|
![]() ![]() |
|
Читаю этот тред и плачу
gloomyBrain, ПОЧЕМУ у вас клиент что-то считает и почему .... у вас сервер эти значения вообще приниманиет!!! |
|
Обновил(-а) iNils 10.12.2010 в 14:27
|
![]() ![]() |
|
зачем их защищать?
|
![]() ![]() |
|
![]() |
![]() ![]() |
|
Плюсую к Хемуле, я буду рад если я смогу читерить если очень захочу. А если не смогу - уйду. Игра теряет клиента на пустом месте, ага.
Но про п2п согласен. |
![]() ![]() |
|
А есть еще казуальные игры с записью рекордов. Там тоже логику на сервере всю делать?
|
![]() ![]() |
|
Запись рекордов - это уже взаимодействие с другими игроками. Мы тут спорим о чисто сингловых.)
|
![]() ![]() |
|
Цитата:
Запись рекордов - это уже взаимодействие с другими игроками.
|
![]() ![]() |
|
Цитата:
Если нет записи результата, то смысл что-либо хакать отпадает в принципе.
А так да, высокая позиция в публичной таблице рекордов даёт намного больше признания и ощущения собственной значимости. ^_^ |
|
Обновил(-а) Хемуль 10.12.2010 в 16:56
|
![]() ![]() |
|
И что? Смысла, то хакать нет.
Zebestov, ты прав. Я даже и не думал, что это придется объяснять. |
![]() ![]() |
|
Psycho Tiger, ну почему? Во времена массовой диабло мании, игры ломали что бы прокачать гера, пойти с ним на турнир и всех грохнуть))
|
![]() ![]() |
|
Щаз просто пилят больше, на прокачку времени не остается =)
|
![]() ![]() |
|
Пилят кого?
|
![]() ![]() |
|
Бюджет обычно
|
![]() ![]() |
|
а в 99% случаев вообще то проще даже не ломать фдэшку, а просто заснифать запрос на сервер сохранения очков и подделать его.
|
Последние записи от gloomyBrain
- Очередной загрузчик. Часть 2. (05.12.2012)
- Очередной загрузчик. Часть 1. (04.12.2012)
- Пул объектов (31.08.2011)
- Мания чисел (08.12.2010)
- Отправка файлов на сервер (допилил) (24.10.2010)