Привет! Я попробую объяснить, но начну немного издалека. Вот есть игра: ****** *Игра* ****** Это - загруженный в оперативную память и запущенный на исполнение бинарный файл. Или исполняемый, как угодно. EXE, в общем. Он состоит из модулей - помимо самого исполняемого файла в его адресное пространство подгружены всякие разные DLL, нужные для его работы. Так как написан он был на компилируемом языке, то на выходе бинарник получился состоящим из так называемых машинных кодов. Если их записать на более понятном для человека представлении, то получится ассемблерный код. Обратно из машинных кодов исходник не получить, потому что все имена функций, переменных и все такое прочее было выброшено компилятором за ненадобностью - ему гораздо быстрее и удобнее ориентироваться в цифрах. Дизассемблированный же листинг мы получить вполне можем. Дизассемблированный - это для архитектуры нашего процессора, то есть он все равно не совсем точный, а примерный. Работать, само собой, работает, тут без вопросов. Адресное пространство, которое я уже выше упомянул - это довольно абстрактная область оперативной памяти, которая зарезирвирована за программой. Она ее видит в виде простыни из 4Гб или чуток побольше адресов, идущих подряд, все это делится на блоки, а блоки - на страницы, которые в нужный момент при помощи магии операционной системы адресуются на физическую память. Такие вот дела. Для того, чтобы изменить ход работы игры, мы можем менять только доступное нам - адресное пространство и код, который мы получили из дизассемблера и\или отладчика. Первый способ - быстрый и удобный, чего уж. Сканер памяти запустил, адрес нужный нашел, меняй - не хочу. А если адрес динамический - посидел 5 минут и нашел указатель. Беда в том, что подходит этот способ далеко не всегда и не для всего. Второй же - куда более муторный, но куда более крутой. Ты сидишь, ковыряешься в отладчике в тщетных попытках понять, что же делает игра. Сидеть и рассматривать примерный дизассемблерный листинг, в котором есть только команды, регистры и адреса - это жесть, как утомительно. Особенно если делать это по 10-12 часов в сутки. Но результат стоит того. При должной сноровке и должном терпении можно хоть всю игру переписать на свой лад. Опции доступны _любые_, без шуток. На что фантазии и времени хватит - то и будет. Менять код игры можно прямо из отладчика, тут же получая результат (или вылет), можно - из Cheat Engine или аналогичной программы, делая скрипты на местном диалекте ассемблера, а можно написать свою программу, которая будет все это делать под твоим руководством. Последний вариант - самый крутой. К счастью, чудо-фирма Microsoft в некоторой мере адекватна и выпустила для своей линейки операционных систем набор API - то есть набор функций, позволяющих приказать этой самой оси сделать нечто полезное. Среди сотен этих функций есть парочка очень необходимых нам - например, возможность читать и менять память в чужом адресном пространстве. Есть в игре, допустим, такая инструкция: DEC EBX Которая при каждом своем срабатывании уменьшает текущее значение регистра EBX на единицу. Можно теперь включить фантазию и нафантазировать, что это - часть функции, ответственной за стрельбу. И срабатывает она каждый раз, как игрок в игре стреляет, отнимая у него патроны. Нас такая ситуация не очень устраивает, так что мы в нашей крутой программе вызываем API-функцию для записи в память и записываем по адресу, где лежит инструкция, опкод инструкции NOP, то есть число 0x90. Почему число? Потому что в памяти лежат цифры, а не DEC или NOP. Их нам выдают отладчик и дизассемблер исключительно потому, что они - добрые и щедрые ребята. В общем, записали, патроны не меняются - круто! Через пару недель мы понимаем, что можно не просто выключать те или иные куски кода, но и дописывать их или переписывать. В какой-то момент сталкиваемся с тем, что у нас доступно для изменения 5 байт, а нужно нам их 25. Тут на помощь приходит техника под названием code injection, которая, как видно из двух английских слов, внедряет кусок кода. Удивительное дело, но при ее использовании нам необходимо всего 5 (а иногда - совсем всего 2) байта. Мы выделяем (или находим) кусок памяти, который игра не использует, записываем туда наши 25 байт, а на месте игровой инструкции записываем переход на нашу память. В итоге игра послушно выполняет то, что мы задумали. Я на днях написал статью, которая поверхностно описывает данную технику. Там как раз используется внешняя программа и вызовы API-функции для записи в память. А писать нужно, как мы помним, цифры. Аж в 16-ричной системе счиления, которую компьютер любит, но не всякий человек. Со временем трейнеростроители поняли, что это не очень уж и удобно, и стали думать. Додумались они до того, что описывал в своих работах Coder. Можно же не использовать внешнюю программу, а внедрить в адресное пространство игры свой исполняемый модуль, скажем, DLL! В едином адресном пространстве будет сильно удобнее - во-первых, не нужны API-функции записи в память - мы можем напрямую ее изменять и копировать, были бы права на это. Во-вторых - можно записать нужную ассемблерную вставку прямо в DLL и делать инъекцию кода, используя адрес этой вставки, обернув ее в функцию. Это позволяет писать намного быстрее и не очень заморачиваться со смещениями и цифрами вместо команд - большинство компилируемых языков программирования поддерживают ассемблерные вставки в коде программы. На этом этапе EXE-файл трейнера выполняет роль красивой обертки, цель которой - показать картинку, написать имя автора и то, какой он крутой и молодец, а затем внедрить в адресное пространство игры эту самую DLL, которая сделает всю дальнейшую работу. Такие вот внедрители DLL и называются инжекторами, только не кода, а DLL. С этой частью, пожалуй, немного разобрались. Осталась самая капелька. Во-первых, Coder использует всякие библиотеки - почему так? Ну, еще он использует C++. А я вот использую С и библиотеки использую, когда мне совсем уж лень писать собственный велосипед. Ему удобнее так, мне - эдак. Дело вкуса. Не требование. Во-вторых, по поводу метода внедрения кода тебе уже ответил Xipho, пока я писал вот это вот. Спасибо всем, кто насладился некоторым количеством букв.