1.2.x - 1.5.x Ограничиваем debug по RoleId/UserId/как специальное право GM.

Vieraw

Администратор
Команда форума
Администратор
12 Май 2012
273
145
43
27
Доброго времени суток.
Я уже длительное время не занимался серверами PW и вот решил снова попробовать что-то сделать.
И так, некоторое время назад господин int 3 написал гайд о том, как ограничть Debug для GM. Но предоставлять всем GM возможность использоваться Debug не очень хорошая идея поэтому я решил ограничть его по другим критериям, а именно по: roleid, userid, сделать его специальным правом GM (добавляется через таблицу auth в MySql).
Редактировать будем следующие функции в GS: gplayer_controller::CommandHandler и gplayer_controller::DebugCommandHandler.
Все манипуляции производятся на GS версии 1.2.6, но на других версия все делается аналогичным образом, кроме ограничения Debug по userid.
И так приступим. Открывает gs в IDA и переходим к функции gplayer_controller::DebugCommandHandler.
Как и в гайде от int 3 чтобы ограничить дебаг мы будем затирать вызов функции: GLog::log.

0. Получаем смещение до RoleID и затираем вызов функции.

В дальнейшем для ограничения Debug по RoleId и UserId нам понадобится RoleId персонажа.
На скриншоте цифра 1 указывает на функции GLog::log, которую необходимо затереть, а цифра 2 на аргумент передоваемый в функцию GLog::log, который, по счастливой случайности, является Id персонажа, который использует Debug.
1.png
Кликаем по параметру на который указывает цифра 2 и нажимаем клавишу J, для перехода к коду на ассемблере, и видим:
2.png
Крассной рамкой выделен вызов функции GLog::log, который необходимо затереть, а желтой смещения до Id персонажа. Копируем выделенное желтым себе.
Затираем вызов функции, для этого можно использовать встроенный Hex-радокр в IDA или любой другой, должно получиться так:
3.png


1. Ограничение Debug по Roleid.

Для того чтобы Debug мог использовать только определенный персонаж необходимо сравнить его id с разрешенным. Сделать это можно написав проверку на месте затертого вызова функции GLog::log.
На ассемблере указанная проверка будет выглядеть следующим образом:
Код:
mov	 eax, [ebp+8]
mov	 eax, [eax+4]
mov	 eax, [eax+8]
cmp	 dword ptr [eax+30h], 20h
jnz	 2AAC

Указанные команды необходимо перевести в opcod и используя Hex-редактор записать в выделенную область.

20h - Id персонажа, в данном случае 32.
jnz 2AAC - выход из функции, где 2AAC разность между адресом назначения и адресом команды, следующей сразу за прыжком. В данном случае: 80D4ECF - (080D241D + 6) = 2AAC. Где:
080D4ECF - адрес выхода из функции
080D241D - адрес по которому находится команда jnz
6 - количество байт занимаемых командой jnz.

Команды и соответствующии им opcod'ы
Код:
mov	 eax, [ebp+8] - 8B 45 08
mov	 eax, [eax+4] - 8B 40 04
mov	 eax, [eax+8] - 8B 40 08
cmp	 dword ptr [eax+30h], 20h - 83 78 30 20
jnz	 2AAC - 0F 85 AC 2A 00 00

Вeсь Hex-код:
Код:
8B 45 08 8B 40 04 8B 40 08 83 78 30 20 0F 85 AC 2A 00 00

Должно получится так:
Hex.
4.png

Asm.
5.png

Псевдокод.
6.png

Сохраняем, заливаем GS на сервер, запускаем сервер. После данных изменений Debug будет доступен только персонажу с Id равным 32.

2. Ограничение Debug по UserId. (Только для 1.2.6!)

И так в 1.2.6 UserID можно узнать используя RoleID использовав следующую формулу: UserID = floor(RoleID / 16) * 16
Таким образом, код проверки на ассемблере будет выглядеть следующим образом:
Код:
mov	 eax, [ebp+this]
mov	 eax, [eax+4]
mov	 eax, [eax+8]
mov	 eax, [eax+30h]
shr	 eax, 4
shl	 eax, 4
cmp	 eax, 20h
jnz	 2AA4

Указанные команды необходимо перевести в opcod и используя Hex-редактор записать в выделенную область.

20h - ID аккаунта, в данном случае 32.
jnz 2AA4 - выход из функции, где 2AAC разность между адресом назначения и адресом команды, следующей сразу за прыжком. В данном случае: 80D4ECF - (080D2425 + 6) = 2AAC. Где:
80D4ECF - адрес выхода из функции
080D2425- адрес по которому находится команда jnz
6 - количество байт занимаемых командой jnz.

