Форум администраторов игровых серверов

Форум администраторов игровых серверов (https://forum.zone-game.info/TT.php)
-   Другие игры / Other games (https://forum.zone-game.info/forumdisplay.php?f=24)
-   -   L2 PTS (https://forum.zone-game.info/showthread.php?t=41215)

Sojang 08.08.2016 20:56

L2 PTS
 
Вопрос следующий:
Как доводят старые птс сборки до новых версий л2 без сорцов?

Emperor 08.08.2016 20:59

Re: L2 PTS
 
Экcтендер.

Sojang 08.08.2016 21:10

Re: L2 PTS
 
Цитата:

Сообщение от Emperor (Сообщение 416706)
Эктендер.

Подробнее можно?Я просто не шарю)

Zubastic 08.08.2016 21:41

Re: L2 PTS
 
Цитата:

Сообщение от Sojang (Сообщение 416708)
Подробнее можно?Я просто не шарю)

Пишется dll, которая хукает функции/патчит память.
Как пример экста:
https://sourceforge.net/p/coep/code/66/

Vavilon 08.08.2016 22:05

Re: L2 PTS
 
Или вот экстендер с гф до эпалога https://bitbucket.org/l2shrine/extender-public/src

Emperor 08.08.2016 23:14

Re: L2 PTS
 
Цитата:

Сообщение от Sojang (Сообщение 416708)
Подробнее можно?Я просто не шарю)

Ну, лучше товарища Зубастика я не отвечу. В двух словах именно так это и работает.
Но, насколько я знаю, полноценной платформой, с гордым званием "PTS", являться оно не будет.

Sojang 19.08.2016 00:03

Re: L2 PTS
 
Цитата:

Сообщение от Zubastic (Сообщение 416710)
Пишется dll, которая хукает функции/патчит память.
Как пример экста:
https://sourceforge.net/p/coep/code/66/

Цитата:

Сообщение от Vavilon (Сообщение 416712)
Или вот экстендер с гф до эпалога https://bitbucket.org/l2shrine/extender-public/src

Кроме этих есть еще проекты поновее?:)

Krickt 19.08.2016 01:34

Re: L2 PTS
 
Это называется эмулятор на Си. :D

Zubastic 19.08.2016 01:35

Re: L2 PTS
 
Цитата:

Сообщение от Sojang (Сообщение 417363)
Кроме этих есть еще проекты поновее?:)

Смотря для каких целей "поновее". Принципы того как оно работает там есть. Другое дело, что нужен будет напильник, чтобы оно работало :)

Sojang 19.08.2016 10:17

Re: L2 PTS
 
Цитата:

Сообщение от Zubastic (Сообщение 417368)
Смотря для каких целей "поновее". Принципы того как оно работает там есть. Другое дело, что нужен будет напильник, чтобы оно работало :)

уже новее не нужно :)
того что скинули выше оказалось достаточно

Sojang 19.08.2016 16:54

Re: L2 PTS
 
Возник вопрос о работе на 64 бит приложениях
В 32бит приложении вызов хукнулся и все окей, а в 64бит приложении все через попу..
Как видно на скрине в коде появляется несуществующий адрес, который не относится к моей dll
Есть у кого мысли по этому поводу?:)

Код:
Свернуть ↑Развернуть ↓

n3k0nation 19.08.2016 17:26

Re: L2 PTS
 
У x64 адреса длиннее. kappa
Попробуйте чето типа этого:
Код:

;если надо, то делаем lea rax,[adr_param] вместо мува
mov rax,0x100500
jmp rax

Код:

48 b8 //mov rax
00 00 00 00 00 00 00 00 //наш_адрес_на_8_байт
ff e0 //jmp rax

Ну и конечно же, это все займет 12 байт, а не 5, как в x86. А вообще, не забываем о релатив адресации.

Sojang 19.08.2016 17:38

Re: L2 PTS
 
Цитата:

Сообщение от n3k0nation (Сообщение 417403)
У x64 адреса длиннее. kappa
Попробуйте чето типа этого:
Код:

;если надо, то делаем lea rax,[adr_param] вместо мува
mov rax,0x100500
jmp rax

Код:

48 b8 //mov rax
00 00 00 00 00 00 00 00 //наш_адрес_на_8_байт
ff e0 //jmp rax

Ну и конечно же, это все займет 12 байт, а не 5, как в x86.

Длиннее то длиннее, однако вот тут
Цитата:

Сообщение от Vavilon (Сообщение 416712)
Или вот экстендер с гф до эпалога https://bitbucket.org/l2shrine/extender-public/src

реализовано так же как у меня, а это судя по всему длл под 64 бит..
UDP: Беру слова назад. То что по ссылке это не 64 бит длл. Однако как тогда реализовать это на плюсах?На си++ никогда не кодил и вот ток ща опыта набираюсь

n3k0nation 19.08.2016 22:10

Re: L2 PTS
 
Цитата:

Сообщение от Sojang (Сообщение 417404)
Однако как тогда реализовать это на плюсах?На си++ никогда не кодил и вот ток ща опыта набираюсь

Почти так же, как и для х86, но с кодом, как я показал выше. И да, на MSVC x64 нет inline asm, поэтому компилим кусок кода на АСМе и берем оттуда "готовый" код, который будет выполнять роль нашего трамплина.
Если не нравится метод через jmp, то можно через возврат:
Код:

push adr
ret

Уже в сишной программе просто вставляем нужный адрес, не забывая его рассчитать.

Sojang 20.08.2016 14:22

Re: L2 PTS
 
Цитата:

Сообщение от n3k0nation (Сообщение 417414)
Почти так же, как и для х86, но с кодом, как я показал выше. И да, на MSVC x64 нет inline asm, поэтому компилим кусок кода на АСМе и берем оттуда "готовый" код, который будет выполнять роль нашего трамплина.
Если не нравится метод через jmp, то можно через возврат:
Код:

push adr
ret

Уже в сишной программе просто вставляем нужный адрес, не забывая его рассчитать.

Блин, что то не доходит до меня:redlol:
asm:
Свернуть ↑Развернуть ↓

Как можно заюзать это из с++?

Zubastic 20.08.2016 17:03

Re: L2 PTS
 
Вот так:
	__asm
	{
		push adr
		ret
	}
Code: C++

Sojang 20.08.2016 17:17

Re: L2 PTS
 
Цитата:

Сообщение от Zubastic (Сообщение 417430)
Вот так:
	__asm
	{
		push adr
		ret
	}
Code: C++

так выше же написали что инлайн вставок в 64бит нету:)

n3k0nation 20.08.2016 22:02

Re: L2 PTS
 
Цитата:

Сообщение от Sojang (Сообщение 417427)
Блин, что то не доходит до меня:redlol:
asm:
Свернуть ↑Развернуть ↓

Как можно заюзать это из с++?

А нафига Вы компилите под 386й?)

Качаете, например, fasm и пишите чето типа этого:
Код:

use64
push 0x7fffffff
ret

Компилите это:
Код:

fasm tramp.asm tramp.bin
Открываете в хексе аутпут и видите чето типа этого:
http://image.prntscr.com/image/dfbcb...8c11352eb4.png

Берем эти замечательные байты и пихаем в сишную прогу. Должно получится чето типа:
Код:

unsigned char trampTemplate[ ] = {
0x68, //push
0x00, 0x00, 0x00, 0x00 //address
0xc3 //ret
};

Адрес кодируется, как беззнаковое 4х байтовое слово. В общем, через костыль и жопу, грубо говоря (вместо того, чтобы дать нормальную поддержку push 8bytes). Пляшем с бубном, вычисляем наш адрес.
Готовим трамплин (псевдокод):
Код:

unsigned char* tramp = new unsigned char[6];
memcpy(tramp, trampTemplate, 6);
((DWORD*)(&tramp[1]))* = adr;

А далее, как обычно, даем через VirtualProtect права на запись куска памяти, где будем переписывать код и пишем наш трамплин туда.

Sojang 20.08.2016 23:37

Re: L2 PTS
 
Цитата:

Сообщение от n3k0nation (Сообщение 417443)
А нафига Вы компилите под 386й?)

Качаете, например, fasm и пишите чето типа этого:
Код:

use64
push 0x7fffffff
ret

Компилите это:
Код:

fasm tramp.asm tramp.bin
Открываете в хексе аутпут и видите чето типа этого:
http://image.prntscr.com/image/dfbcb...8c11352eb4.png

Берем эти замечательные байты и пихаем в сишную прогу. Должно получится чето типа:
Код:

unsigned char trampTemplate[ ] = {
0x68, //push
0x00, 0x00, 0x00, 0x00 //address
0xc3 //ret
};

Адрес кодируется, как беззнаковое 4х байтовое слово. В общем, через костыль и жопу, грубо говоря (вместо того, чтобы дать нормальную поддержку push 8bytes). Пляшем с бубном, вычисляем наш адрес.
Готовим трамплин (псевдокод):
Код:

unsigned char* tramp = new unsigned char[6];
memcpy(tramp, trampTemplate, 6);
((DWORD*)(&tramp[1]))* = adr;

А далее, как обычно, даем через VirtualProtect права на запись куска памяти, где будем переписывать код и пишем наш трамплин туда.

спасибо за развернутый ответ:)
но чет я кажись кривой и он пишет в память не push адрес ret а бред полный

код:
Свернуть ↑Развернуть ↓

Sojang 21.08.2016 22:56

Re: L2 PTS
 
все еще актуально..........

Ugly 22.08.2016 10:09

Re: L2 PTS
 
Удивительно как можно совершить столько ошибок в паре строчек кода :(
tramp = new unsigned char[6];
Code: C++
Memory leak без delete[] в конце. Лучше сразу на стеке объявить char tramp[6];
tramp[1] = (char)pNewFunc;
Code: C++
Это копирует только один младший байт адреса.
WriteMemory(pAddress, &tramp, sizeof(tramp));
Code: C++
Cразу две ошибки. У тебя tramp - это указатель, следовательно &tramp - адрес этой переременной, а не самого буфера с кодом; по той же причине sizeof(tramp) будет == 4, а не 6.

 
char trampoline[6];
trampoline[0] = 0x68; // push imm32
memcpy(&trampoline[1], pNewFunc, 4); // тут я не понял. pNewFunc у тебя это уже адрес новой функции или это указатель на переменную с адресом новой функции?
trampoline[5] = 0xС3; // ret
WriteMemory(pAddress, trampoline, sizeof(trampoline));
 
Code: C++

f1redark 22.08.2016 11:09

Re: L2 PTS
 
Да уж, как можно так издеваться над c++

Sojang 22.08.2016 14:03

Re: L2 PTS
 
Цитата:

Сообщение от Ugly (Сообщение 417516)
Удивительно как можно совершить столько ошибок в паре строчек кода :(
tramp = new unsigned char[6];
Code: C++
Memory leak без delete[] в конце. Лучше сразу на стеке объявить char tramp[6];
tramp[1] = (char)pNewFunc;
Code: C++
Это копирует только один младший байт адреса.
WriteMemory(pAddress, &tramp, sizeof(tramp));
Code: C++
Cразу две ошибки. У тебя tramp - это указатель, следовательно &tramp - адрес этой переременной, а не самого буфера с кодом; по той же причине sizeof(tramp) будет == 4, а не 6.

 
char trampoline[6];
trampoline[0] = 0x68; // push imm32
memcpy(&trampoline[1], pNewFunc, 4); // тут я не понял. pNewFunc у тебя это уже адрес новой функции или это указатель на переменную с адресом новой функции?
trampoline[5] = 0xС3; // ret
WriteMemory(pAddress, trampoline, sizeof(trampoline));
 
Code: C++

спасибо)
только теперь адрес то верно пишет, но когда выполняется патченый код то приложение крашится тупо..в чем может быть проблема?
UDP: Посмотрел дебагером, а там по адресу pNewFunc расположено что то очень странное..
https://pp.vk.me/c604724/v604724067/...eaOr9BBnL4.jpg

Zubastic 22.08.2016 15:01

Re: L2 PTS
 
Просто длл не загружена, если не ошибаюсь.
А вообще критует из-за ошибки записи скорее всего. Писать через виртуалпротект же надо :)

Добавлено через 1 минуту
void HookFunction(void* dest, void* src, int countBytes)
{
	DWORD dwProtect = PAGE_READWRITE;
	VirtualProtect(dest, countBytes, dwProtect, &dwProtect);
	*(int*)dest = (int)src;
	VirtualProtect(dest, countBytes, dwProtect, &dwProtect);
}
Code: C++
Для моих нужд этого хватает.

Sojang 22.08.2016 15:06

Re: L2 PTS
 
Цитата:

Сообщение от Zubastic (Сообщение 417528)
Просто длл не загружена, если не ошибаюсь.
А вообще критует из-за ошибки записи скорее всего. Писать через виртуалпротект же надо :)

Добавлено через 1 минуту
void HookFunction(void* dest, void* src, int countBytes)
{
	DWORD dwProtect = PAGE_READWRITE;
	VirtualProtect(dest, countBytes, dwProtect, &dwProtect);
	*(int*)dest = (int)src;
	VirtualProtect(dest, countBytes, dwProtect, &dwProtect);
}
Code: C++
Для моих нужд этого хватает.

так длл то вроде как загружается:) и код патчится вот только как то криво у меня все работает

Добавлено через 19 минут
Я тут подумал, а у меня вообще адрес функции правильно определятся?:D
CPatchEngine::Instance()->WriteCall((BYTE *)0x14010DF47, (DWORD *)PatchInit);
Code: C++
 
void CPatchEngine::WriteCall(BYTE *pAddress, DWORD *pNewFunc)
{
	char trampoline[6];
	trampoline[0] = 0x68; // push imm32
	memcpy(&trampoline[1], &pNewFunc, 4); 
	trampoline[5] = 0xC3; // ret
	WriteMemory(pAddress, trampoline, sizeof(trampoline));
}
 
Code: C++

Ugly 22.08.2016 15:49

Re: L2 PTS
 
Функция называется WriteCall, но вообще-то равносильна jmp, а не call. Предварительно на стек следует положить адрес, куда вернётся управление после возврата из функции.

Sojang 22.08.2016 21:23

Re: L2 PTS
 
Цитата:

Сообщение от Ugly (Сообщение 417532)
Функция называется WriteCall, но вообще-то равносильна jmp, а не call. Предварительно на стек следует положить адрес, куда вернётся управление после возврата из функции.

Я что то вообще запутался:redlol:
мне в начале темы говорили про:
push Adr
ret
я как понял в данном случае это не верно будет для call?

Sojang 23.08.2016 00:58

Re: L2 PTS
 
Такс ладно собравшись с мыслями я что то вообще в тупик попал.
Размер
push Adr 
ret
Code: ASM
6 байт, а размер
call Adr
Code: ASM
5 байт и вот тут и получается бред какой то...
Далее нужно же после вызова моей функции вернуться к оригинальной и тут я вообще в тупик попал что то
Тогда нужно писать что то вроде
mov rax, Adr // моя функция
call rax
mov rax, Adr // оригинал
call rax
Code: ASM
и опять же размер больше 5 байт и все пойдет через попу..:redlol:

:):
Свернуть ↑Развернуть ↓

n3k0nation 23.08.2016 10:01

