ArxLex

Sniper: Ghost Warrior, обман кол-ва гранат

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

Кто может помочь мне со взломом? Пытаюсь найти адрес гранат методом умень./увелич., но ничего не выходит. В итоге остаются 2 адреса текстов кол-ва гранат в Юникоде. Может есть какой-то другой метод? В качестве инструмента пользовался MHS, CE5.6. Адреса жизней, патронов и потронов в магазине оружия нашел благополучно...

post-40-1277626241,54_thumb.jpg

post-40-1277626247,28_thumb.jpg

post-40-1277626251,49_thumb.jpg

0

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


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

Могу помочь советом.

Постарайся искать для удобства правилом не известное, а затем отсевом изменилось на единицу в MHS или Artmoney (такого правила в CE нет), когда количество гранат увеличивается или уменьшается. Минимальное кол-во гранат должно быть не меньше 1, т.к. если гранат ноль, то возможно адрес с количеством гранат может не существовать и создаваться, когда гранат становиться больше 1.

Я говорю о видимом числе гранат. На самом деле может быть на единицу меньше,или счётчик гранат, когда их видимое кол-во становиться больше, может идти не в сторону увеличения, а уменьшения (и наоборот).. может быть объектный тип гранат.

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

1

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


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

Спасибо за совет! Я пробовал поиск с отсевом изменилось на единицу. Но увы все оставшиеся адреса не рабочие(не реагируют на фриз)... А с помощью юникодов я ещё никогда не делал поиски с бряком (слышал что, большинство флеш игр таким образом ломаются)... Может скачаешь и попробуешь ради совместного интереса? Игра весит всего 900 мб(репак). Вот ссылка на торрент :grin:

0

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


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

Там не нужен сейв, в начале игры на тренеровках дают кучу гранат. Ты только не нажимай на "Прекратить тренеровку и начать миссии"... O-=

0

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


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

Короче что я узнал.

Гранаты имеют объектный тип, чего я боялся. Есть шаблонная функция, которая считает у объекта подобъекты. Гранаты подсчитываются и выводятся на экран.

Если не понятно что такое шаблонная функция, то это функция которая может принмать и возвращать разные типы данных. В данном случае эта функция может обрабатывать объекты разных типов.

Выглядит она следующим образом:

int __userpurge sub_10045550<eax>(int a1<edi>, int a2) // edi указатель на объект игрока, a2 - гранаты игрока (или другие)
{
int v2; // ebx@1
unsigned int v3; // esi@1
int v4; // eax@2
int v5; // eax@2
char v6; // zf@2
int v7; // eax@3

v2 = 0;
v3 = 0;
if ( *(_DWORD *)(a1 + 1308) )// если количество "подобъектов" больше нуля, то
{
do
{
v5 = *(_DWORD *)(a1 + 1304); // указатель на массив указателей подобъектов
v6 = *(_DWORD *)(v5 + 8 * v3) == a2; // опредилить тип объекта = 0x14 гранаты
v4 = v5 + 8 * v3; // для получения и вызова функции, скорее это итератор
if ( v6 ) // если это гранаты
{
v7 = *(_DWORD *)(v4 + 4); // определить алгоритм итератора
if ( v7 ) // если определеилили, то вызывать
{
if ( (unsigned __int8)(*(int (__thiscall **)(int))(*(_DWORD *)v7 + 788))(v7) ) // если граната как объект существует
++v2; // то увеличить счётчик
}
}
++v3;
}
while ( v3 < *(_DWORD *)(a1 + 1308) );
}
return v2; // возращаем кол-во гранат
}

Если сделать инжект и возвращать например всегда 20 гранат, то визуально будет всегда 20 гранат. Но на самом деле они будут уменьшаться при броске. Почему нельзя найти адрес гранат, потому что он передаётся через стек и затем пропадает.

Как я и писал я узнал это всё поставив бряк на запись юникодовские данные в OllyDbg. Также для наглядности использовал IDA.

Ну а теперь чтобы сделать множество гранат.

