Comments 22
Кат-кат-кат
+6
А в чем же основная проблема статьи? Просто я не понимаю пока что вашего жаргона «кат-кат». Хотелось бы исправить это так, чтобы все было, как положено.
0
Теперь можно ставить на огромное поле 1 мину и с первого раза пытаться ее поймать. Получится снайпер.
0
Не знал о существовании программы Cheat Engine, а благодаря вашим статьям узнал — спасибо!
0
inc [rcx+18]
Пробуем изменить данную команду так, чтобы при открытии новой клетки поля прибавлялась не единица, а, например, максимальное целое число типа INTEGER, т.е 4294967295 ( HEX = FFFFFFFF ):
Как можно наблюдать, переполнение буфера работает в нашу пользу, но не в полной мере
Но где же здесь переполнение буфера? Похоже что это был счётчик открытых пустых клеток (я так и не понял этого из вашего рассказа), но какой смысл несут его странные значения?
Для начала давайте представим архитектуру любого стандартного приложения. Получится примерно следующее:
1) Подключение библиотек, используемых в программе
2) Описания классов и реализация их методов
3) Точка входа. (В си, например, это функция main() )
Давайте сначала представим архитектуру любого стандартного города. Получится примерно следующее:
1) Завоз материалов для строительства
2) Чертежи домов
3) Вокзал (в Питере, например, это Московский вокзал).
+9
Переполнение целочисленного буфера изображено на слайде, который тремя ниже того, который вы привели. Под «странным значением» вы подразумеваете максимальное целое число типа INT?
0
Переполнение целочисленного буфера изображено на слайде
Я бы на таком слайде ожидал увидеть дамп памяти, в котором отмечены границы буфера (кстати, какого?) и указано что было перезаписано в результате его переполнения.
максимальное целое число типа INT?
Я уж не знаю, что вы называете типом INT, когда у вас 64-битная система, а дизассемблер не пишет ни dword ptr ни qword ptr.
Мне сначала показалось, что система ваша 32-битная, но тогда прибавление 0xffffffff равносильно вычитанию единицы.
А так, ну число какое-то, большое…
+1
При чём здесь переполнение буфера?
+2
Просто фраза красивая, видимо.
0
Переполнение целочисленного буфера. Иначе же, что это по вашему? Где-то в игре присутствует переменная-счетчик типа INTEGER, которую мы пытаемся переполнить.
0
Я вам выше привёл ссылку на то, что обычно называют переполнением буфера.
В двух словах, переполнение буфера — это непреднамеренная запись программой данных в свою память. Непреднамеренная, потому что программа намеревалась записать данные в определённый массив/буфер, но в силу ошибок обработки адресов/индексов массива промахнулась мимо целевого буфера и переписала другие данные.
Целочисленные переполнения — это отдельный класс проблем, он может быть связан с буферами, а может быть не связан с ними. Вот я думаю, что если бы сапёр пытался писать в память, адрес которой отличается на 4Г от того, что он ожидал, он бы грохнулся с сегфолтом, а поскольку этого не произошло я и высказал сомнение, что имеет место переполнение буфера.
В двух словах, переполнение буфера — это непреднамеренная запись программой данных в свою память. Непреднамеренная, потому что программа намеревалась записать данные в определённый массив/буфер, но в силу ошибок обработки адресов/индексов массива промахнулась мимо целевого буфера и переписала другие данные.
Целочисленные переполнения — это отдельный класс проблем, он может быть связан с буферами, а может быть не связан с ними. Вот я думаю, что если бы сапёр пытался писать в память, адрес которой отличается на 4Г от того, что он ожидал, он бы грохнулся с сегфолтом, а поскольку этого не произошло я и высказал сомнение, что имеет место переполнение буфера.
+2
Вообщето все результаты сапера хранятся в обычном текстовом файлике, который можно поправить руками и вуаля вы открыли все мины за 1 сек. Помню когда то мой отец(любитель этой игры), долго возмащался что я задень побил его годовой рекорд))
0
Объясните лучше, как в подобных ситуациях быть?
Скриншоты
Речь о правом нижнем угле.
0
Если вы использовали «переполнение буфера», то, как я уже говорил, данный способ не может гаранировать 100% победы. Вероятность победы прямопропорциональна количеству открытых клеток при первом клике по полю. Т.е чем больше клеток удалось открыть, тем большая вероятность отсеивания большего количества мин. В данном случае отсеивается не менее 50% клеток поля, а вместе с ними и 50% всех мин( об этом сказано с статье и видно из вашего скрина ). Далее же придется полагаться на свой опыт в игре и удачу, так как способ, основанный на переполнении буфера, лишь упрощает процесс игры, а не полностью его решает :)
0
Вы молодец, что занялись подобного рода развлечениями. Копаться в дизассемблированном коде игр приятно и, иногда, небесполезно. Читать об этом тоже занятно, тем более, что пишите вы интересно. Продолжайте изыскания, пишите еще.
Теперь о том что плохо.
В первой части вашей статьи написана ерунда. Код, на который вы обратили внимание (inc[rcx + 0x18]), действительно подсчитывает количество открытых клеток. Но, во-первых, когда вы заменяете его на (add[rcx + 0x18], 0xFFFFFFFF) не происходит никакого переполнения буфера, просто вместо прибавления единички, она отнимается. Зато, благодаря тому, что вы варварски затираете две инструкции, (xor edx, edx и mov r13, r10) происходит небольшой побочный эффект. Кстати, попробуйте, убрать только mov r13, r10, тоже интересно получается. Во-вторых, этот счетчик открытых клеток служит только для одного: определять когда игра закончилась. Это происходит так:
(if (board->width) * (board->height) == board->openedFields + board->numMines) {
board->gameWin();
}
так что, изменяя эту ячейку памяти, вы абсолютно ни на что не влияете.
Теперь о том что плохо.
В первой части вашей статьи написана ерунда. Код, на который вы обратили внимание (inc[rcx + 0x18]), действительно подсчитывает количество открытых клеток. Но, во-первых, когда вы заменяете его на (add[rcx + 0x18], 0xFFFFFFFF) не происходит никакого переполнения буфера, просто вместо прибавления единички, она отнимается. Зато, благодаря тому, что вы варварски затираете две инструкции, (xor edx, edx и mov r13, r10) происходит небольшой побочный эффект. Кстати, попробуйте, убрать только mov r13, r10, тоже интересно получается. Во-вторых, этот счетчик открытых клеток служит только для одного: определять когда игра закончилась. Это происходит так:
(if (board->width) * (board->height) == board->openedFields + board->numMines) {
board->gameWin();
}
так что, изменяя эту ячейку памяти, вы абсолютно ни на что не влияете.
0
Sign up to leave a comment.
Articles
Change theme settings
Исследование игры-головоломки «Сапёр» (продолжение)