Перейти к содержанию

Лидеры

  1. 24K

    24K

    Пользователи+


    • Баллы

      7

    • Постов

      130


  2. A1t0r

    A1t0r

    Ветераны


    • Баллы

      1

    • Постов

      351


  3. krocki

    krocki

    Разработчики


    • Баллы

      1

    • Постов

      743


Популярный контент

Показан контент с высокой репутацией 03.11.2014 во всех областях

  1. В этом учебнике я собираюсь обрисовать основной API, необходимый для создания трейнера в Дельфи. Основы знания Дельфи предпочтительны, но Дельфи итак довольно прост в освоении. Концепция. Хорошо, вот что мы хотим от трейнера. Мы запускаем игру. После этого ALT+TAB в Windows. Мы запускаем трейнер, и жмем кнопку. Это действие запишет некие значения в некоторые адреса в игре. Так, например, если мы знаем адрес денег в памяти игры, мы сможем хакать деньги, используя этот трейнер. Вот что нам надо для этого: Название окна игры Запускаем игру, потом переходим в Windows по Alt+Tab. Ищем в панели задач нашу игру и записываем е_ точный заголовок. (К примеру, запустив Red Alert 2, в панели задач Вы увидите кнопку с ее названием - Red Alert 2. Это и есть заголовок главного окна программы. Кстати, Red Alert 2 взломать способом, описанным здесь, не удастся - это DMA игра. Читайте пару документов здесь, посвященных именно A.G.T. и борьбе с DMA) Адреса в памяти игры (в шестнадцатеричном виде) Используем программу, подобную GameHack или MTC (Magic Trainer Creator), мы можем найти любое значение в игре и соответствующий ему адрес в памяти. К примеру, адрес в шестнадцатеричном виде 41D090. Запишем и это тоже. Значение, которое мы хотим записать (в шестнадцатеричном виде): Так, у нас есть адрес в памяти. Что мы хотим в него записать? Скажем, я хочу 50 единиц золота. То есть первым делом мне надо перевести 50 в шестнадцатеричную форму, используя соответствующий конвертер (подойдет и Калькулятор из Стандартных программ Windows - не забудьте включить инженерное представление - прим.пер.) Конвертер скажет 32. Так что запишите и это значение также. Число байт, которое мы хотим писать В том значении, которое мы получили выше, мы должны знать также сколько байт это займет в памяти. К примеру, число 32 займет только 1 байт, но FF07 займет уже два байта. В общем случае, две цифры будут занимать один байт. Начнем кодить Мы собираемся использовать Win32 API чтобы записывать значения в память другого процесса. Вот те функции, которые мы будем использовать. По порядку: FindWindow GetWindowThreadProcessID OpenProcess ReadProcessMemory WriteProcessMemory CloseHandle (Прочтите описания этих функций в файле Win32.hlp (или MSDN - прим.пер.) для полного описания. ) Я буду показывать только основы, так что начинающие могут просто копировать код из этого документа и вставлять его в свой проект.) Итак, начало. Во-первых, мы объявляем наши переменные. Скопируйте и вставьте это в свой проект: Var WindowName : integer; ProcessId : integer; ThreadId : integer; buf : PChar; HandleWindow : Integer; written : cardinal; Теперь надо объявить следующие константы. Скопируйте и этот раздел. Эти константы устанавливаются в соответствии с тем, что вы записали выше. Const WindowTitle = 'prog test'; Address = $41D090; PokeValue = $32; NumberOfBytes = 1; Теперь, чтобы записать значения, вы должны получить хэндл памяти игры. Невозможно сделать это в одно действие, поэтому мы сделаем следующее. Получаем хэндл главного окна С этим хендлом мы получаем идентификатор процесса (process identifier - pID) С этим pID, мы получаем хэндл области памяти. С этим хэндлом мы можем начинать хакать. Во-первых, нам надо получить хэндл главного окна. Используем функцию FindWindow WindowName := FindWindow(nil,WindowTitle); If WindowName = 0 then begin MessageDlg('Игра должна быть запущена до трейнера. Запустите ее, потом трейнер', mtwarning,[mbOK],0); end; Заметим, что код проверяет, равен ли нулю хэндл этого окна. Если оно равно, это значит, что игра не запущена, так что мы предупреждаем пользователя и говорим ему о том, чтобы он запустил игру. Теперь нам нужен pID. Мы используем функцию GetWindowThreadProcessId. После этого мы получаем хэндл области памяти через OpenProcess. Скопируйте код, приведенный ниже. ThreadId := GetWindowThreadProcessId(WindowName,@ProcessId); HandleWindow := OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId); Вот оно. Теперь нам надо использовать WriteProcessMemory чтобы писать что-то внутри этого хэндла. Как только мы это сделаем, мы закрываем хэндл. Так принято. Так безопасно. Скопируйте код, приведенный ниже: GetMem(buf,1); buf^ := Chr(PokeValue); WriteProcessMemory(HandleWindow,ptr(Address),buf,NumberOfBytes,write); FreeMem(buf); CloseHandle(HandleWindow); Вот исходный код для всего трейнера. Для начинающих программистов, чтобы быстро сделать трейнер, требуется только поменять константы, объявленные в начале программы. Var WindowName : integer; ProcessId : integer; ThreadId : integer; buf : PChar; HandleWindow : Integer; write : cardinal; Const WindowTitle = 'prog test'; Address = $41D090; PokeValue = $32; NumberOfBytes = 1; ########################################################### # (Вставьте следующий код в обработчик OnClick кнопки )# ########################################################### begin WindowName := FindWindow(nil,WindowTitle); If WindowName = 0 then begin MessageDlg('Игра должна быть запущена до трейнера. Запустите ее, потом трейнер', mtwarning,[mbOK],0); end; ThreadId := GetWindowThreadProcessId(WindowName,@ProcessId); HandleWindow := OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId); GetMem(buf,1); buf^ := Chr(PokeValue); WriteProcessMemory(HandleWindow,ptr(Address),buf,NumberOfBytes,write); FreeMem(buf); CloseHandle(HandleWindow); end;
    1 балл
  2. Щас попробую скачать эту игрушку и взломать на уровни.
    1 балл
  3. Итак, Adventure Island, первая часть. так и не прошёл в детстве, хоть сейчас отыграюсь))) Проходим до конца уровня и сохраняемся. Открываем RAM Search и ищем единичку(первый уровень). Проходим на 2-й и ищем двойку. Нету. Хм. Попробуем на 1-м уровне поискать ноль, а на втором единицу. Находится десяток адресов, но интересный первый 0038. Ставим в Debugger'e бряк на запись по этому адресу, вываливаемся по адресу 815B: 00:815B:E6 38 INC $0038 = #$00 это увеличение номера round'а. Запомнили место, пригодится если надо будет прыгнуть на следующий уровень. Идем ниже по коду. В 0037 номер area, запомнили. Идём дальше. Вот он прыжок на начало уровня: 00:816F:4C 9A 80 JMP $809AТеперь можно писать скрипт. Напишем функцию обратного вызова для нажатия на кнопку перехода: cheats = { --название таблицы с функциями обратного вызова, пока только одна функция пусть будет "toLevel" ["toLevel"] = function(...) --в функцию передаются некоторые параметры local val, area, round = {...}, nil, nil --пишем их в таблицу val, а также заведём локальные переменные area и round area, round = tonumber(val[1]), tonumber(val[2]) --переписываем параметры в соответствующие переменные ---------------------------------- --если переход запускается из меню memory.writebyte(0x003F, 3) --устанавливаем кол-во жизней memory.writebyte(0x0076, 10) --сытость memory.writebyte(0x0528, 10) --сытость memory.writebyte(0x0077, 0xFF) --сытость --------------------------------- if (area == 0) or (round == 0) then --если любой аргумент равен 0 будем прыгать на след. уровень memory.setregister("pc", 0x815B) --прыгаем на место увеличения round, дальше игра сама разберётся print("Jumped to next level") --печатаем в консоль else --если переход на конкретный уровень memory.writebyte(0x0037, area-1) --записываем в area и round значения memory.writebyte(0x0038, round-1) --на 1 меньшие memory.setregister("pc", 0x809A) -- и прыгаем на начало уровня print("Jumped to area "..area..", round "..round) --печатаем для отладки end end}Теперь напишем интерфейс и зададим функцию обратного вызова для кнопки: function winDraw() -- переход на уровень levelSpinArea = iup.text{ --спиннер для area spinmin = 0, --ограничиваем значения spinmax = 8, --от 0 до 8 spin = "YES", readonly = "YES" --только чтение(от шаловливых ручек) } levelSpinRound = iup.text{--спиннер для round spinmin = 0, spinmax = 4, spin = "YES", readonly = "YES" } levelButton = iup.button{ title = "GO", --надпись на кнопке action = function(self) --функция обработки для кнопки, передаём два параметра cheats["toLevel"](levelSpinArea.spinvalue, levelSpinRound.spinvalue) end } levelLabel = iup.label{ --надпись с пояснением как пользоваться title = "if (area or round) = 0 then jump to next level" } level = iup.frame{ --пространство обведённое рамочкой title = "To area(1-8) round(1-4)", iup.vbox{ --вертикальный контейнер для элементов iup.hbox{ --внутри горизонтальный контейнер для элементов levelSpinArea, --пихаем спиннер для area levelSpinRound, --пихаем спиннер для round levelButton --кнопку }, levelLabel --ну и надпись ниже }, size = "85X20" --размер фрейма } dialogs = dialogs + 1 --увеличиваем на 1 диалог для обработки handles[dialogs] = iup.dialog{ --и создаём его title="Adventure Island Trainer +1 by A1t0r", --заголовок окна resize = "NO", --без ресайза size = "220X50", --размер окна iup.hbox{ iup.vbox{ level --и вставляем наш level jump } } } handles[dialogs]:show() --показываем окноendwinDraw() --выполнить функцию вышеwhile (true) do FCEU.frameadvance() --нарисовать кадр игрыendТеперь скрипт полностью. Когда напишу (если напишу) полный трейнер, выложу в Файлы. Или drs36 напишет для практики) --[[Адреса игровых значений:0x0037 - area0x0038 - roundИнтересные места в коде игры:0x815B - увеличение уровня на 10x809A - начало уровня]]--require("auxlib")--таблица обратных вызовов(callback)cheats = {["toLevel"] = function(...)local val, area, round = {...}, nil, nilarea, round = tonumber(val[1]), tonumber(val[2])memory.writebyte(0x003F, 3)memory.writebyte(0x0076, 10)memory.writebyte(0x0528, 10)memory.writebyte(0x0077, 0xFF)if (area == 0) or (round == 0) thenmemory.setregister("pc", 0x815B)print("Jumped to next level")elsememory.writebyte(0x0037, area-1)memory.writebyte(0x0038, round-1)memory.setregister("pc", 0x809A)print("Jumped to area "..area..", round "..round)endend}function winDraw()--ПОДГОТОВКА ЭЛЕМЕНТОВ ИНТЕРФЕЙСА И ЛОГИКИ-------------------------------------------- переход на уровеньlevelSpinArea = iup.text{spinmin = 0,spinmax = 8,spin = "YES",readonly = "YES"}levelSpinRound = iup.text{spinmin = 0,spinmax = 4,spin = "YES",readonly = "YES"}levelButton = iup.button{title = "GO",action = function(self)cheats["toLevel"](levelSpinArea.spinvalue, levelSpinRound.spinvalue)end}levelLabel = iup.label{title = "if (area or round) = 0 then jump to next level"}level = iup.frame{title = "To area(1-8) round(1-4)",iup.vbox{iup.hbox{levelSpinArea,levelSpinRound,levelButton},levelLabel},size = "85X20"}dialogs = dialogs + 1handles[dialogs] = iup.dialog{title="Adventure Island Trainer +1 by A1t0r",resize = "NO",size = "220X50",iup.hbox{iup.vbox{level}}}handles[dialogs]:show()endwinDraw()while (true) doFCEU.frameadvance()end
    1 балл
  4. Здесь напишу как найти Float значение, и как написать скрипт (С помощью Cheat Engine) буду рассказывать всё подробно Взял игру Need For Speed Undercover (Будем взламывать закись азота) 1) Открываем Cheat Engine 2) Выбираем процесс игры "nfs.exe" 3) Выбираем тип значения ("Value Type") открылся список из списка выбираем "4 byte" 4) Выбираем тип сканирования ("Scan Type") открылся список из списка выбираем "Unknown initial value" (Это означает "Поиск неизвестного значения") 5) Заходим в игру, выбираем профиль, выбираем машину на которой установлено нитро 6) Сворачиваем игру, возвращаемся к программе, нажимаем "Fist Scan" (Это означает "Начать поиск") 7) Заходим в игру, и используем закись азота (т.е уменьшаем или прибавляем этот процесс называется "Отсеивание") 8) Сворачиванием игру, возвращаемся к программе, нажимаем "Next Scan" (это означает "Следующие сканирование" или "Отсеивание") 9) Продолжаем так делать несколько раз пока не найдётся несколько адрес (Ваш адрес или нет можно проверить путём "Замораживание адреса", слево есть такой маленький квадратик, нажмите на него (Этим вы заморозили адрес, т.е адрес изменяться не будет) заморозили адрес, вошли в игру, если закись азота не уменьшается то адрес наш 10) Сворачиваем игру, возвращаемся к программе, по нашему найденному адрес жмём по правой кнопки мышкой и нажимаем "Find out what accesses this adress" (Это означает "Брекпоинт на доступ") 11) Возвращаемся в игру и уменьшаем или прибавляем кол - во закиси азота 12) Сворачиваем игру, возвращаемся к программе, и в не большом окне появились инструкции, ищем примерно такое значение "fld dword ptr [ecx+000000b4]" (Мы должны именно с этой инструкцией работать) 13) Справо нажимаем "Show disassembler" (Это означает "Показать дизассемблер") 14) Далее (Сверху есть панель) жмём "Tools" ----> "Auto Assembler" (Это означает "Инструменты" ---> "Ассемблер") 15) Далее (Сверху есть панель) жмём "Template" ----> Cheat Table flamework code" (Это означает "Шаблон" ----> "вставление секций [ENABLE] и [DISABLE]" 16) Далее "Template" ----> "Code ingection" (Это означает "Шаблон" ----> "Внедрение кода") 17) Далее приступаем к написанию скрипта Должен получиться вот такой скрипт: [ENABLE] //code from here to '[DISABLE]' will be used to enable the cheat alloc(newmem,2048) //2kb should be enough label(returnhere) label(originalcode) label(exit) 007358B0: jmp newmem nop returnhere: newmem: //this is allocated memory, you have read,write,execute access //place your code here mov [ecx+000000b4],(float)1 originalcode: fld dword ptr [ecx+000000b4] <---- Наша инструкция exit: jmp returnhere [DISABLE] //code from here till the end of the code will be used to disable the cheat 007358B0: fld dword ptr [ecx+000000b4] //Alt: db D9 81 B4 00 00 00 dealloc(newmem) <---- Убираем dealloc(newmem) в конец скрипта чтобы игра не глючила и не вылетала 18) Далее "File" ----> "Assign to current cheat table" (Это означает "Файл" ----> "Связь с текущей таблицей") 19) Чтобы активировать скрипт нужно его заморозить Есть второй способ нахождения Float значения: 1) Открываем Cheat Engine 2) Выбираем процесс игры "nfs.exe" 3) Выбираем тип значения ("Value Type") открылся список из списка выбираем "Float" 4) Выбираем тип сканирования ("Scan Type") открылся список из списка выбираем "Unknown initial value" (Это означает "Поиск неизвестного значения") (Также вместо "Unknown initial value" ("Поиск неизвестно значения") можно сделать "Exact Value" ("Поиск точного значения") и где написано "Value" (Значение) написать 1 5) (Потом когда уменьшили или увеличили закись азота "Процесс отсеивания") в "Scan Type" ("Тип сканирования") в открылся список и выбираем "Decreased Value" ("Значение уменьшилось") или "Increased Value" ("Значение увеличилось") Дальше всё также как и в первой способе! Автор: 24K
    1 балл
  5. На написание этой статьи меня подтолкнул Ramil. В таких играх как: Call Of Duty Modern Warfare 3, Medal Of Honor, и Battlefield нету индикатор здоровья, но когда в ГГ стреляют то сверху появляется "Красная полоса" и некоторым очень трудно её найти, об этом и статья! В этих играх адрес жизней DMA, так что если мы умрем или перезагрузим игру то всё насмарку. 1. Запускаем Cheat Engine (Любая версия) 2. Запускаем игру 3. Возвращаемся к Cheat Engine 4. Выбираем процесс игры "iw5sp.exe" 5. Заходим в одиночную игру, выбираем любую миссию 6. Возвращаемся к Cheat Engine 7. Выбираем тип сканирования ("Scan Type") из раскрытого списка выбираем "Unknown initial value" (Это означает "Поиск Неизвестного значения") 8. Выбираем тип значения ("Value Type") из раскрытого списка выбираем "4 byte" (Это означает "4 Байта") (В других играх, может быть другой тип) 9. Нажимаем "Fist Scan" (Это означает "Начать поиск") 10. В игре даем в себя стрелять и сверху появилась "Красная полоска" когда она появилась резко ставите игру на паузу (Это необходимые действия перед отсеиванием) 11. Возвращаемся к Cheat Engine 12. В "Scan Type" (Это означает "Тип сканирования") выбираем "Decreased value" (Это означает "Значение уменьшилось") 13. И после этого нажимаем "Next Scan" (Это означает "Следующие сканирование" или "Отсеивание") 14. Возвращаемся в игру 15. Находим укрытие, ждем пока "Красная полоска" не пропадет с экрана, когда пропала ставим игру на паузу 16. Возвращаемся к Cheat Engine в "Scan Type" (Это означает "Тип сканирования") выбираем "Increased value" (Это означает "Значение увеличилось") 17. И после этого нажимаем "Next Scan" (Это означает "Следующие сканирование" или "Отсеивание") 18. И так делаем несколько раз пока не останется несколько адресов (Адрес жизней или нет можно проверить путём "Заморозки адреса", слево адреса есть "Маленький квадратик" ("Active") - Он замораживает адрес, или активирует скрипты, достаточно нажать в середину "Маленького квадратика" и в нем появится "Крестик" - это означает что адрес заморожен, или скрипт активирован, деактивировать - можно, повторно нажав в середину "Маленького квадратика") 19. Когда заморозили адрес, заходим в игру и опять даем врагов в себя стрелять, если враги в тебе стреляют а ГГ не умирает, то адрес наш! P.S В новых играх очень трудно и немножко долговато найходить адрес здоровья, так что нужно быть очень внимательными при "Отсеивании". Если инструкция работает с адресом нашего ГГ и адресами здоровья врагов то читаем эту тему: http://forum.gamehac...%B0-id-players/ Скрипт "Бесконечное здоровье" в Call Of Dity Modern Warfare 3 (v1.0) (Автор скрипта Grom-Skynet) [ENABLE] alloc(newmem,2048) label(returnhere) label(zd) newmem: push edx mov edx,[010BF428] cmp [esi+00000150],edx pop edx je zd sub ecx,ebp mov [esi+00000150],ecx jmp returnhere zd: db 90 90 mov [esi+00000150],ecx jmp returnhere iw5sp.exe+22058: jmp newmem nop nop nop returnhere: [DISABLE] iw5sp.exe+22058: sub ecx,ebp mov [esi+00000150],ecx dealloc(newmem)
    1 балл
  6. тебе нужно выучить http://forum.gamehac...%B0-id-players/ вот скрипт здоровья: (v1.0) [ENABLE] alloc(newmem,2048) label(returnhere) label(zd) newmem: push edx mov edx,[010BF428] cmp [esi+00000150],edx pop edx je zd sub ecx,ebp mov [esi+00000150],ecx jmp returnhere zd: db 90 90 mov [esi+00000150],ecx jmp returnhere iw5sp.exe+22058: jmp newmem nop nop nop returnhere: [DISABLE] iw5sp.exe+22058: sub ecx,ebp mov [esi+00000150],ecx dealloc(newmem) учись и ещё раз учись, и не здавайся Скрипт "Бесконечные патроны" [ENABLE] alloc(newmem,2048) label(returnhere) newmem: db 90 90 90 pop edi pop esi jmp returnhere iw5sp.exe+B606C: jmp newmem returnhere: [DISABLE] iw5sp.exe+B606C: add [ecx+04],eax pop edi pop esi dealloc(newmem) Скрипт "Стрельба без перезарядки, бесконечные гранаты" [ENABLE] alloc(newmem,2048) label(returnhere) newmem: inc [eax+ecx*4+04] sub [eax+ecx*4+04],edx add esp,10 jmp returnhere iw5sp.exe+D6832: jmp newmem nop nop returnhere: [DISABLE] iw5sp.exe+D6832: sub [eax+ecx*4+04],edx add esp,10 dealloc(newmem)
    1 балл
×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.