• Объявления

    • Garik66

      Пользователям форума   05.11.2017

      Прошу обратить внимание на эту тему (чтобы увидеть ссылку, войдите в объявление - нажмите на заголовок):   
ArxLex

Программирование трейнеров на Ассемблере

18 сообщений в этой теме

В этой теме будут выкладываться примеры трейнеров написанные на языке Ассемблер. Тема будет периодически обновляться)))

Необходимые инструменты:

- MASM32 v10

- WinAsm v5.1.5 + WinAsm v5.1.7 патч

Установка и настройка:

1. Первым делом вам надо установить MASM32, который вы можете скачать по ссылке ниже.

- Скачайте и запустите файл install.exe

- Выберите диск где будет установлен MASM32

- Далее нажмите на кнопку Start -> Ok -> Yes -> Ok -> Extract - > Ok

2. Установка WinAsm и патча:

- Распакуйте папку WinAsm из архива (WinAsm515Full) в папку где вы установили MASM32

- Для установки патча просто распакуйте файлы из архива (WinAsm_V5.1.7.0) в папку WinAsm

3. Настройка WinAsm:

- Запустите файл WinAsm.exe из папки WinAsm

- Затем Tools -> Options -> Files&Paths -> Projects Path

- Тут вы увидете x:masm32WinAsm

- Просто в конце добавьте Projects (x:masm32WinAsmProjects)

Удаление:

- Просто удалите папку MASM32

Сами инструменты и исходники вы можете взять отсюда:

http://letitbit.net/download/8716.fe8ed ... es.7z.html

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Примеры вроде хорошие. Но вот решил на FASM испытать, скомпилить не удалось. Убрал лишние ссылки на инклуды вроде плеера XM'ов и about, при компилировании все хорошо, а на деле после запуска даже диалогового окна не выводит.

Плюс при скачке в архиве почему битый exe оказался. Если у вас есть оригинал трейнера , то большая просьба перезалить не битый архив. Хотелось бы протестить , может вообще на седьмой винде не пашет корректно.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Скачал пример трейнера на ассемблере: http://forum.gamehacklab.ru/index.php?app=core&module=attach&section=attach&attach_id=283

А как вместо адресов и прописываемых байтов, использовать скрипт СЕ???

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Часть1.

 ClassName      db "SkinClass",0
AppName db "CDS TRAINER",0

Error db "Error",0
game_err db "Game is not loaded",0
szCapt db "GTA: San Andreas",0

Gaddress1 dd 007428e6h ; адрес по которому будем патчить(ammo GTA SA)
Gval1 db 0ffh,046h,00ch,090h,090h,090h ;баты для патча
Gnum1 db 6

Gaddress2 dd 007428e6h ; адрес по которому будем патчить(возвращаем)
Gval2 db 0ffh,04eh,00ch,08bh,046h,008h ;баты для патча
Gnum2 db 6
-----------

Часть2

invoke   GetAsyncKeyState,VK_F10 ;F10 кнопка действия
.if eax

mov _option,1

invoke TrainerEngine,Gaddress1,addr Gval1,6; 6 это количество байт для патча
ret
.endif


invoke GetAsyncKeyState,VK_F11 ;F11 кнопка undo
.if eax

mov _option,2

invoke TrainerEngine,Gaddress2,addr Gval2,6

ret
-------------

Часть3

 ;####################################################################


TrainerEngine PROC aHack:DWORD, nVal:DWORD, iSize:BYTE
LOCAL phandle:DWORD

LOCAL windhand:DWORD

Invoke FindWindow,0, addr szCapt

.if eax ==0
Invoke MessageBoxA,0, addr game_err, addr Error, MB_OK


ret
.endif
mov windhand,eax

invoke GetWindowThreadProcessId,windhand,addr pid
Invoke OpenProcess, PROCESS_VM_READ or PROCESS_VM_WRITE or PROCESS_VM_OPERATION,NULL, pid
test eax,eax
jz @F
mov phandle,eax


Invoke WriteProcessMemory,phandle, aHack, nVal, iSize, NULL;Write



Invoke CloseHandle, phandle;Close handle
@@:
ret;return


TrainerEngine ENDP
;####################################################################3

----------------------------

Собираем всё вместе:

 1)
...
Gaddress1 dd 007428e6h ; адрес по которому будем патчить(ammo GTA SA)
Gval1 db 0ffh,046h,00ch,090h,090h,090h ;баты для патча
Gnum1 db 6
...
invoke TrainerEngine,Gaddress1,addr Gval1,6; 6 это количество байт для патча
...
2)
...
Gaddress2 dd 007428e6h ; адрес по которому будем патчить(возвращаем)
Gval2 db 0ffh,04eh,00ch,08bh,046h,008h ;баты для патча
Gnum2 db 6
...
invoke TrainerEngine,Gaddress2,addr Gval2,6
...
3)
TrainerEngine PROC aHack:DWORD, nVal:DWORD, iSize:BYTE
...
Invoke WriteProcessMemory,phandle, aHack, nVal, iSize, NULL;Write
....
ret;return

Прекрасно видно где байты активации, а где деактивации.. также понятны адреса.

Следовательно на CE можно написать скрипт такой(заметь на сколько он будет короче всего кода исходника)

[ENABLE]
007428e6:
db ff 46 00 90 90 90
[DIASABLE]
007428e6:
db ff 4e 00 8b 46 08