Re: L2 PTS
 
Sojang, для начала определитесь вообще, что Вы хотите, а не бездумно копируйте код)
jmp - безусловный переход и не более того.
push/ret - аналог jmp.
call - кидает на стек текущий адрес и прыгает на указанный адрес; если функция ret-ается, то у нас происходит возврат туда откуда был call (адрес caller'a на стеке же есть).

Для вызова оригинальной функции нужно выполнить, то что было затерто переходом (jmp/push-ret/call), обычно это пролог функции по какому-нибудь calling conventions, а-ля, stdcall для win32. При вызове оригинальной функции, мы смещаемся на то количество байтов, которое мы перетерли.
Пример: адрес функции 0x1000, мы переписали первые 5 байт на jmp, значит мы реализуем перетертые 5 байт и делаем переход на 0x1005, грубо говоря.

Если затерто было БОЛЬШЕ пролога, да и вообще чето как-то получилось, то что размер перетертых команд не совпадает с размером команд, которыми мы заменили, то пишем дизассемблер длин, нопим кривые куски команд и делаем все то же самое, но реализовывать обратный переход надо уже с учетом того, что мы нопнули.

Можно конечно оботись костылем такого вида: если у нас перехваченная функция гарантированно дергается в один поток, то можно просто снимать хук, когда мы хотим перейти назад и ставить его опять, после того, как мы получим результат работы функции. Главное не забыть сбросить instruction cache, иначе ничего не поменяется;)

Sojang 23.08.2016 14:10

Re: L2 PTS
 
Цитата:

Сообщение от n3k0nation (Сообщение 417571)
Sojang, для начала определитесь вообще, что Вы хотите, а не бездумно копируйте код)
jmp - безусловный переход и не более того.
push/ret - аналог jmp.
call - кидает на стек текущий адрес и прыгает на указанный адрес; если функция ret-ается, то у нас происходит возврат туда откуда был call (адрес caller'a на стеке же есть).

Для вызова оригинальной функции нужно выполнить, то что было затерто переходом (jmp/push-ret/call), обычно это пролог функции по какому-нибудь calling conventions, а-ля, stdcall для win32. При вызове оригинальной функции, мы смещаемся на то количество байтов, которое мы перетерли.
Пример: адрес функции 0x1000, мы переписали первые 5 байт на jmp, значит мы реализуем перетертые 5 байт и делаем переход на 0x1005, грубо говоря.

Если затерто было БОЛЬШЕ пролога, да и вообще чето как-то получилось, то что размер перетертых команд не совпадает с размером команд, которыми мы заменили, то пишем дизассемблер длин, нопим кривые куски команд и делаем все то же самое, но реализовывать обратный переход надо уже с учетом того, что мы нопнули.

Можно конечно оботись костылем такого вида: если у нас перехваченная функция гарантированно дергается в один поток, то можно просто снимать хук, когда мы хотим перейти назад и ставить его опять, после того, как мы получим результат работы функции. Главное не забыть сбросить instruction cache, иначе ничего не поменяется;)

Такс я чет не понял про пролог..я вообще патчил в приложении вызовы например call это оказывается не правильно?:(
Я вообще туплю что то и нихуа не понимаю :redlol::redlol:

Zubastic 23.08.2016 14:33

Re: L2 PTS
 
Окей, вот такая штука:
http://klikr.org/b3681a10f4268d699e2421aa4fbc.png
Это и есть пролог. Вообще рекомендую прочитать про calling convention. Многое станет ясно.
Вот ты это заменяешь на jmp addr.В конце выполнения ты можешь сделать jmp в то место откуда пришел и программа продолжит выполнение. Или же сделать ret и она вернет значение.

Sojang 23.08.2016 14:53

Re: L2 PTS
 
Цитата:

Сообщение от Zubastic (Сообщение 417585)
Окей, вот такая штука:
http://klikr.org/b3681a10f4268d699e2421aa4fbc.png
Это и есть пролог. Вообще рекомендую прочитать про calling convention. Многое станет ясно.
Вот ты это заменяешь на jmp addr.В конце выполнения ты можешь сделать jmp в то место откуда пришел и программа продолжит выполнение. Или же сделать ret и она вернет значение.

спасибо, про пролог теперь все ясно:)
однако остались вопросы про
Цитата:

Сообщение от Zubastic (Сообщение 417585)
В конце выполнения ты можешь сделать jmp в то место откуда пришел и программа продолжит выполнение. Или же сделать ret и она вернет значение.

вот тут можете разъяснить по подробнее?:redlol:

Emperor 23.08.2016 15:04

Re: L2 PTS
 
Я думаю стоит начать с литературы, а то кол-во вопросов так и будет увеличиваться.

Sojang 23.08.2016 15:14

Re: L2 PTS
 
Цитата:

Сообщение от Emperor (Сообщение 417589)
Я думаю стоит начать с литературы, а то кол-во вопросов так и будет увеличиваться.

ну вот если вопросы у меня так и будут расти то обязательно займусь литературой:)
что нибудь посоветовать можете из книг?

Emperor 23.08.2016 15:33

Re: L2 PTS
 
Sojang, Крупника\Юрова можно почитать. У них там вроде и учебники есть для вышек и простые книги для масс.
С забугорными не знаком.

Zubastic 23.08.2016 15:36

Re: L2 PTS
 
Цитата:

Сообщение от Sojang (Сообщение 417588)
спасибо, про пролог теперь все ясно:)
однако остались вопросы про
вот тут можете разъяснить по подробнее?:redlol:

Допустим ты увеличиваешь функционал.
Ты берешь 5 байт и копируешь их к себе. Затем вместо 5 байт пишешь jmp в свою функцию. Там делаешь все, что нужно, после этого вызываешь 5 байт, которые перенес после чего делаешь jmp обратно (на тот же адрес который ты заменил +5 байт).
http://coderx.ru/showthread.php?t=3609

Вот почитай. Вообще зря ты на х64 полез, не разобравшись с х32.
Я могу ошибаться, более опытные форумчане думаю поправят.

Sojang 23.08.2016 16:13

Re: L2 PTS
 
Цитата:

Сообщение от Zubastic (Сообщение 417592)
Допустим ты увеличиваешь функционал.
Ты берешь 5 байт и копируешь их к себе. Затем вместо 5 байт пишешь jmp в свою функцию. Там делаешь все, что нужно, после этого вызываешь 5 байт, которые перенес после чего делаешь jmp обратно (на тот же адрес который ты заменил +5 байт).
http://coderx.ru/showthread.php?t=3609

Вот почитай. Вообще зря ты на х64 полез, не разобравшись с х32.
Я могу ошибаться, более опытные форумчане думаю поправят.

Так в 64 же нету __asm вставок. Как тогда сделать jmp обратно то?:(

Zubastic 23.08.2016 17:33

Re: L2 PTS
 
Ну я уверен, что есть более легальные способы, вот мои идеи:
делаешь dummy функцию, например с мессадж боксом и вместо ее пишешь jump

Sojang 23.08.2016 17:41

Re: L2 PTS
 
Цитата:

Сообщение от Zubastic (Сообщение 417595)
Ну я уверен, что есть более легальные способы, вот мои идеи:
делаешь dummy функцию, например с мессадж боксом и вместо ее пишешь jump

да я уже разобрался.
спасибо в любом случае:)

Sojang 23.08.2016 19:14

Re: L2 PTS
 
появилась новая проблема :D
Меняю начало функции на свой код(mov rax, адрес jmp rax) и все окей функция из моей длл вызывается, но как только я пытаюсь выполнить свой asm код(нужен что бы продолжить работу программы) приложение зависает и закрывается..
Из за чего это происходит?(




Текущее время: 16:14. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot