(я прошу прощения, если это неправильное место, чтобы спросить это. Я думаю, что это определенно связано с программированием, хотя, если это относится к другому сайту, пожалуйста, дайте мне знать)
Я вырос, играя в Pokémon Red and Blueигры, которые были очень увлекательными, но несколько печально известными наличием множества эксплуатируемых глюков (например, см. этот нелепый скоростной запуск игры , использующий повреждение памяти, чтобы превратить экран элемента в редактор шестнадцатеричных кодов).
Недавно я обнаружил интересный спидран игры, в котором используется сбой, называемый «сбой ZZAZZ», чтобы испортить важные области памяти и позволить игроку почти сразу же выиграть игру.Согласно авторскому описанию speedrun , глюк ZZAZZ работает следующим образом:
Чтобы начать битву с трейнером, игре необходимо загрузить много данных, таких как [...] деньги, которые он уступит, если победит.Когда он загружает деньги, все может стать действительно безобразным.По независящим от меня причинам деньги хранятся совершенно по-другому, в игре используется структура данных из трех байтов, и вместо преобразования значения в двоичное, она хранится в «человеческом» представлении.Например, $ 123456 будет храниться как 0x123456 вместо 0x01E240, правильная конверсия.
[Некоторые недопустимые записи в таблице тренеров] указывают на местоположение с недопустимыми денежными данными.Когда игра пытается выполнить арифметику с этими данными в указанной структуре, она сходит с ума и начинает перезаписывать огромные порции оперативной памяти.Более конкретно, для каждого блока из трех байтов два из них будут содержать 0x9999 (максимальная сумма денег, которую может дать тренер).Этот шаблон повторяется много раз через RAM.Чтобы увидеть это лучше, я рекомендую приостановить воспроизведение видео на эмуляторе после того, как наложен указатель ZZAZZ, и установить для просмотра памяти VBA значение 0xD070.
Этот анализ имеет смысл, но я, программист, не могу помочьно интересно, как же программисты написали код, который сделал бы это возможным.Ни о каком подходе, который я могу придумать для написания функции, которая преобразует десятичное число с шестнадцатеричным кодированием в десятичное, никогда не начнется заполнение случайных блоков памяти с 0x9999, если ввод не будет действительным десятичным числом с шестнадцатеричным кодированием.
У меня такой вопрос - без специальной разработки алгоритма, позволяющего завершить таким образом, существует ли простая реализация преобразования десятичного числа с шестнадцатеричным кодом в десятичное, которое может привести к такого рода повреждению памяти при подаче недопустимого значения?
Опять же, если это не по теме, мои извинения.Я думаю, что другие программисты на этом сайте, возможно, тоже выросли, играя в эту игру, и это звучит как интересное упражнение в обратном инжиниринге, чтобы попытаться выяснить, как такой сбой может быть возможным.