Я вот понять не могу. Почему тебя беспокоит вопрос написания скриптов на CE по исходнику трейнера на MASM-е.

Всё можно сделать на Cheat Engine

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Меня интересует, как скрипт CE преобразовать в код, который бы компилировался на ассемблере, а не наоборот.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Это можно сделать с помощью LUA engine в CE. Надо знать LUA, надо знать какие функции, события, свойства CE предоставляет LUA Engine. И тогда ты можешь через GUI формы созданные тобой в IDE CE в прямом смысле давать команды компилировать трейнер на MASM, задав адреса и байты активации и деактивации.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А видеоурок можно по этому вопросу сделать?

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Тут надо не видеоурок делать, а писать самому на LUA. Никто не будет заниматься этим видео. И потом чему учить в этом видео - как и где строчку кода написать? или как формы GUI делать? А остальное тоже - видео делать. Проще будет всё сделать и сразу дать результат, чем снимать видео.

Вод тебе в помощь функция. Изменишь её так, чтобы она писала байты активации и деактивации в исходный код MASM для одного чита. А дальше долго будешь мучиться и разбираться как организовать генерацию для нескольких читов из формы GUI...


local addressInjection = address
local sumBytes = 0
local originalCodeString = ""

repeat
extrafield, opcode, bytes, address = splitDisassembledString(disassemble(address))
local countBytes = math.floor(string.len (string.gsub(bytes, " ", "")) / 2)
originalCodeString = originalCodeString..[[

]]..opcode
sumBytes = sumBytes +countBytes
address = string.format("%x", ("0x"..address) + countBytes)
until (sumBytes >= 5)

local nopsString = ""
local nopsCount = sumBytes - 5
if (nopsCount>0) then
nopsString = " db"
for i = 1, nopsCount do
nopsString = nopsString.." 90"
end
nopsString = nopsString..[[

]]
end

if (originalcode) then
script =[[
[ENABLE]
alloc(newmem,2048)
label(originalcode)
label(returnhere)

newmem:
]]..injectInstruction..[[

originalcode:]]..originalCodeString.. [[

jmp returnhere

]]..addressInjection..[[:
jmp newmem
]]..nopsString..[[
returnhere:

[DISABLE]
]]..addressInjection..":"..originalCodeString.. [[


dealloc(newmem)
]]
else
script =[[
[ENABLE]
alloc(newmem,2048)
label(returnhere)

newmem:
]]..injectInstruction..[[

jmp returnhere

]]..addressInjection..[[:
jmp newmem
]]..nopsString..[[
returnhere:

[DISABLE]
]]..addressInjection..":"..originalCodeString.. [[


dealloc(newmem)
]]
end

local teSlave = getTableEntry(cheatName)

if (teSlave == nil) then
teSlave = addresslist_createMemoryRecord(addresslist)
memoryrecord_setDescription(teSlave, cheatName)
memoryrecord_setType(teSlave, vtAutoAssembler)
end

memoryrecord_setScript(teSlave, script)
end
function GenerateAAscript( cheatName, address, injectInstruction, originalcode )

Скорее всего, всё это непросто для тебя. Для меня не сложно, но затратно по времени, а самое главное у меня другие цели. Я не придерживаюсь варианта когда трейнер в виде .exe файла. Я придерживаюсь варианта, когда один .exe файл и много скриптов с связанными ресурсами(картинки, стили, бинарные файлы и т.п.) и огромная база данных в конце с поддержкой обновления из Интернета... К этому я потихоньку стремлюсь...

Так что если у тебя сильный стимул сделать как ты хочешь, то я написал какое направление можно выбрать. Другое направление классическое - писать исходники MASM самому вручную..

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Зачем палить из пушки по воробью? Достаточно на LUA организовать трансляцию автоассемблерного скрипта в патч-байты, как в свое время это было реализовано в TSearch.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А как этого добиться?

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если ты хорошо знаешь LUA, то на нем можешь написать функцию, которая будет брать адрес инъекции, считывать из него байты и выводить в доступном виде. Если же нет - тогда ты можешь открыть окно дизассамблера СЕ, перейти на адреса, которые используются в инъекции, и скопировать байты вручную.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А как быть с играми, которые при каждой перезагрузке чуть меняют адрес? Как тогда мне байты выдернуть?

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Видимо, мы о разных байтах говорим. Если ты используешь взлом игровых инструкций - тогда они не будут менять своего местоположения, и, соответственно, байты этих инструкций будут всегда одинаковыми. К тому же, при таком взломе для трейнера достаточно эти байты один раз выдернуть. Если будет время и желание, сделаю видеоурок, но в этом сильно сомневаюсь, ибо это уж самые азы геймхакинга, без этих знаний стоящий трейнер не напишешь.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Байты то остаются те же, а вот сам адрес немного меняется при каждом новом запуске (например: GImage + ....)

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если меняется адрес инструкции, это значит, что она расположена не в исполняемом файле игры, а в подгружаемом модуле. Как с этим бороться - есть статья на сайте.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Как быть, если игра постоянно меняет CodeCave из подгружаемого модуля? :(

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Пользоваться выделенной памятью в памяти процесса. Создать выделенный кусок памяти можно с помощью функции VirtaulAllocEx. Только при таком подходе прыжки на выделенную память нужно будет рассчитывать "вручную".

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас