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

Поиск значения таймера между выстрелами


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

Ребята, обращаюсь к тем, кто имел\имеет опыт написания своего отладчика или работы с бряками. Представим себе ситуацию:

В гипотетической игре у игрока есть оружие, стреляющее с интервалом в 0.5 сек. Разработчики этот интервал знают, а вот кто-то посторонний - нет. Как чаще всего ищется значение этого таймера? Что-то типа:

1. Находим адрес патронов

2. Ставим на него бряк

3. Трассируем вверх, пока не найдём нужное значение таймера

Я подумал, что это как-то слишком долго, так что возникла идея автоматизировать процесс. Конкретно - делаем всё то же самое, но программно:

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

2. Прога ставит на адрес int3

3. Включает у себя таймер

4. Шлёт игре несколько LMouseClick-событий, заставляя её пострелять. Или за неё это делает юзер.

5. Замеряет таймером время между int3-срабатываниями

Собственно, если у кого-нибудь есть сорцы по установке int3 - поделитесь, а? :)

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

В общем, как я очень надеюсь, есть решение попроще - в Olly 2.00+ версии есть логгирование бряков (в том числе и бряков на память), а вот для версии 1.10 есть плагин, позволяющий писать скрипты. Завёл сначала посмотреть на логгирование - довольно уныло, голый лог-файл и больше ничего, так что сейчас пишу скрипт - там всё уже веселее. :]

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

Ребята, обращаюсь к тем, кто имел\имеет опыт написания своего отладчика или работы с бряками. Представим себе ситуацию:

В гипотетической игре у игрока есть оружие, стреляющее с интервалом в 0.5 сек. Разработчики этот интервал знают, а вот кто-то посторонний - нет. Как чаще всего ищется значение этого таймера? Что-то типа:

1. Находим адрес патронов

2. Ставим на него бряк

3. Трассируем вверх, пока не найдём нужное значение таймера

Я подумал, что это как-то слишком долго

Не долго, если знать как. Займёт 10 -15 минут. Второй (твой способ ниже) ещё труднее :)

... так что возникла идея автоматизировать процесс. Конкретно - делаем всё то же самое, но программно:

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

2. Прога ставит на адрес int3

3. Включает у себя таймер

4. Шлёт игре несколько LMouseClick-событий, заставляя её пострелять. Или за неё это делает юзер.

5. Замеряет таймером время между int3-срабатываниями

Собственно, если у кого-нибудь есть сорцы по установке int3 - поделитесь, а? :)

Идея по описанию не плохая.

Задержки могут быть как уменьшающийся счётчик. Например, от 1200 до 0. И никакого понятия не будет, сколько в мс единиц этого счётчика. Допустим за 300 мс, счётчик уменьшился с 1200 до 0.

Очень много тонкостей здесь по нахождению адреса таймера или счётчика по приблизительному вычислению времени между бряками. Возможно этот способ не прокатит на большинстве игр.

В общем, как я очень надеюсь, есть решение попроще - в Olly 2.00+ версии есть логгирование бряков (в том числе и бряков на память), а вот для версии 1.10 есть плагин, позволяющий писать скрипты. Завёл сначала посмотреть на логгирование - довольно уныло, голый лог-файл и больше ничего, так что сейчас пишу скрипт - там всё уже веселее. :]

Это довольно муторно. Даже на CE Lua-Engine будет попроще.

Вот мой пример как я искал таймер при выстреле оружия (заняло меньше 10 минут)

1) В CE Находим адрес патронов дробовика

2) Ставим бряк на запись

3) Автотрейсим (есть такая опция в CE) по 10000 инструкций, получаем дерево вызовов

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

Наконец нашли такой бряк на адресе, где распознаётся ввод. В глубину ещё остаётся три бряка до бряка записи патронов.

5) Теперь надо выяснить какой из оставшихся бряков реагирует только на левый клик и не реагирует когда клики идут очень быстро. Я использовал Lua-код для ведения лога в отладчике. И установил что следующий в глубь участок кода, как раз не работает при очень быстрых кликах


{
делать выстрелы
}
иначе
{
продолжать задерживать выстрелы
}
если ((таймер остановился для выстрела) и (т.п.))

Ну, а если в псевдокоде IDA, то


{
int v1; // esi@1
int v2; // eax@1
signed int v3; // eax@4
int v4; // eax@8
double v5; // ST10_8@13

v1 = a1;
v2 = (*(int (__stdcall **)(_DWORD))(**(_DWORD **)(a1 + 40) + 488))(*(_DWORD *)(a1 + 372));
if ( v2
&& (*(_DWORD *)(v2 + 32) > 0 || (*(int (__thiscall **)(int))(*(_DWORD *)(v2 + 44) + 132))(v2 + 44) == -1)
&& (v3 = *(_DWORD *)(v1 + 48), v3 != 2)
&& v3 != 3
&& (v3 < 4 || v3 > 6)
|| (v4 = *(_DWORD *)(v1 + 48)) == 0
|| v4 == 3
|| v4 == 5 && (unsigned __int8)sub_104CB430() )
{
sub_104C6150(*(float *)&v1, 0); // shot 2
*(_DWORD *)(v1 + 112) = 3;
*(_BYTE *)(v1 + 116) = 0;
}
else
{
if ( *(_DWORD *)(v1 + 48) == 2 )
{
v5 = IGSObject::GetTime(v1) - *(float *)(v1 + 52);
if ( sub_104C5C10() - 0.1 < v5 )
{
if ( !*(_BYTE *)(v1 + 116) )
*(_BYTE *)(v1 + 116) = 1;
}
}
}
}
void __usercall sub_104CB1E0(int a1<eax>)

Соответственно там где первый if,т.е. там где первый условный прыг пишем жёсткий JMP на код с комментарием "Shot2". Делаем это скриптом CE с сигнатурой кода, чтобы скрипт работал и на другой версии файла game_x86_rwdi.dll


// MasterGH 2011
[ENABLE]
aobscan(address,74xx83xxxxxx7Fxx8Bxxxx8Dxxxx8BxxxxxxxxxxFFxx83xxxx75xx8Bxxxx83)
label(injectAddress)
registersymbol(injectAddress)

address: // "game_x86_rwdi.dll"+4CB1FC = 0x030DB1FC
injectAddress:
db E9 83 00 00 00 // jmp game_x86_rwdi.dll+4CB284
nop


[DISABLE]
injectAddress:
db 74 30 //je game_x86_rwdi.dll+4CB22E
db 83 78 20 00 // cmp dword ptr [eax+20],00
unregistersymbol(injectAddress)
// Fast Shot

В этом случае все задержки пропали. Дальше копать не стал, т.к. мне лень. Если патроны бесконечные, можно стрелять очень быстро нажимая на мышку без конца. Правда прицел скачет как бешеный. Бесконечные патроны делал заморозив адрес патронов дробовика на 14 патронах.

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

№3, тоже действенный способ, согласен. No recoil (скачущий прицел) обычно ставится сразу же после выстрела, так что можно или потрассировать чуть пониже или есть способ потупее: Берём два оружия с разной отдачей, ищем неизвестное значение, просто переключаясь между ними - значение отдачи часто хранится в структуре оружия, далее ставим бряк и смотрим что туда пишет. Ещё один способ - находим угол, на который крутится мышь (часто лежит рядом с координатами самого игрока) по вертикали, ставим бряк туда, стреляем. Ещё один - просто ищем "неизвестное->увеличилось->уменьшилось", но с одним и тем же оружием - главное успевать ставить паузу. :)

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

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

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

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