1) Либо не давать разрушить объект гранаты при её броске.

2) При броске гранаты, создавать новую.

+ если назначить некоторое множество гранат, то нужно их сконстурировать через констурктор.

На всё про всё требуется время на исследование, пока у меня с ним напряженка.

Вот скрипт на отображение 20 гранат:

[ENABLE]
aobscan(_faddress,xx8bxxxxxxxxxx8bxxffxx8bxxxxxxxxxxd9xxxxxxxxxxd9xxxxxxxxxxd8xxdf)
alloc(_newmem,2048)
label(_returnhere)
label(_originalcode)

_newmem:

_originalcode:
mov eax, #20
push eax
mov eax,[esi+00000308]
jmp _returnhere

_faddress: // 00FB6ADA = GameDLL_x86.dll+556ADA
jmp _newmem
nop
nop
_returnhere:

[DISABLE]
aobscan(_faddress,90908bxxffxx8bxxxxxxxxxxd9xxxxxxxxxxd9xxxxxxxxxxd8xxdf)

_faddress-5:
push eax
mov eax,[esi+00000308]

dealloc(_newmem)
//Alt: db 50 8B 86 08 03 00 00

Зайдёшь в call выше адреса сигнатуры xx8bxxxxxxxxxx8bxxffxx8bxxxxxxxxxxd9xxxxxxxxxxd9xxxxxxxxxxd8xxdf и увидешь дизассемблерный код, который был переведён на сишный

00AA5550   /$  53                 PUSH EBX
00AA5551 |. 55 PUSH EBP
00AA5552 |. 8B6C24 0C MOV EBP,DWORD PTR [ESP+C] ; GameDLL_.00FB6ADA
00AA5556 |. 56 PUSH ESI
00AA5557 |. 33DB XOR EBX,EBX
00AA5559 |. 33F6 XOR ESI,ESI
00AA555B |. 399F 1C050000 CMP DWORD PTR [EDI+51C],EBX
00AA5561 |. 76 33 JBE SHORT GameDLL_.00AA5596
00AA5563 |> 8B87 18050000 /MOV EAX,DWORD PTR [EDI+518]
00AA5569 |. 392CF0 |CMP DWORD PTR [EAX+ESI*8],EBP
00AA556C |. 8D04F0 |LEA EAX,DWORD PTR [EAX+ESI*8]
00AA556F |. 75 1A |JNZ SHORT GameDLL_.00AA558B
00AA5571 |. 8B40 04 |MOV EAX,DWORD PTR [EAX+4]
00AA5574 |. 85C0 |TEST EAX,EAX
00AA5576 |. 74 13 |JE SHORT GameDLL_.00AA558B
00AA5578 |. 8B10 |MOV EDX,DWORD PTR [EAX]
00AA557A |. 8BC8 |MOV ECX,EAX
00AA557C |. 8B82 14030000 |MOV EAX,DWORD PTR [EDX+314]
00AA5582 |. FFD0 |CALL NEAR EAX
00AA5584 |. 84C0 |TEST AL,AL
00AA5586 |. 74 03 |JE SHORT GameDLL_.00AA558B
00AA5588 |. 83C3 01 |ADD EBX,1
00AA558B |> 83C6 01 |ADD ESI,1
00AA558E |. 3BB7 1C050000 |CMP ESI,DWORD PTR [EDI+51C]
00AA5594 |.^ 72 CD \JB SHORT GameDLL_.00AA5563
00AA5596 |> 5E POP ESI ; GameDLL_.012CE8FC
00AA5597 |. 5D POP EBP ; GameDLL_.012CE8FC
00AA5598 |. 8BC3 MOV EAX,EBX
00AA559A |. 5B POP EBX ; GameDLL_.012CE8FC
00AA559B \. C2 0400 RET 4

Пока больше ничем помочь не могу.

1

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


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

спасибо хоть за то что пояснил cool.gif

0

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


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

С гренами не разобрался но вот чё вышло по этой игре

