Перейти к содержанию

Перехват EndScene DirectX 9


Рекомендуемые сообщения

Доброго времени суток. Очень нуждаюсь в помощи.

 

Вопрос по поводу рисования в чужом окне игры. Ищу сигнатуру функции EndScene, затем хукаю её на свою при помощи MS Detours. Хук ставится отлично, вопросов нет. Вопросы возникают далее...

//Код функции - перехватчика, где font - глобальный указатель на структуру ID3DXFont.
HRESULT __stdcall hkEndScene(LPDIRECT3DDEVICE9 dev)
{
	if (!font) D3DXCreateFont(dev, 30, 0, FW_BOLD, 0, 0, 1, OUT_TT_ONLY_PRECIS, 0, 0 | FF_DONTCARE, "Arial", &font);

	RECT fontRect;
	fontRect.left = 500;
	fontRect.top = 500;
	fontRect.right = 1000;
	fontRect.bottom = 1000;

	font->DrawTextA(0, "Hello, WORLD!", -1, &fontRect, DT_CENTER, D3DCOLOR_RGBA(255, 0, 128, 196));

	return oEndScene(dev);
}

Теперь если делаем инжект библиотеки в главном меню игры - всё отлично работает (даже если зайти в локацию) и надпись держится всё время, если же инжектим в локации - всё работает, но стоит дать игре какое-то сообщение (например, сделать окно активным или нажать в нём), то игра сразу виснет. Под отладчиком я понял, что игра зацикливается в функции PeekMessage, и больше от туда не выходит... ? Если же закоментировать вот эту строчку кода 

font->DrawTextA(0, "Hello, WORLD!", -1, &fontRect, DT_CENTER, D3DCOLOR_RGBA(255, 0, 128, 196));

то надписи естественно нет, но игра и не виснет не при каких раскладах. Следовательно эта функция что-то портит...

Пробовал с помощью _asm вставок сохранять и потом восстанавливать регистры/флаги - не помогло. Стек вроде в порядке, хотя на 100% не уверен. Может что-то связано с согласованием вызовов? Хотя кто его знает, везде stdcall.

 

Если что нужно - уточняйте, скину. Буду благодарен любым идеям.

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

10 часов назад, MadVlad сказал:

Под отладчиком я понял, что игра зацикливается в функции PeekMessage

Любое приложение под винду в цикле опрашивает пришедшие к его окну сообщения. Это нормально. Скорее всего, дело именно во времени инжекта. 

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

Опрашивать то опрашивает, но ведь не вечно в цикле крутится... Просто когда я делаю "шаг с обходом" через эту функцию в отладчике, то не через 1, и не через 5 минут функция не возвращает управление обратно, и следовательно приложение стает "мертвым". Да и с WinAPI я работаю уже не первый год...

2 часа назад, Xipho сказал:

Скорее всего, дело именно во времени инжекта. 

Вот тут не понял, можно по подробнее? Пробовал инжектить Cheat Engine'ом - эффект тот же. Всё работает до первого клика по окну (активация окна).

Изменено пользователем MadVlad
Ссылка на комментарий
Поделиться на другие сайты

Сделал отрисовку только тогда, когда нажата кнопка. Всё работает. Игра вылетает, если к примеру изменить размер окна, сделать окно неактивным а потом его активировать. В чём дело - понятия не имею.

Убрал все GetKeyState - проблема осталась. Убираем функцию font->DrawTextA - игра работает как обычно и не вылетает. Заменял функцию рисования текста на рисование линии - симптомы те же. Игра заходит в функцию PeekMessage, откуда уже не выходит. В отладчике перед входом в функцию PeekMessage видно, что регистры и стек в любом случае одинаковы, отличаются лишь некоторые флаги и ST регистры. Почему игра бесконечно ходит по этой функции и не выходит из неё - сказать сложно...

Вопрос: почему функции рисования нарушают работу игры, и как с этим бороться?

 

И почему я должен ждать +- 1 день, что бы мой пост одобрил модератор? Я что, гадости пишу? Это по меньшей мере глупо, не на одном форуме такого не встречал. Просто дико бесит, когда мне нужно просто так ждать овер дохрена времени, что бы получить ответ...

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

19 часов назад, MadVlad сказал:

Игра вылетает, если к примеру изменить размер окна, сделать окно неактивным а потом его активировать. В чём дело - понятия не имею.

надо reset хук и там делать ReleaseFont +font в 0

 

В 27.06.2019 в 22:28, MadVlad сказал:

Ищу сигнатуру функции EndScene

это лучше хук на коде игры - макс надежно на любой версии ос

 

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

1 час назад, gmz сказал:

ReleaseFont +font в 0

Блин, чувак, спасибо огромное, всё заработало как часики!!!

1 час назад, gmz сказал:

надо reset хук

А можно пожалуйста по подробнее, что означает reset hook?

1 час назад, gmz сказал:

это лучше хук на коде игры - макс надежно на любой версии ос

То есть найти в коде игры, где игра вызывает EndScene, и этот вызов подменить своей функцией, и в конце своей функции вызвать EndScene? Окей, так и сделаю.

 

И ещё есть вопросик: в игре координаты персонажа заданы в double координатах, причём они очень маленькие (например z: 6.63448740346359E-317). Как для них сделать WorldToScreen функцию? Функция D3DXVec3Project принимает параметр D3DXVECTOR3, состоящий из 3-х float значений. Как быть?

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

Эту функцию использовать в конце хук-функции? И где взять аргумент для неё? Или перехватить её и в ней делать ReleaseFont? До меня долго доходит... 

И волнует так же вопрос насчёт координат, изложенный в моём посте выше (в инете ничего не нашел, а искал весь день).

Изменено пользователем MadVlad
Ссылка на комментарий
Поделиться на другие сайты

39 минут назад, MadVlad сказал:

Эту функцию использовать в конце хук-функции? И где взять аргумент для неё? Или перехватить её и в ней делать ReleaseFont?

без параметров хук. потом проверяешь font на 0 и если не 0 - достаешь из font указатель на ReleaseFont

 

44 минуты назад, MadVlad сказал:

вопрос насчёт координат

хз пробуй как флоат

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

Спасибо большое! сделал вот так, путём перехвата Reset функции:

HRESULT __stdcall hkReset(LPDIRECT3DDEVICE9 dev, D3DPRESENT_PARAMETERS *pPresentationParameters)
{
	if (font)
	{
		font->Release();
		font = 0;
	}
    return oReset(dev, pPresentationParameters);
}
10 часов назад, gmz сказал:

лучше хук на коде игры - макс надежно на любой версии ос

Я нашел в игре код, где идёт вызов функций EndScene или Reset, да вот только перехватить не смог. На ассемблере я легко бы это сделал, но пишу я на плюсах, и хукаю с помощью MS Detours, а этой штука предназначена хукать только целые функции, а не конкретные строчки кода (по моему). Писать свой хук путем замены байтов, прыжков, и прочей лабуды мне пока лень, я ведь только учусь, поэтому решил просто хукнуть эти функции, и всё отлично работает! ?

7 часов назад, gmz сказал:

хз пробуй как флоат

Вот тут проблема, если просто приводить тип double к float - все линии идут в одну точку, и то хрен знает куда. Может координаты нужно домножить на какую-то матрицу... Кто его знает)) Но в любом случае спасибо!

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

×
×
  • Создать...

Важная информация

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