keng

Помогаторы
  • Публикации

    1 562
  • Зарегистрирован

  • Посещение

  • Days Won

    54

keng last won the day on June 25

keng had the most liked content!

Репутация

285 Codecaver

О keng

  • Звание
    Who u gonna call? Gamehackers!
  • День рождения 16.02.1990

Контакты

  • Сайт
    http://keng.gamehacklab.ru
  • Skype
    et.keng

Информация

  • Пол
    Мужчина
  • Город
    Москва
  • Интересы
    Ууу, всякое разное!
  1. Привет, читатель! Ты сейчас читаешь это, потому что в тебе есть интерес ко взлому игр и низкоуровневому программированию, ибо этот мини-блог будет посвящен как раз этой тематике. Если конкретнее, то я постараюсь показать и рассказать о том, как пишутся движки для трейнеров. Если ты вдруг не в курсе, то трейнер - это программа, позволяющая всячески изменять поведение компьютерной игры. Например, сделать ГГ (главного героя) бессмертным или же выдать ему миллион игровых очков. В общем, сделать нечто такое, чего штатный игровой процесс не подразумевает. Если ты вообще не понимаешь, о чем идет речь, то сначала поищи в интернете, как создаются читы для игр, а потом уже возвращайся сюда. Я буду предполагать, что взламывать игры (искать значения в памяти и немного пользоваться отладчиком/дизассемблером) ты уже умеешь. Итак, поехали! Весь исходный код я буду хранить в репозитории на github, ссылку на него и на нужный коммит буду выдавать в конце статей, если это потребуется. С чего начнем? А начнем мы с выбора инструментов. Мои коллеги по цеху давно и очень успешно создают подобные этому обучающие материалы, но на высокоуровневых языках - C++ и C#, а местами и на Delphi. К счастью, мы от подобного избавлены, так что выбор у нас один - Ассемблер. Первая проблема заключается в том, что их много и они местами сильно различаются, так что отныне и в обозримом будущем я буду использовать [flat assembler]. Идешь на сайт в раздел "Download" и качаешь последнюю версию flat assembler for Windows (на момент написания этой статьи - 1.71.63). Скачанный архив нужно куда-то распаковать и можно запускать местную среду разработки - fasmw.exe. А вот и код на сегодня: ; main.asm format PE GUI 4.0 include 'win32wxp.inc' invoke ExitProcess,0 data import library kernel32,'KERNEL32.DLL' import kernel32,\ ExitProcess,'ExitProcess' end data Что происходит? ААА! Да ну, все в порядке. Разберем построчно. Символ точки с запятой обозначает комментарий. Сразу берем за правило, что в каждом файле исходного кода первой же строчкой будет идти его имя. В местной среде разработке (как и в любой другой) есть возможность запустить программу на исполнение, предварительно ее скомпилировав (если язык разработки является компилируемым). В твоем случае нужно выбрать меню "Run->Run" или ткнуть F9. Если звезды сложатся удачно, то с виду ничего не произойдет. Отсутствие ошибок - это половина успеха! Но вернемся к разбору исходного кода. Первой осмысленной с точки зрения компилятора строчкой идет вторая. Она указывает, что же за формат такой должен получиться на выходе. Формат, в смысле - исполняемого файла. EXE, то есть. В Windows основным таким форматом является PE, он же Portable Executable. Подробнее про него можно почитать в Интернете, например [тут]. GUI говорит компилятору о том, что это будет приложение с графическим интерфейсом пользователя, а не консольно-текстовое, что нам и нужно. И пока хватит с этой строчки, подробности про нее можно почитать на сайте ассемблера в разделе Documentation. Далее у нас идет директива include. Тут все просто - компилятор ищет файл с таким именем и банально вставляет вместо всей этой строчки его содержимое, как есть. Или ругается, если что-нибудь пошло не так. Если ты очень любопытен, то можешь найти этот файл в папке с ассемблером и посмотреть, что в нем написано. Пока что я скажу, что в нем описываются функции WinAPI - это такой здоровенный набор функций Windows, из которых и состоят, по факту, все программы. Запустить программу? WinAPI! Открыть файл? WinAPI! Поменять картинку на рабочем столе? WinAPI! И вот так всегда. Все в Windows сводится к большой стопке разных функций WinAPI, вызванных в нужном порядке. Хочешь подробнее прямо сейчас - ищи в Интернете (подсказка: MSDN). Что там идет дальше? Точно! Единственный, на самом деле, кусочек реального кода программы, а не какой-то вспомогательной фигни. invoke - это вызов функции. После этой команды идет имя функции и ее аргументы, если они есть. Самая настоящая команда ассемблера! На самом деле, конечно, это макрос, но об этом потом. Как бы это выглядело в реальной жизни? Представь, что надо заварить 10 чашек чая. И даже есть функция (по сути - просто набор действий) под названием "СделатьЧай". Что должна делать эта функция? Взять чашку, насыпать в нее чай, налить кипяток, добавить сахар, перемешать. Так и пишем: СделатьЧай: 0. Взять чашку 1. Насыпать в чашку чай 2. Налить в чашку кипяток 3. Добавить в чашку сахар 4. Перемешать Допустим, что мы пишем на ассемблере программу, которая заваривает чай. И что "СделатьЧай" - это функция WinAPI. Вот так будет выглядеть ее вызов: invoke СделатьЧай Ага! Ты сразу спросишь - "а нафига ноль в конце той строчки? что еще за аргументы такие?". Аргумент - это просто некое значение, передаваемое функции в момент ее вызова. Например, "СделатьЧай, 10 раз". Если бы наша функция, делающая чай, принимала аргумент "Количество" и была бы написана так, что был бы в ней цикл - "делать чай, пока количество не станет равным 0, после каждой чашки отнимать от количества 1", то делала бы она за один вызов 10 чашек и вместо: invoke СделатьЧай ; 0 чашка invoke СделатьЧай ; 1 чашка invoke СделатьЧай ; 2 чашка invoke СделатьЧай ; 3 чашка invoke СделатьЧай ; 4 чашка invoke СделатьЧай ; 5 чашка invoke СделатьЧай ; 6 чашка invoke СделатьЧай ; 7 чашка invoke СделатьЧай ; 8 чашка invoke СделатьЧай ; 9 чашка Можно было бы написать всего лишь: invoke СделатьЧай,10 ; 10 раз И оно бы внутри в цикле 10 раз вызвалось. Удобно ведь? Конечно! И места меньше занимает. Функция у нас вызывается всего одна - "ExitProcess" с аргументом в виде нуля. Знатоки английского языка могут догадаться, что эта функция делает. Завершает процесс. Выходит. Совсем. Да, все так - все, что программа делает на данный момент - это успешно завершает свою работу. Успешно, потому что аргумент у нее "0". Аргумент этой функции - это так называемый код возврата. Он сильно нужен (зачем-то) Windows и она решает именно по коду возврата, хорошо ли было программе во время работы или плохо. Вот случись ошибка - завершаешь программу с не-нулевым кодом возврата и все, Windows об этом будет знать. Когда-то давно это была единственная возможность узнать результат работы - эти самые коды возврата были описаны в документации к программам. Так-то! Итак, выяснилось, что оно начинает работу и сразу же ее завершает, зато успешно. Ну а что, надо ведь начинать с чего-то, верно? Остался последний кусок. Кусок этот отвечает за предоставление нашей программе доступа к WinAPI. Эти все функции - не магия и не само собой оно работает, а где-то в системе хранится. Если точнее, то хранится в библиотеках, которые имеют расширение DLL, хотя тоже являются исполняемыми файлами. Да, они тоже исполняемые, просто не умеют сами запускаться - их должен загрузить в себя другой процесс (работающий EXE файл) и можно будет вызывать функции загруженной библиотеки. То, какие функции можно вызывать, а какие нельзя, определяется библиотекой, а процесс, загрузивший ее, может только попросить указать ему место, где в библиотеке нужные ему функции лежат. Этим и занимается секция data import - end data. Мы указываем, что нам нужно загрузить библиотеку kernel32.dll, а из нее - функцию по имени ExitProcess. Что происходит при запуске? EXE-файл загружает библиотеку. Та сообщает ему, где искать адрес функции ExitProcess. После этот самый адрес и подставляется команде invoke. Такой вот компилятор умный. На этом пока закончим. [Репозиторий] на github. [Коммит].
  2. Собственно, в этом весь мой вопрос и заключается - зачем этим всем заниматься в managed-среде. Ну банально же не для этого язык.
  3. Тогда я бы посмотрел на пример кода.
  4. MSVS не заточена под конкретный язык. В виме же: Есть. Есть. Есть. Потому что по сути IDE - это текстовый редактор, из которого можно вызывать компилятор и отладчик. И все. Не три окошка, а одно, можно и так сказать. Лично я отладчиком не пользуюсь, но у меня при этом есть и навигация (как по дереву всего проекта, так и по вкладкам и буферам), подсветки/автоподстановки, анализ и рефакторинг на лету, интеграция с VCS, деплой одной кнопкой, тесты и прочие автосохранения. Проблема тут только в том, что по сравнению с MSVS оно банально быстрее работает и не жрет оперативку. Сядь и подумай, что бы тебе хотелось сделать или облегчить. Банально поиск по файлам или сортировку. Как только придумаешь - разбивай на подзадачи и выполняй их шаг за шагом, по одной.
  5. В виме плагинов в сотни и тысячи раз больше, чем в MSVS. Там есть абсолютно все, чего душе угодно, уровень кастомизации - просто запредельный. Мое окружение с 10-15 плагинами при этом кушает <50 мегабайт ОЗУ, так что и тут MSVS, мягко говоря, проигрывает.
  6. Ну, технически, можно поменять способ хранения данных в памяти, тогда это будет уже не просто список указателей, а, допустим, дерево. Впрочем, я не знаю, зачем это может быть нужно.
  7. Разница в том, что после вызова EndScene() картинка все еще будет лежать в бэк-буфере и только вызов Present() этот самый буфер поставит вместо основного. Технически, разница не очень большая.
  8. Quake, поломанный при помощи MTC.
  9. Языков программирования - великое множество, так что горячо советую начать с теоретических основ информатики. Разберешься, как работает сам компьютер - будет хотя бы от чего отталкиваться. Дальше я бы посоветовал тот же python, после его изучения и некоторой практики уже сам сможешь понять, что изучать после него. В принципе, можно было бы и ассемблер приплести, но у него сфера применения довольно узкая и (исходя из моей статистики) с него довольно сложно переходить на языки более высокого уровня.
  10. ВНЕЗАПНО, не тот же. По моим ощущениям, там задушенный id Tech 6 + Saber, потому что QC и DooM на одном и том же железе выдают безумно различающуюся производительность, где-то раз в пять (по fps).
  11. Про взлом ничего не написано. ;]
  12. Разработчик - не беседка, и вполне похоже на Q3. Мне понравилось, поиграл немного во время предыдущей волны.
  13. Их нужно будет зарегистрировать [тут]. Кто забрал - отпишитесь.
  14. call - это push + jmp в одном флаконе. На стеке сохраняется адрес возврата.