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

A1t0r

Ветераны
  • Постов

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

  • Посещение

  • Победитель дней

    39

Весь контент A1t0r

  1. Используя подсказку krocki, возможно должно быть так pushadmov bl,2div blmov [esi+000000F1C],alpopadВ этом случае делимое не должно быть больше чем 65535. Хотя в первом варианте всё было правильно, делимое - 8 байт EDX:EAX, делитель - 4 байта edi. Инструкция точно не отвечает ни за что другое? Или быть может значение eax дальше не сходится с полученным значением в ячейке памяти.
  2. Адрес-то правильный, просто чит замораживает значение по адресу. drs36, если хочешь чтобы работало нормально, то активируй и сразу же деактивируй чит с нужным значением уровня. Тактика активировал и забыл хороша для жизней, патронов и т. д.
  3. С таким не сталкивался. Если у тебя так получилось, то может ты заморозил значение уровня, либо не увеличил текущее. Обнаружил другой баг, сейчас исправим. Поправил скрипт на случай перехода на др. уровень из меню.
  4. Итак, 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
  5. Согласен, только разница между последним байтом инструкции и куда прыгнуть, а длина инструкции прыжка 5 байт. Если вперед, то всё просто, назад - нужно учитывать эти 5 байт. Проверено на себе)
  6. Всё зависит от первого байта команды. Ты используешь E9 - это близкий ОТНОСИТЕЛЬНЫЙ переход, смещение 4-байтовое. В этом случае опкоды для перехода на 0x004121E2 такие: E9 F6 FF FF FF Если указать смещение 00 00 00 00, то будет произведён переход на след. инструкцию. Смещение считается от последнего байта данной инструкции, т. е. 004121EB. Чтобы перейти на E2 нужно сделать: от последнего байта инструкции до первого 4 шага(будем на E7) + 5 шагов до E2. Смещение FF FF FF FF указывает на последний байт команды (004121EB). Итого: (FF - 4) - 5 = FB - 5 = F6. Для экономии места лучше использовать короткий прыжок (Short 0xEB) со смещением -128 +127. Опкоды такие EB F9А если ты хочешь писать абсолютный адрес, тогда прыжок имеет код 0xEA(jmp FAR). Опкод EA E2 21 41 00Если хочешь почитать, например, здесь, начиная с раздела "Команда безусловного перехода JMP(Переход, прыжок =”JUMP”)"
  7. Самое простое решение выглядит так: mov [ecx+000006E1],64Но можно поискать в памяти по соседству ячейку со значением 100, если такая имеется, то считывать это значение в al. Смотря как выглядит код считывания значения.
  8. Если нужно создавать библиотеки для вставки их в CE, то подобные приблуды от сторонних разработчиков не подойдут. Необходимо собрать динамическую библиотеку из исходников lua версии 5.1, и использовать для своей получившийся файл .lib, как я уже писал в 13 посте. Если всё сделано правильно, то можно сделать файл .def в котором должны будут написаны экспортируемые функции. Скачай обычные исходники вместе с примерами, пройдя по ссылке выше(в конце статьи ссылка на Lua_1Step.rar). В файле lua.pas найдёшь апишные функции, а описание их можно читать на сайте lua.org (инглиш, что поделаешь) или lua.ru (русский).
  9. Есть реализация lua для delphi. нужно только найти справочник АПИ. А лучше зайди сюда
  10. Извиняйте пишу на C. Для 32-битной версии нужно при сборке подключать 32x версию. #include "main.h"#include <lua.hpp>int DLL_EXPORT Symma(lua_State* L){ if (lua_gettop(L)>0) { if (lua_isnumber(L, 1) && lua_isnumber(L, 2)) { const float a = lua_tonumber(L, 1); const float b = lua_tonumber(L, 2); lua_pushnumber (L, lua_Number(a+); return 1; } else MessageBoxA(0, "Not number!", "DLL Message", MB_OK | MB_ICONINFORMATION); } else MessageBoxA(0, "No arguments!", "DLL Message", MB_OK | MB_ICONINFORMATION); return 0;}extern "C" BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){ return TRUE;}#ifndef __MAIN_H__#define __MAIN_H__#include <windows.h>#include <lua.hpp>#ifdef BUILD_DLL #define DLL_EXPORT __declspec(dllexport)#else #define DLL_EXPORT __declspec(dllimport)#endif#ifdef __cplusplusextern "C"{#endifint DLL_EXPORT Symma(lua_State* L);#ifdef __cplusplus}#endif#endif // __MAIN_H__
  11. Использование регистров зависит от того под какую версию написана программа. Есть ведь 32 и 64 битные приложения.
  12. Ну вот как-то так: Попробуй. Складываться должны даже вещественные числа, но точность местами оставляет желать лучшего) Project2.rar
  13. Естественно, но только этого недостаточно. Нужно ещё уметь работать со стеком луа. Простые вызовы сишных функций ни к чему не приведут, ну разве что к ошибке. Сразу видно, даже не заглядывал в программу. Что-то по той ссылке нету примера с передачей параметра в функцию. Без состояния стека можно только вызывать отдельные функции MessageBox, например, таким образом никак не получит извне строку для вывода. Текст неопределённой ошибки можно увидеть?
  14. 515 раз скачали

    Трейнер для игры Battle City на эмулятор FCEUX 2.2.2
  15. Название: Battle City. Script for FCEUX 2.2.2 Добавил: A1t0r Добавлен: 23 Окт 2014 Категория: Трейнеры Трейнер для игры Battle City на эмулятор FCEUX 2.2.2 Нажмите здесь, чтобы скачать файл
  16. Поговорил с одним человеком и получилось сделать подключение своей дллки. Использовал Codeblocks, компилятор MinGW. Библиотека собрана для 64-битной версии CE, можно для 32. Внутри архива .dll, .h и .cpp. Реализовал одну функцию printString, выводящую в messagebox'е переданную ей строку. Для подключения к скрипту CE нужно написать следующее: printString = package.loadlib("D:\\load_my_Lib64.dll", "printString") --загрузка функции из библиотекиprintString("123") --вызов для строкиprintString(123)--вызов для числаПуть написал для примера, главное ставить \\ в пути. Версия CE 6.4. Главное чтобы в корне были библиотеки луа 5.1 Пароль от архива: gamehacklab.ru Будет больше времени и интерес к теме напишу подробнее. DLLka+CPPH.rar
  17. Как минимум dd (float)150находится в исполняемом коде. Нужно вынести, например так newmem:originalcode:fsub dword ptr [subst] fstp dword ptr [eax] push esimov ecx,ediexit:jmp returnheresubst:dd (float)150"Darksiders2.exe"+3B7857:jmp newmemreturnhere:
  18. Прошло 2 года, надо всё-таки поставить точку в теме. Вот таблица и трейнер на бессмертие и много бесконечного золота. Бессмертие получилось сделать только привязавшись к значению золота - оно не равно 0 только у перса. Найти ID не удалось, но и так работает) Хотя цепочки к значениям золота, опыта и здоровья найти удалось. Если что можно переписать скрипт на бессмертие. чтобы сравнивать значение регистра с содержимым последнего элемента в цепочке указателей. Версия 2.28 rus Sacred Underworld v2.28rus by A1t0r(CT and EXE).rar
  19. Откопал у себя пример, очень простой. Взлом UnEpic. Цепочка очень маленькая, но принцип будет понятен. 00492345:fst dword ptr [esi+000003C0] - сохраняется новое значение жизни, используется и для игрока и для противникаЕсли лезть и анализировать структуру лень - ищем указатель в статической памяти. Когда нашли эту инструкцию при ранении игрока, смотрим чему равно esi и ищем это значение в памяти. В данном случае сразу найдётся указатель в статике. И получается такой скрипт newmem:push eax - сохр.mov eax, [00B6A2C0] - считываем указатель по найденному адресуcmp esi, eax - сравниваем его со значением esipop eaxje exit - если будет запись значения в структуру игрока, то выходимoriginalcode:fst dword ptr [esi+000003C0] - иначе раним противникаexit:jmp returnhereНо не всегда бывает так просто. Предположим, после поиска значения esi нам выдало несколько адресов не статичных. Тогда берём любой, ставим бряк на доступ и продолжаем игру. Чаще всего достаточно просто зайти и выйти, т.к. доступ производится множество раз, если только указатель не оказался "левым", тогда пробуем другой. Если что-то выскочило, смотрим как инструкция обращается к нашему указателю. Например, пусть будет mov eax,[ecx+24]. Берем значение ecx и ищем дальше, повторяем пока не найдём статичный адрес. Для данного случая скрипт будет такой(удлиню нашу цепочку, в 00B6A2C0 будет ecx) newmem:push eax - сохр.mov eax, [00B6A2C0]mov eax, [eax+24] - дополнительное звено в нашей цепиcmp esi, eaxpop eaxje exit originalcode:fst dword ptr [esi+000003C0]exit:jmp returnhere
  20. Начнём с того, что "говорил что-нибудь придумать" это относится к анализу структуры и привязке к какому-то значению. Если лень анализировать или не получается привязаться, то можно попробовать вычислить цепочку указателей и проверять фильтром, пытается ли в данный момент инструкция писать, например, в ячейку со здоровьем игрока.
  21. A1t0r

    Risen 3 - Titan Lords

    Версия игры 1.0. Надо бы собрать всё воедино, что было сделано для данной игры, хотя бы в виде ссылок. Скрипты на бессмертие и бесконечные вещи. Первая версия программы для модификации параметров персонажа CharModer. Во второй версии немного дополнил список параметров. Risen 3 - Titan Lords CharModer v2 by A1t0r (CT and EXE).rar
  22. Народ, этот раздел называется Благодарности, а не Жалобы. Я что-то пропустил? Что вы на него набросились?
×
×
  • Создать...

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

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