MasterGH

X-Ray Engine (S.T.A.L.K.E.R. - игровые движки)

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

post-3-0-92354900-1424602998_thumb.jpeg

 

 

X-Ray Engine 1.5

 

Ссылка на репозиторий

 

This repository contains X-Ray Engine sources based on version 1.5.10. The original engine is used in S.T.A.L.K.E.R. Clear Sky game released by GSC Game World.

X-Ray Engine 1.6

 

Ссылка на репозиторий

 

This repository contains X-Ray Engine sources based on version 1.6.02. The original engine is used in S.T.A.L.K.E.R. Call of Pripyat game released by GSC Game World.

It is a place to share ideas on what to implement, gather people that want to work on the engine, and work on the source code.

 

Инструкции по работе и установке читем там же.

Как пользоваться ?

 

Пример. В отладке нашли код перезарядки и рядом слово WeaponMagazined.cpp. Ищем в репозитории в соответствии с ближайшей версии игры и находим ссылку.

 

Берем ida + декопиль, смотрим на файл и ищем хоть какие-то соответствия перезарядки.... 

Надеюсь эта информация будет кому-то полезна для тренировки дизассемблирования. Мне кажется она вообще просто бесценной. Очень большая редкость чтобы к популярным играм выкладывали сорцы движка.


 

Выводы после изучения исходников:

Вывод1

 

Как в отладке так и в исходнике паляться строковые переменные имеющие уникальное название. Эти переменные используются для получения значений-настроек по ключевым словам в том числе определяемых по уровню сложности игры.

Например,

void CShootingObject::Load (LPCSTR section){//...   //время затрачиваемое на выстрел   fOneShotTime = pSettings->r_float (section,"rpm");//...}
 

Примеры ключевых слов можно посмотреть еще под спойлером

 

 

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

 

ПРИМЕНЕНИЕ

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

 

1. Ищем строки по всему коду через CE.

2. Выбираем какую-нибудь похожую на настройки.

3. Ставим бряк на чтение.

4. Если во время игры не срабатывает, то сохраняем игру в слот и загружаем его.

5. Инструкции должны появиться(!) в окне брейкпоинтов, главное чтоб адрес текста не менял своего положения после перезагрузки. Т.е. мы окажемся внутри r_float() функции, которая будет возвращать все float типы по аргументам

6. На какой-нибудь инструкции чешем все стринг константы

7. Пишем инъекцию с фильтром на определенную константу и значение

8. Перезагружаемся(грузим слот сохранения, или начать игру заного) и видим изменения.

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

 

Эксперименты показали, что на практике подтверждается как минимум поиск констрант. Вот скриншоты констрант.

 

Во время загрузки:

post-3-0-18425800-1424617252_thumb.png post-3-0-94140500-1424617256_thumb.png post-3-0-95060400-1424617260_thumb.png post-3-0-54051900-1424617265_thumb.png post-3-0-89718300-1424617269_thumb.png

 

Во время игры, да-да, даже во время игры происходит поиск констант, что наверняка затратно по времени.

post-3-0-68500900-1424617275_thumb.pngpost-3-0-19293200-1424617283_thumb.png

 

Жаль проскакивающие значения на адресе не имеют тип string и юникод, и время обновления не хватает.

void CShootingObject::LoadFireParams( LPCSTR section ){	string32	buffer;	shared_str	s_sHitPower;	shared_str	s_sHitPowerCritical;	//базовая дисперсия оружия	fireDispersionBase	= deg2rad( pSettings->r_float	(section,"fire_dispersion_base"	) );	//сила выстрела и его мощьность	s_sHitPower			= pSettings->r_string_wb(section, "hit_power" );//читаем строку силы хита пули оружия	s_sHitPowerCritical	= pSettings->r_string_wb(section, "hit_power_critical" );	fvHitPower[egdMaster]			= (float)atof(_GetItem(*s_sHitPower,0,buffer));//первый параметр - это хит для уровня игры мастер	fvHitPowerCritical[egdMaster]	= (float)atof(_GetItem(*s_sHitPowerCritical,0,buffer));//первый параметр - это хит для уровня игры мастер	fvHitPower[egdNovice] = fvHitPower[egdStalker] = fvHitPower[egdVeteran] = fvHitPower[egdMaster];//изначально параметры для других уровней сложности такие же	fvHitPowerCritical[egdNovice] = fvHitPowerCritical[egdStalker] = fvHitPowerCritical[egdVeteran] = fvHitPowerCritical[egdMaster];//изначально параметры для других уровней сложности такие же	int num_game_diff_param=_GetItemCount(*s_sHitPower);//узнаём колличество параметров для хитов	if (num_game_diff_param>1)//если задан второй параметр хита	{		fvHitPower[egdVeteran]	= (float)atof(_GetItem(*s_sHitPower,1,buffer));//то вычитываем его для уровня ветерана	}	if (num_game_diff_param>2)//если задан третий параметр хита	{		fvHitPower[egdStalker]	= (float)atof(_GetItem(*s_sHitPower,2,buffer));//то вычитываем его для уровня сталкера	}	if (num_game_diff_param>3)//если задан четвёртый параметр хита	{		fvHitPower[egdNovice]	= (float)atof(_GetItem(*s_sHitPower,3,buffer));//то вычитываем его для уровня новичка	}	num_game_diff_param=_GetItemCount(*s_sHitPowerCritical);//узнаём колличество параметров	if (num_game_diff_param>1)//если задан второй параметр хита	{		fvHitPowerCritical[egdVeteran]	= (float)atof(_GetItem(*s_sHitPowerCritical,1,buffer));//то вычитываем его для уровня ветерана	}	if (num_game_diff_param>2)//если задан третий параметр хита	{		fvHitPowerCritical[egdStalker]	= (float)atof(_GetItem(*s_sHitPowerCritical,2,buffer));//то вычитываем его для уровня сталкера	}	if (num_game_diff_param>3)//если задан четвёртый параметр хита	{		fvHitPowerCritical[egdNovice]	= (float)atof(_GetItem(*s_sHitPowerCritical,3,buffer));//то вычитываем его для уровня новичка	}	fHitImpulse			= pSettings->r_float	(section, "hit_impulse" );	//максимальное расстояние полета пули	fireDistance		= pSettings->r_float	(section, "fire_distance" );	//начальная скорость пули	m_fStartBulletSpeed = pSettings->r_float	(section, "bullet_speed" );	m_bUseAimBullet		= pSettings->r_bool		(section, "use_aim_bullet" );	if (m_bUseAimBullet)	{		m_fTimeToAim		= pSettings->r_float	(section, "time_to_aim" );	}}
void CShootingObject::Load (LPCSTR section){//...   //время затрачиваемое на выстрел   fOneShotTime = pSettings->r_float (section,"rpm");//...}
Изменено пользователем MasterGH
0

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


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

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

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

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

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


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

Войти

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


Войти сейчас