Мой сайт
Главная | | Регистрация | Вход
Приветствую Вас Гость | RSS
Меню сайта
Мини-чат
Наш опрос
Оцените мой сайт
Всего ответов: 9
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Поиск
Календарь
«  Февраль 2014  »
Пн Вт Ср Чт Пт Сб Вс
     12
3456789
10111213141516
17181920212223
2425262728
Архив записей
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Главная » 2014 » Февраль » 22 » [Скрипт] "Патчер памяти" или "Пишем флайхак" [Delphi]
    15:05
     

    [Скрипт] "Патчер памяти" или "Пишем флайхак" [Delphi]

    По умолчанию"Патчер памяти" или "Пишем флайхак" [Delphi] Причин к написанию данной темы было три:
    1. Меня попросили.
    2. Когда-то давно я очень долго искал подобную тему, и не нашел.
    3. Флайхаки работают только на фришках.

    Итак начнем.
    Первым делом опишу какие функции мы будем использовать:

    1. FindWindow (модуль Windows)
    function FindWindow(lpClassName, lpWindowName: PChar): HWND; stdcall;
    lpClassName - Имя класса окна (для PW - ElementClient Window)
    lpWindowName - Текст заголовка окна (для PW - Element Client, для офа ПВ - Perfect World)
    С помощью этой функции мы получим дескриптор (handle) окна.

    2. GetWindowThreadProcessId (модуль Windows)
    function GetWindowThreadProcessId(hWnd: HWND; lpdwProcessId: Pointer = nil): DWORD; stdcall; overload;
    hWnd - дескриптор окна.
    lpdwProcessId - указатель на переменную типа Dword, после использования функции в него скопируется идентификатор потока создавшего окно.
    От этой функции нам нужен идентификатор потока (PID).

    3. OpenProcess (модуль Windows)
    function OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; stdcall;
    dwDesiredAccess - Устанавливает права доступа к объекту (мы будем получать полные права доступа PROCESS_ALL_ACCESS)
    bInheritHandle - Параметр дескриптора наследования.
    dwProcessId - идентификатор потока.
    С помощью этой функции мы получим права доступа к памяти объекта, и идинтификатор объекта.
    После окончания работы с идентификатором объекта необходимо закрыть его функцией CloseHandle.

    4. ReadProcessMemory (модуль Windows)
    function ReadProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer;
    nSize: DWORD; var lpNumberOfBytesRead: DWORD): BOOL; stdcall;
    hProcess - Идентификатор объекта
    lpBaseAddress - указатель на адрес из которого будем читать
    lpBuffer - указатель на переменную-буфер, в которую будем читать значение из памяти.
    nSize - количество байт, которое мы хотим прочитать.
    lpNumberOfBytesRead - переменная-буфер, в которой устанавливается значение соответствующее количеству прочитанных байт.
    С помощью этой функции мы будем "подбираться" к нужному нам адресу.

    5. WriteProcessMemory (модуль Windows)
    function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer;
    nSize: DWORD; var lpNumberOfBytesWritten: DWORD): BOOL; stdcall;
    hProcess - Идентификатор объекта
    lpBaseAddress - указатель на адрес в который будем писать
    lpBuffer - указатель на переменную-буфер, значение которой будем записывать в память.
    nSize - количество байт, которое мы запишем в память
    lpNumberOfBytesRead - переменная-буфер, в которой устанавливается значение соответствующее количеству записанных байт.

    Теперь немного о структуре памяти Perfect World.
    На жуке и иных порталах много говорят о оффсетах, но не все понимают что же это за зверь.
    Оффсет это смещение относительно некоего адреса памяти.



    На скриншоте все что выше красной стрелки - отрицательные смещения, все что ниже - положительные.

    К примеру у нас есть базовый адрес игры Perfect World - $009C0E6C и есть смещение $1C.
    Запись вида [ba]+$1C значит что нужно прочесть значение лежащее по адресу $009C0E6C и прибавить к нему $1C, таким образом мы получим адрес начала блока игровой сессии, который по незнанию называют базовым адресом (более приемлимое (и принятое) название base pointer - базовый указатель) и используют в PWGtm (то есть можно сказать что [ba]+$1C=bp).
    Запись вида [ba]+$1C+$20 значи что нам нужно прочесть значение лежащее по базовому адресу, прибавить к нему $1C, и получить базовый указатель, затем прочитать значение лежащее по адресу базового указателя и прибавить к нему $20. Таким образом мы получим указатель на начало структуры данных о персонаже.
    $668 - смещение адреса в памяти отвечающего за полет (на самом деле в по этому адресу находится битовая структура с флагами состояния персонажа, но для простоты мы будем работать с целым байтом), относительно начала структуры данных о персонаже. Путь [ba]+$1C+$20+$668 приведет нас к нему.

    Итак надеюсь все понятно, начнем кодить
    Для начала бросим на форму две кнопки, и назовем их ВКЛ и ВЫКЛ



    Переключимся на редактор кода и напишем процедурку:

    Код:

    procedure FlyHack(state:bool); const base_addr=$009C0E6C; fly_offset=$668; var WndHndl:THandle; buf:byte; ipbuf,PID,hProcess,BytesCount:dword; begin WndHndl:=findwindow('ElementClient Window',nil); GetWindowThreadProcessId(WndHndl, @PID); hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, PID); if hProcess <> 0 then // Проверяем получен ли идентификатор объекта try ReadProcessMemory(hProcess, ptr(base_addr), @ipbuf, sizeof(ipbuf), BytesCount); ReadProcessMemory(hProcess, ptr(ipbuf+$1C), @ipbuf, sizeof(ipbuf), BytesCount); ReadProcessMemory(hProcess, ptr(ipbuf+$20), @ipbuf, sizeof(ipbuf), BytesCount); ReadProcessMemory(hProcess, ptr(ipbuf+fly_offset), @buf, sizeof(buf), BytesCount); if (buf<>$0) and (buf<>$10) then messagebox(0,'Неверная версия клиента','Пишем флайхак',16) else begin if state=true then // Если нажали "ВКЛ" begin buf:=$10; writeprocessmemory(hProcess,ptr(ipbuf+fly_offset),@buf,1,BytesCount); messagebox(0,'Клиент пропатчен','Пишем флайхак,64); end; if state=false then // Если нажали "ВЫКЛ" begin buf:=$0; writeprocessmemory(hProcess,ptr(ipbuf+fly_offset),@buf,1,BytesCount); messagebox(0,'Клиент пропатчен','Пишем флайхак',64); end; end; finally closehandle(hProcess); end; end; Теперь в обработчики событий OnClick наших кнопок запишем:
    для "ВКЛ" - FlyHack(true);
    для "Выкл" - FlyHack(false);

    Вуаля, флайхак готов.

    В аттаче исходник проекта. Вложения Тип файла: rarфлайхак.rar (2.1 Кб, 676 просмотров)
    Просмотров: 1979 | Добавил: cressire | Рейтинг: 0.0/0
    Всего комментариев: 0