Лидеры
Популярный контент
Показан контент с высокой репутацией 31.10.2011 во всех областях
-
Date: 30.11.2011 Author: keng Tools needed: Cheat Engine 6.1, Microsoft Notepad Не знаю точно, куда запостить, если что - пните в нужную сторону. Итак, идея проста и избита, но по ней статьи я не нашёл. Задача: Вызвать API-фунцию из самой игры (или приложения). Как нам всем хорошо известно, API-функция - это: 1. Читаем статью на вики. Вдумчиво. 2. Понимаем, что это, говоря по-человечески, функция (а точнее, их набор), при помощи которой все Windows-приложения (и игры в том числе) контактируют между собой и взаимодействуют с системой. Простые примеры: 1. CreateFile. Создаёт файл. Удобно? Да. И из любой программы можно вызвать - создастся файл. 2. MessageBox. Показывает окошко с некоторой информацией и кнопками "Ok", "Cancel" и так далее, на выбор. Позволяет добиться какой-то реакции от пользователя. Тоже крутая штука. В общем, прелесть в том, что эти функции стандартизированы, вызываются одинаково и используются в 100% приложений и игр. Тэк-с, теорией немного пропитались, пойдём дальше. Тренироваться будем на всеми любимом Блокноте. Открываем блокнот (Пуск -> Выполнить -> notepad.exe): Открываем Cheat Engine (надеюсь, не нужно показывать, как она выглядит). Присоединяемся к процессу notepad.exe и начинаем думать. В программе есть меню. В меню "Файл" есть пункт "Сохранить как", который вызывает диалоговое окошко, позволяющее сохранить (!) текущий документ. В выполнение этой-то функции мы и внедрим свой замечательный код. Делаем поиск текстового значения, вот так: Находим один-единственный адрес, хранящий эту текстовую строку. Добавляем его в таблицу адресов, жмём правой кнопкой и выбираем опцию "Find out what accessess this address" (Найти, что обращается к этому адресу). Выскакивает окошко отладчика, возвращаемся в блокнот и пробуем сохранить наш документ. В отладчике видим примерно вот такую картину: Первая функция вызвалась обратилась к нашему адресу аж 8 раз, а вот остальные - по одному. Выбираем одну из них (на свой вкус, я взял вторую), жмём кнопку "Show disassembler" (Показать дизассемблер). Открывается окно дизассемблера, в нём ничего не трогаем и идём в меню Tools - Auto Assembler (Инструменты - Автоассемблер), или жмём Ctrl+A. В окне автоассемблера набиваем следующий код: Ага, как же. Ещё немного теории! В ассемблере API-функции вызываются вот таким вот образом: push arg2 push arg1 push arg0 call func Командами push мы запихиваем в стек аргументы функции (если нужны), так как это стек - запихиваем их с конца (справа налево), после чего командой call func вызываем функцию, где func - имя или адрес (в 16-й системе счисления, ибо компьютер - глуп и не понимает привычных нам арабских цифр). Попробуем вызвать функцию Beep. Кликом по названию идём в MSDN и читаем о ней статью, а кто не знает английского или не любит читать (), для тех поясняю - эта функция заставляет встроенный в компьютер динамик пищать, а в качестве аргументов принимает частоту и длительность сигнала. Итак, нам остаётся выяснить адрес функции, чтобы вызвать её из блокнота, так как все эти функции хранятся во внешних dll-библиотеках и адреса вызова для разных программ могут быть разные, ибо библиотеки эти подгружаются динамически. Идём в отладчик и выбираем меню View - Enumerate DLL's and Symbols (Вид - Пронумеровать ДЛЛ'ки и Символы). Получаем вот такое окно: Жмём правой кнопкой - Find (Найти) - вводим слово Beep и в выделенной строчке получаем адрес вызова: Возвращаемся в Авто ассемблер и нашему коду! В меню выбираем Template - Code Injection (Шаблон - Инъекция кода) и пишем вот так: alloc(newmem,2048) //2kb should be enough label(returnhere) label(originalcode) label(exit) newmem: //this is allocated memory, you have read,write,execute access //place your code here originalcode: mov eax,[esi+ecx*4-1C] mov [edi+ecx*4-1C],eax //наш код pushad push 10 push ff call 75A76DF3 popad exit: jmp returnhere "msvcrt.dll"+9CCA: jmp newmem nop nop nop returnhere: Разберу поподробней то, что мы написали. Вот этот кусочек: pushad push 10 push ff call 75A76DF3 popad Pushad - сохраняет текущие значения всех регистров, чтобы мы чего лишнего не поломали нашим хитрым кодом. push 10 и push ff - толкаем в стек длительность (16 мсек) и частоту (255 Гц) в качестве аргументов нашей функции. Напомню прототип функции: Beep(Frequency, Duration) где Frequency - это частота, а Duration - это длительность. Командой call мы вызваем, собственно, нашу пищалку-пищалочку, а затем popad-ом возвращаем значения регистров на свои места. Всё дописали, перепроверили, жмём Execute (Выполнить), пробуем сохранить файл - слышим пищание. Круто! ...но зачем это может быть нужно? Если почитать справку по WinAPI-функциям, можно найти немало полезных. Например, MessageBox, который можно вызывать при определённом событии. Скажем, убили нашего игрока - а нам показали значение какого-то адреса, сколько он прожил или ещё что-нибудь полезное. Такой импровизированный отладчик, ага. На этом всё. UP: Прилепил к шапке статью в виде PDF: WinApiInjection_by_keng.zip4 балла