0

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


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

Я писал статью про Sniper: Ghost Warrior , в общем так и не дописал. Может быть у кого получиться разобраться. Я урывками пытаюсь одолеть, но пока без результа.

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

Есть следующий вариант, конструктор гранат точно есть   B)

1) Игра вероятно по скрипту создаёт на карте Тренировки через какое-то время гранату.

Граната эта обвёрнута в оболочку базового класса "игровой объект".

2) "Игровые объекты" состоят в динамическом массиве нашего героя следующим образом как было описано в статье (см. ссылку выше). 

{{указтель на игровой объект, тип игрового объекта},

{указтель на игровой объект, тип игрового объекта},....}

Тип гранат у нас 0x14.

3)" Игровой объект" сам состоит в каком-то классе контроллера. Контролллер по ходу включает методы визуализации гранаты и контроль  её свойств из объекта-владельца "игрового мира".

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

Из этих 4-х пунктов следует. Что мы должны "инициализировать" гранату в мире и вызвать функцию взятия этой гранаты. 

Конструктор, я думаю именно тот который нужен один из 10-ти я нашёл (они срабатывали всегда перед появлением гранаты в мире) IGSObject__CreateObject .

int __thiscall sub_10200520(int this)
{
  int v1; // ebp@1
  int result; // eax@2
  const CHAR *v3; // eax@3
  int v4; // eax@5
  int v5; // eax@6
  int v6; // esi@6
  int v7; // eax@6
  void (__thiscall *v8)(_DWORD, _DWORD); // eax@7

  v1 = this;
  if ( *(_DWORD *)(this + 116) )
  {
    v3 = *(const CHAR **)(this + 112);
    if ( !v3 )
      v3 = &byte_106B1600;
    v4 = (*(int (__stdcall **)(const CHAR *))(*(_DWORD *)dword_10A47500 + 20))(v3);
    if ( v4
      && (v7 = IGSObject__CreateObject(v1 + 24, v4, 0, 0),
          v5 = _RTDynamicCast(v7, 0, &off_10A140D4, &off_10A19214, 0),
          v6 = v5,
          v5) )
    {
      v8 = *(void (__thiscall **)(_DWORD, _DWORD))(*(_DWORD *)(v5 + 1000) + 20);
      *(_BYTE *)(v6 + 1020) = 1;
      v8(v6 + 1000, v1);
      IGSObject__InitObject(v6 + 24, v1 + 24);
      result = v6 + 1000;
    }
    else
    {
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

Ну а дальше у меня пока копать нет времени, надо бежать по делам.

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

#include <typeinfo> // Для std::bad_cast
#include <iostream> // Для std::cerr и др.

class A
{
public:
    // Механизм динамической идентификации типа данных доступен только для полиморфных
    // классов (т.е. классов, содержащих хотя бы одну виртуальную функцию-член)
    virtual void foo();

    // другие члены класса...
};

class B : public A
{
public:
    void methodSpecificToB();

    // другие члены класса...
};

void my_function(A& my_a)
{
    try
    {
        B& my_b = dynamic_cast<B&>(my_a);
        my_b.methodSpecificToB();
    }
    catch (const std::bad_cast& e)
    {
        std::cerr << e.what() << std::endl;
        std::cerr << "Этот объект не является объектом типа B" << std::endl;
    }
}

0

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


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

Моя цитата:

1) Игра вероятно по скрипту создаёт на карте Тренировки через какое-то время гранату.

Граната эта обвёрнута в оболочку базового класса "игровой объект".

Забыл сказать, что в тот день когда я писал пост выше, я вышел на цикл создания гранат о нём я писал в своей теме чем я занимаюсь - ссылка.

Так вот цикл из того поста:

void __stdcall sub_10050F50(int a1, float a2)
{
  int v2; // eax@1
  int v3; // ecx@2
  int v4; // ebp@3
  int v5; // eax@4
  int v6; // edi@4
  double v7; // st6@7
  int v8; // [sp+8h] [bp+4h]@2

  v2 = *(_DWORD *)(a1 + 20);
  if ( v2 )
  {
    v3 = *(_DWORD *)(a1 + 12);
    v8 = *(_DWORD *)(a1 + 12);
    if ( v2 > 0 )
    {
      v4 = v2;
      do
      {
        v5 = *(_DWORD *)(v3 + 8);
        v6 = v3 + 8;
        if ( v5 )
        {
          if ( *(_BYTE *)(v3 + 24) )
            goto LABEL_21;
          v7 = *(float *)(v3 + 28);
          if ( *(_BYTE *)(v3 + 26) )
            v7 = v7 + *(float *)(v5 + 480) * *(float *)(v3 + 32);
          if ( a2 - *(float *)(v3 + 36) < v7 )
          {
LABEL_21:
            v3 = *(_DWORD *)v3;
          }
          else
          {
            if ( *(_BYTE *)(v3 + 25) )
              *(float *)(v3 + 36) = a2;
            (*(void (__cdecl **)(_DWORD))(*(_DWORD *)(v3 + 16) + 16))(*(_DWORD *)(v3 + 12));
            if ( *(_BYTE *)(v6 + 17) )
            {
              v3 = *(_DWORD *)v8;
            }
            else
            {
              if ( *(_DWORD *)(v6 + 12) )
                sub_100525F0(*(_DWORD *)(*(_DWORD *)(v6 + 4) + 8) + 76);
              v3 = *(_DWORD *)sub_100526C0();
            }
          }
        }
        else
        {
          v3 = *(_DWORD *)sub_100526C0();
        }
        --v4;
        v8 = v3;
      }
      while ( v4 );
    }
  }
}

...обрабатывал на карте тренировки 314 действий в игре. Одно из них создание гранат под данным счётчика по данным конечного кол-ва гранат. Так как цикл действий выполняется с каким-то интервалом- думаю секундным, то по счётчику получается создание гранат через какой-то период. В общем копать цикл нужно этот. Он находится (если я не забыл) в engine_x86.dll. На этот цикл можно выйти если поставить бряки на все конструкторы в OllyDbg, а затем найти те которые срабатывают при создании гранаты. Затем идём по коду по ретам вверх пока не выйдем в engine_x86.dll и там наткнёмся на этот цикл. Если кому нужно, то могу привести точные координаты. 

0

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


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

Я тоже не могу найти гранаты,один раз нашел экранное значение С4 и все <_<

0

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


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

Нужно зайти в режим тренировки. На столе будут появляться гранаты. Я искал адрес с текстом. А дальше уже плохо помню. Вроде ставил бряк на адрес в OllyDbg и смотрел что выше по коду пока не наткнулся на код подсчитывающий количество гранат, а там уже увидел, что есть структура в ней 8 указателей на 8-мь гранат, если 8 гранат было взято со стола.

0

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


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

NullAlex: Читаем пункт 1.3 основных правил форума.
[ENABLE] alloc(newmem,2048)label(returnhere)label(originalcode)label(exit) newmem:mov [esi+18],#99originalcode://mov [esi+18],eaxmov [esi],nvd3dum.dll+937018 exit:jmp returnhere "nvd3dum.dll"+4A9D11:jmp newmemnopnopnopnopreturnhere:    [DISABLE]dealloc(newmem)"nvd3dum.dll"+4A9D11:mov [esi+18],eaxmov [esi],nvd3dum.dll+937018
0

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


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

Интересно! Почему патчится кусок драйвера от nvidia? Как ты вышел на эту инструкцию?
0

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


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

Интересно! Почему патчится кусок драйвера от nvidia? Как ты вышел на эту инструкцию?

нашел патроны, и через структуру нашел гранаты 

0

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


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

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

 

Инъекция например должна быть в GameDLL_x86.dll.  А вот nvd3dum.dll файло из восьмерки. 

 

Проверять я это не буду, не верю  :)

0

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


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

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

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

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

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


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

Войти

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


Войти сейчас