Как выводить информацию о предметах в MU online через функцию RealShowItemText

Автор 7mm, 2010 Нояб. 22, 01:19

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Ключевые слова [SEO] mu onlineразработкамодификацияrealshowitemtext

7mm

Для модификации выводимой информации хукаем функцию:

RealShowItemText @ 0x005B0A30

//
// ShowItemText hook
//
// @ItemAddText()
//    Вывод строковой информации о вещи. Используется подобие форматирования:
//    /b - жирный
//    /n - новая строка
//    /a{X} - аттрибуты строки (X - символ)
//        A, 00 - белый
//        B, 01 - голубой
//        C, 02 - красный
//        D, 03 - жёлтый
//        E, 04 - зелёный
//        F, 05 - белый, красный фон
//        G, 06 - сиреневый (ближе к красному)
//        H, 07 - белый, синий фон
//        I, 08 - белый, бежевый фон
//        J, 09 - зелёный, синий фон
//        K, 10 - серый
//        L, 11 - сиреневый (светлый)
//        M, 12 - сиреневый (тёмный)
//        N, 13 - оранжевый

#define SHOW_INFO_LINE            0x07CD1800
#define SHOW_INFO_LINE_NR        0x07D0490C
#define SHOW_INFO_LINE_BOLD        0x07D01ED8
#define SHOW_INFO_LINE_STYLE        0x07CD29F0

int ItemAddText(char * ptext)
{
int index;

for (index = REF_32(SHOW_INFO_LINE_NR); index < 20; index++) {
char * pline = (char *)(SHOW_INFO_LINE + index * 100);

REF_16(pline) = 0x000A;

for (;;) {
// check for EOL
if (REF_08(ptext) == 0) {
return index;
}
// check for </n>
if (REF_16(ptext) == 0x6E2F) {
ptext = ptext + 2;
break;
}
// check for </b>
if (REF_16(ptext) == 0x622F) {
REF_32(SHOW_INFO_LINE_BOLD + index * 4) = 1;
ptext = ptext + 2;
}
// check for </a{X}>
if (REF_16(ptext) == 0x612F) {
REF_32(SHOW_INFO_LINE_STYLE + index * 4) = REF_08(ptext + 2) - 'A';
ptext = ptext + 3;
}
*pline++ = *ptext++, *pline = 0;
}

REF_32(SHOW_INFO_LINE_NR) = index;
}

return index;
}

DECLARE_HOOK(ShowItemText, int pos_x, int pos_y, int lines, int a4, int a5, int a6, int a7)
{
void * pItem;

GET_REG_VALUE(pItem, ebx);

if (IsBadReadPtr(pItem, 4)) {
DbgPrint("Bad <ebx> pointer detected. It's may be not a bug!n");
} else {
if (ItemCheck(REF_16(pItem))) {
lines = ItemAddText("/b/aE Этот предмет/n /b/aH добавлен в игру!/n");
}
}

return RealShowItemText(pos_x, pos_y, lines, a4, a5, a6, a7);
}

Результат:
## здесь был скриншот ##

Mr.Kernighan


7mm


netpartizan


Bason4ik


SmallHabit

Цитировать7mm,может расскажешь как оффсеты эти найти в других мейнах?
Дебаггером =)

Mr.Kernighan

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

Bason4ik


SmallHabit

7mm, я бы в дальнейшем вам советовал приводить и примеры самого асм кода из маина который мы переделываем, да и пояснять что да как, ибо я думаю у вас единственного на данном форуме хорошее знание асма, темболее что клиент это самое больное место девелоперов Му коммунити, ибо на сервере у нас есть и .pdb и .map файлы, чего нельзя сказать о клиенте. В общем, если вас не затруднит я бы попросил написать маленькую статейку о том как хукать всякие функции из маина, как распознать что данная функция делает и т.д. Я думаю это многим бы помогло =)

А за сурсик спасибо. =)

7mm

Цитата: Bason4ik от 2010 Нояб. 28, 17:52  7mm,может расскажешь как оффсеты эти найти в других мейнах?

Посмотрите на той версии клиента, что я дал. Разберитесь - что к чему, потом ищите похожее на других версиях. Вам тут правильно подсказали взять в руки отладчик, дизассемблер - без этого никак.

2SmallHabit
С чего лучше начать, какие вопросы осветить?.. Тема объёмная, всё сразу описать наверняка не удастся...

SmallHabit

ЦитироватьDECLARE_HOOK(ShowItemText, int pos_x, int pos_y, int lines, int a4, int a5, int a6, int a7)

Хотя бы с этого =) Откуда берём кол-во переменных, их типы и т.д. ну и про саму функцию DECLARE_HOOK хотелось немного услышать =)

Killbrum

Цитата: SmallHabit от 2010 Нояб. 29, 20:42  Хотя бы с этого =) Откуда берём кол-во переменных, их типы и т.д. ну и про саму функцию DECLARE_HOOK хотелось немного услышать =)
О_о ну наверно же по кол-ву вызванных pushpop и по размерностям переменных в байтах. От туда и смотрим сколько входных аргументов имеет данная ф-ция.

Лично у меня по коду несколько вопросов:
1) ShowItemText hook что это? Класс? Адрес? Переменная? Т.к. это идет входным параметром
2) что такое REF_32 ? и т.д.

А вообще о идее статей. Лично меня интересует как Вы это находите. Ну пойму как это найти в Си коде. Но а здесь как? В своё время я пытался добавить новых монстров но вместо этого выкопал несколько других ф-ций. Но у меня примерно занимало 2-3 часа 1 ф-ция. Да и вывертывало от вида дебуг кода...

Если у Вас есть конечно желание то можете написать примерный цикл статей в таком порядке:

1) основные принципы хуков. В чем тут загвоздка? я например не очень в этом разбираюсь. Почему? Просто статей хороших к сожл нету. Вот у меня валяется книжка Windows via C++ но Рихтер очень хитро всё описывает и реально же его приемы далеко не всегда и не везде работают. А библиотека МС-Рема вообще на делфях
2) основные принципы реверсинга. Что как и почем. (здесь не стоит рассказывать о самом АСМ т.к. если человек этого не знает то ему еще рано. Ну а просто расписать как примерно можно что то находить)
3) более детальное описание принципов нахождения "того что надо"

SmallHabit

ЦитироватьО_о ну наверно же по кол-ву вызванных pushpop и по размерностям переменных в байтах. От туда и смотрим сколько входных аргументов имеет данная ф-ция.
Поверь, я даже этого незнал, ну сколько входных, а каких типов? оО

ЦитироватьА вообще о идее статей. Лично меня интересует как Вы это находите. Ну пойму как это найти в Си коде. Но а здесь как? В своё время я пытался добавить новых монстров но вместо этого выкопал несколько других ф-ций. Но у меня примерно занимало 2-3 часа 1 ф-ция. Да и вывертывало от вида дебуг кода...
Когда пытался добавить мапы уходило примерно столько-же времени :D

Killbrum

Цитата: SmallHabit от 2010 Нояб. 29, 21:37  Поверь, я даже этого незнал, ну сколько входных, а каких типов? оО

Когда пытался добавить мапы уходило примерно столько-же времени :D
не прибедняйся =)

а по теме: думаю смотря что лежит в стеке. Например если 4 байта то это предположительно DWORD.

Mr.Kernighan

to SmallHabit :)
А я вот с удовольствием почитал бы информацию о работе протоколов/пакетов а так же шифрование c1/c2/c3/c4 на руссишь :)
Я в принципе писал тебе уже на твоем форуме, но время блин со всех сторон жмет, и не всегда удается выйти в skype и обсудить это с тобой, поэтому хорошим решением не только для меня но и для всех кому тема будет интересна, сделать хороший туторик.
Мне интересно как я и говорил, проверка отдельных byte/ов, то есть их определенные действия.
Каким методом ты узнаешь за что отвечает определенный byte, за исключением пакетов что уже имеются в структурах Deathway, к примеру новых.
Я в принципе уже давно в mu community, но раньше я программировал то, из того что уже имелось, потом долгое время я не следил за событиями что происходили в этой сфере, а сейчас без сторонней поддержки ну очень сложно что либо сделать... Буду благодарен за любой изложенный материал ;)

7mm

Для доступа к данным, определяемым смещениями, я использую следующие макросы:
#define REF_08(x) (*(unsigned char *)(x))
#define REF_16(x) (*(unsigned short *)(x))
#define REF_32(x) (*(unsigned int *)(x))
В этом случае, если есть некий константный адрес, обращение к данным будет выглядеть следующим образом:

#define MY_OFFSET 0x12345678

char x_char = REF_08(MY_OFFSET);
REF_08(MY_OFFSET) = x_char;

SmallHabit

Brain, спасибо что напомнил, обязательно закончу ту статейку, только есть пара вопросов? Стиль написания оставлять тот-же?(скрины,примеры) или же писать всё обо всём в общем?

7mm

Цитировать#define REF_08(x) (*(unsigned char *)(x))
#define REF_16(x) (*(unsigned short *)(x))
#define REF_32(x) (*(unsigned int *)(x))

Как распознать в асме какой именно тип данных используется? А то вдруг там BYTE используется а я буду выбирать как int или char? Не велика беда, но всё таки =)

7mm

2SmallHabit
Ну в общем случае, это наверное невозможно. На самом деле, первое, на что можно смотреть - это размерность данных. 1 - BYTE, 2 - WORD, 4 - DWORD. Этого как правило бывает достаточно. Это пожалуй базовые типы, являющиеся к тому же беззнаковыми. Если копать глубже, то тот же BYTE может на деле оказаться BOOLEAN, если диапазон значений, например, 1 и 0. С другой стороны, тип BOOL с тем же диапазоном значений занимает 4 байта, т.е. DWORD.

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

Mr.Kernighan

ЦитироватьBrain, спасибо что напомнил, обязательно закончу ту статейку, только есть пара вопросов? Стиль написания оставлять тот-же?(скрины,примеры) или же писать всё обо всём в общем?
Ну в зависимости, думаю определять тебе, где необходимы скриншоты/где все обо всем, а где нет.

Killbrum

Цитата: SmallHabit от 2010 Нояб. 30, 13:59  [Как распознать в асме какой именно тип данных используется? А то вдруг там BYTE используется а я буду выбирать как int или char? Не велика беда, но всё таки =)
Cамого типа BYTE в стандарте нету. Это просто ехидные проделки мелкософта дабы обозначить "свои" типы данных и делать удобный переход с х16 на х32 и с х32 на х64. Если я не ошибаюсь и есть unsigned char, смотри typedef

Похожие темы (5)

Сообщений: 37
Просмотров: 21561

Сообщений: 127
Просмотров: 38046

Сообщений: 32
Просмотров: 12376