Команды и соответствующии им opcod'ы
Код:
mov	 eax, [ebp+8] - 8B 45 08
mov	 eax, [eax+4] - 8B 40 04
mov	 eax, [eax+8] - 8B 40 08
mov	 eax, [eax+30h] - 8B 40 30
shr	 eax, 4 - C1 E8 04
shl	 eax, 4 - C1 E0 04
cmp	 eax, 20h - 83 F8 20
jnz	 2AA4 - 0F 85 A4 2A 00 00

Вeсь Hex-код:
Код:
8B 45 08 8B 40 04 8B 40 08 8B 40 30 C1 E8 04 C1 E0 04 83 F8 20 0F 85 A4 2A 00 00

Должно получится так:
Hex.
7.png

Asm.
8.png

Псевдокод.
9.png

Сохраняем, заливаем GS на сервер, запускаем сервер. После данных изменений Debug будет доступен только аккаунту с ID равным 32.

3. Debug как специальное право GM (добавляется через таблицу auth в MySql).

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

Приступим:
Что бы узнать как осуществляется провека на наличие у GM права на выполнение действия необходимо обратится к функции gplayer_controller::GMCommandHandler, в которой такая проверка осуществляется.
10.png

На скриншоте красным вделенна интересующая нас проверка. Из которой видно, что вызвается функциия GNET:: Privilege::Has_Hide_BeGod. Как видно из названия данная функция проверяет может ли GM использовать нефидимость и неуязвимость.
Двойным кликом переходим к псевдокоду указанной функции и видим, что в ней осуществляется проверка на равенство единице значения элемента массива с индексом равным праву GM, которое записывается в MySql. Сам массив имеет фиксированный размер в 256 байт.
11.png

Т.е. для того чтобы сделать Debug специальным правом GM необходимо выбрать любое понравившееся число в диапозоне от 0 до 255, которое свободно и выполнить проверку на равенство его единице. Я выбрал значения 250.

И так, необходимо узнать смещения до данного массива.
Переходим в фукнцию gplayer_controller::GMCommandHandler и видим, что в качестве параметра в функцию GNET:: Privilege::Has_Hide_BeGod передается _gm_auth, переходим к коду на ассемблере и видим следуещее:
12.png

Переходим к коду на ассемблере функции GNET:: Privilege::Has_Hide_BeGod и видим:
13.png

Таким образом, код проверки на ассемблере будет выглядеть следующим образом:

Код:
mov	 eax, [ebp+8]
mov	 eax, [eax+38h]
cmp	 byte ptr [eax+0FAh], 1
jnz	 2AAC

Указанные команды необходимо перевести в opcod и используя Hex-редактор записать в выделенную область.

0FAh- ID специального права GM, в данном случае 250.
jnz 2AAC - выход из функции, где 2AAC разность между адресом назначения и адресом команды, следующей сразу за прыжком. В данном случае: 80D4ECF - (080D241D+ 6) = 2AAC. Где:
080D4ECF - адрес выхода из функции
080D241D - адрес по которому находится команда jnz
6 - количество байт занимаемых командой jnz.

Команды и соответствующии им opcod'ы
Код:
mov	 eax, [ebp+8] - 8B 45 08
mov	 eax, [eax+38h] - 8B 40 38
cmp	 byte ptr [eax+0FAh], 1 - 80 B8 FA 00 00 00 01
jnz	 2AAC - 0F 85 AC 2A 00 00

Вeсь Hex-код:
Код:
8B 45 08 8B 40 38 80 B8 FA 00 00 00 01 0F 85 AC 2A 00 00

Должно получится так:
Hex.
14.png

Asm.
15.png

Псевдокод.
16.png

Сохраняем, заливаем GS на сервер, запускаем сервер, выдаем кому надо GM право с ID равным 250. После данных изменений Debug будет доступен только аккаунтам, у которых есть GM право с ID равным 250.

4. Финальные штрихи.

И так, дебаг ограничен по одному из приведенных выше критериев и все вроде бы хорошо, но теперь у простых GM'ов не работает телепортация по ctrl+лкм.
Для того чтобы это исправить необходимо отредактировать функцию gplayer_controller::CommandHandler, а именно убрать из нее следующую проверку:
17.png

На ассемблере она выглядит так:
18.png

Для этого необходимо выделенный участок кода затереть.

Должно получится так:
Hex.
19.png

Asm.
20.png

Псевдокод.
21.png


Сохраняем, заливаем GS на сервер, запускаем сервер.
На этом все. Теперь Debug ограничен одним из трех, приведенных выше, способом и у всех GM работает телепортация по ctrl+лкм.
 

Пользователи онлайн

Сейчас на форуме нет ни одного пользователя.

Последние ресурсы

Статистика форума

Темы
3.838
Сообщения
21.197
Пользователи
7.601
Новый пользователь
hkuno