-
Постов
351 -
Зарегистрирован
-
Посещение
-
Победитель дней
39
Тип контента
Профили
Форумы
Загрузки
Блоги
Весь контент A1t0r
-
Используя подсказку krocki, возможно должно быть так pushadmov bl,2div blmov [esi+000000F1C],alpopadВ этом случае делимое не должно быть больше чем 65535. Хотя в первом варианте всё было правильно, делимое - 8 байт EDX:EAX, делитель - 4 байта edi. Инструкция точно не отвечает ни за что другое? Или быть может значение eax дальше не сходится с полученным значением в ячейке памяти.
-
Итак, 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 байт. Проверено на себе)
-
Всё зависит от первого байта команды. Ты используешь 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”)"
-
Если нужно создавать библиотеки для вставки их в CE, то подобные приблуды от сторонних разработчиков не подойдут. Необходимо собрать динамическую библиотеку из исходников lua версии 5.1, и использовать для своей получившийся файл .lib, как я уже писал в 13 посте. Если всё сделано правильно, то можно сделать файл .def в котором должны будут написаны экспортируемые функции. Скачай обычные исходники вместе с примерами, пройдя по ссылке выше(в конце статьи ссылка на Lua_1Step.rar). В файле lua.pas найдёшь апишные функции, а описание их можно читать на сайте lua.org (инглиш, что поделаешь) или lua.ru (русский).
-
Есть реализация lua для delphi. нужно только найти справочник АПИ. А лучше зайди сюда
-
Извиняйте пишу на 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__
-
Ну вот как-то так: Попробуй. Складываться должны даже вещественные числа, но точность местами оставляет желать лучшего) Project2.rar
-
Естественно, но только этого недостаточно. Нужно ещё уметь работать со стеком луа. Простые вызовы сишных функций ни к чему не приведут, ну разве что к ошибке. Сразу видно, даже не заглядывал в программу. Что-то по той ссылке нету примера с передачей параметра в функцию. Без состояния стека можно только вызывать отдельные функции MessageBox, например, таким образом никак не получит извне строку для вывода. Текст неопределённой ошибки можно увидеть?
-
-
Название: Battle City. Script for FCEUX 2.2.2 Добавил: A1t0r Добавлен: 23 Окт 2014 Категория: Трейнеры Трейнер для игры Battle City на эмулятор FCEUX 2.2.2 Нажмите здесь, чтобы скачать файл
- 4 ответа
-
- 1
-
-
Поговорил с одним человеком и получилось сделать подключение своей дллки. Использовал 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
-
Прошло 2 года, надо всё-таки поставить точку в теме. Вот таблица и трейнер на бессмертие и много бесконечного золота. Бессмертие получилось сделать только привязавшись к значению золота - оно не равно 0 только у перса. Найти ID не удалось, но и так работает) Хотя цепочки к значениям золота, опыта и здоровья найти удалось. Если что можно переписать скрипт на бессмертие. чтобы сравнивать значение регистра с содержимым последнего элемента в цепочке указателей. Версия 2.28 rus Sacred Underworld v2.28rus by A1t0r(CT and EXE).rar
-
Откопал у себя пример, очень простой. Взлом 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
-
Начнём с того, что "говорил что-нибудь придумать" это относится к анализу структуры и привязке к какому-то значению. Если лень анализировать или не получается привязаться, то можно попробовать вычислить цепочку указателей и проверять фильтром, пытается ли в данный момент инструкция писать, например, в ячейку со здоровьем игрока.
-
Версия игры 1.0. Надо бы собрать всё воедино, что было сделано для данной игры, хотя бы в виде ссылок. Скрипты на бессмертие и бесконечные вещи. Первая версия программы для модификации параметров персонажа CharModer. Во второй версии немного дополнил список параметров. Risen 3 - Titan Lords CharModer v2 by A1t0r (CT and EXE).rar
-
Народ, этот раздел называется Благодарности, а не Жалобы. Я что-то пропустил? Что вы на него набросились?