Объявления
Поздравляем
VDV_forever


Друзья, если не получается зарегистрироваться, напишите на почту vdv_forever@bk.ru.
Я оторву свою задницу от всех дел и обязательно Вас активирую! :smile10:
Добро пожаловать на геройский форум! :smile25:

База данных IDA от void17

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineАватара пользователя
void_17  
имя: DM
Ветеран
Ветеран
 
Сообщения: 530
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 116 раз.

Re: База данных IDA от void17

Сообщение void_17 » 30 ноя 2021, 03:35

Хорошо. Молодцы. Пока работаете, запишите мне "техническое задание". Какие адреса вас интересуют и какие вас смущают. Я приеду домой и разберусь, отправлю вам. Не забудьте базы обновлять кстати.
Вернуться к началу

offlineАватара пользователя
void_17  
имя: DM
Ветеран
Ветеран
 
Сообщения: 530
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 116 раз.

Re: База данных IDA от void17

Сообщение void_17 » 30 ноя 2021, 03:36

Кстати. На декомпиляционный листинг Ghidra надеяться не рекоммендую практически в большинстве случаев. Все-таки между RoE и SoD большая разница, даже в полях структур.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5540
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2155 раз.

Re: База данных IDA от void17

Сообщение AlexSpl » 30 ноя 2021, 03:40

Цитата:
Какие адреса вас интересуют и какие вас смущают. Я приеду домой и разберусь, отправлю вам. Не забудьте базы обновлять кстати.

Меня интересует всё, что связано с использованием заклинаний AI, и вообще с заклинаниями.

Кстати, начало army, скорее всего, тоже два вектора для Гипноза:

Код: Выделить всё
#pragma pack(push, 4)
struct army
{
  vector hypnotize2[2];
  char f_000[20];
  enum ECreatureType type;
 
...

combatMonster_0043E720() может быть функцией удаления отряда из вектора Гипноза. А sub_00448A40() - освобождением вектора (начало = конец).
Вернуться к началу

offlineАватара пользователя
void_17  
имя: DM
Ветеран
Ветеран
 
Сообщения: 530
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 116 раз.

Re: База данных IDA от void17

Сообщение void_17 » 30 ноя 2021, 04:23

AlexSpl писал(а):

Цитата:
Какие адреса вас интересуют и какие вас смущают. Я приеду домой и разберусь, отправлю вам. Не забудьте базы обновлять кстати.

Меня интересует всё, что связано с использованием заклинаний AI, и вообще с заклинаниями.

Кстати, начало army, скорее всего, тоже два вектора для Гипноза:

Код: Выделить всё
#pragma pack(push, 4)
struct army
{
  vector hypnotize2[2];
  char f_000[20];
  enum ECreatureType type;
 
...

combatMonster_0043E720() может быть функцией удаления отряда из вектора Гипноза. А sub_00448A40() - освобождением вектора (начало = конец).


Полный бред, как по мне. В диске есть исправленная база 1.2 с army. В самом начале army есть поле hex интовое. Никак не может быть даже логически там никаких два vector-а, это не самое главное ведь. Эти два vector-a могут быть посередине, ну никак не в начале. Смотрите простые функции combatManager-a.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5540
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2155 раз.

Re: База данных IDA от void17

Сообщение AlexSpl » 30 ноя 2021, 04:27

Начало WalkTo:

Код: Выделить всё
v5 = a1->activeSpellDuration[54];
  a1->hypnotize2[1].First = -1;
  a1->hypnotize2[1].Allocator = -1;
  LODWORD(v3) = a1->creatureInfo.speed;
  if ( v5 )
  {
    if ( (a1->creatureInfo.flags & 0x40) != 0 )
    {
      LODWORD(v3) = 0;
    }
    else
    {
      a5a = a1->creatureInfo.speed;
      v3 = (a5a * a1->slow_effect);
      if ( v3 <= 0 )
        LODWORD(v3) = 1;
    }
  }
  if ( !army::FindPath(a1, a2, v3, 0, 0) )
    return 0;
  First = a1->hypnotized[1].First;
  secondHexOrientation = a1->secondHexOrientation;
  if ( First )
    v8 = (a1->hypnotized[1].Last - First) >> 2;
  else
    v8 = 0;
  v9 = v8;
  v10 = v8 - 1;
  if ( v9 > 0 )
  {
    do
    {
      combatMonster_0043E720((*(a1->hypnotized[1].First + v10) + 1300), a1);
      v11 = v10--;
    }
    while ( v11 > 0 );
  }
  sub_004D4E90(&a1->hypnotized[1], a1->hypnotized[1].First, a1->hypnotized[1].Last);
  v13 = std::vector<int>::size(a1->hypnotized);
  v12 = v13 - 1;
  if ( v13 > 0 )
  {
    do
    {
      combatMonster_0043E720((*(a1->hypnotized[0].First + v12) + 1316), a1);
      v14 = v12--;
    }
    while ( v14 > 0 );
  }
  sub_00448A40(a1->hypnotized);
  army::remove_binding(a1);

Может и не Гипноз, но на вектор очень сильно похоже.

В хексе смещение 0x514:

Код: Выделить всё
combatMonster_0043E720((*(a1->hypnotized[1].First + v10) + 0x514), a1);
Последний раз редактировалось AlexSpl 30 ноя 2021, 04:30, всего редактировалось 1 раз.
Вернуться к началу

offlineАватара пользователя
void_17  
имя: DM
Ветеран
Ветеран
 
Сообщения: 530
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 116 раз.

Re: База данных IDA от void17

Сообщение void_17 » 30 ноя 2021, 04:29

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

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

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5540
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2155 раз.

Re: База данных IDA от void17

Сообщение AlexSpl » 30 ноя 2021, 04:35

Может, это вектор для ауры? Обычно army::remove_aura() и army::remove_binding() в связке идут.

Моя логика такая. При уничтожении отряда убираем Гипноз (0x514) и ауру (0), при движении - только ауру (0). Вектор для ауры нужен, например, для заклинаний по площади.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5540
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2155 раз.

Re: База данных IDA от void17

Сообщение AlexSpl » 30 ноя 2021, 04:55

Вот посмотрите на это:

Код: Выделить всё
void __fastcall combatMonster_0043E720(army *a1, int a2)
{
  char *First; // esi
  int vectorSize; // eax
  int vectorSize_1; // edi
  int v5; // eax
  char *i; // edi
  char *Last; // edx
  char *j; // eax

  First = a1->aura[0].First;
  if ( First )
    vectorSize = (a1->aura[0].Last - First) >> 2;
  else
    vectorSize = 0;
  vectorSize_1 = vectorSize;
  v5 = vectorSize - 1;
  if ( vectorSize_1 )
  {
    for ( i = &First[4 * v5]; *i != a2; i -= 4 )
    {
      if ( !v5-- )
        return;
    }
    Last = a1->aura[0].Last;
    for ( j = &First[4 * v5 + 4]; j != Last; j += 4 )
      *(j - 1) = *j;
    a1->aura[0].Last = a1->aura[0].Last - 4;
  }
}

Похоже на удаление элемента вектора с конца: a1->aura[0].Last = a1->aura[0].Last - 4; У aura смещение 0. А вот это:

Код: Выделить всё
for ( j = &First[4 * v5 + 4]; j != Last; j += 4 )
      *(j - 1) = *j;

есть сдвиг элементов вектора влево на 1.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5540
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2155 раз.

Re: База данных IDA от void17

Сообщение AlexSpl » 30 ноя 2021, 05:13

Проапгрейдил своё понимание ауры :smile1:

Код: Выделить всё
if ( type == CID_UNICORN || type == CID_WAR_UNICORN )
{
   v7 = v5->activeSpellDuration[SPL_HYPNOTIZE] ? 1 - v5->side : v5->side;
   if ( v7 == this->side && (v5->creatureInfo.flags & CF_IMMOBILE) == 0 )
   {
     Last = v5->aura2[0].Last;
     First = v5->aura2[0].First;
     a4 = this;
     if ( First == Last )
      goto LABEL_16;
     do
     {
      if ( *First == this )
        break;
      ++First;
     }
     while ( First != Last );
     if ( First == Last )
LABEL_16:
      std::vector<army *>::push_back(v5->aura2, Last, 1u, &a4);
     v11 = this->aura2[1].Last;
     v10 = this->aura2[1].First;
     a4 = v5;
     if ( v10 == v11 )
      goto LABEL_21;
     do
     {
      if ( *v10 == v5 )
        break;
      ++v10;
     }
     while ( v10 != v11 );
     if ( v10 == v11 )
LABEL_21:
      std::vector<army *>::push_back(&this->aura2[1], v11, 1u, &a4);
   }
}

Так что как минимум 0x514 - это аура.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5540
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2155 раз.

Re: База данных IDA от void17

Сообщение AlexSpl » 30 ноя 2021, 05:26

Кажется, начинаю понимать связь Гипноза и ауры:

Код: Выделить всё
case SPL_HYPNOTIZE:
   First = this->unicornAura[1].First;
   if ( First )
     v3 = (this->unicornAura[1].Last - First) >> 2;
   v21 = v3;
   v22 = v3 - 1;
   if ( v21 > 0 )
   {
     do
     {
      combatMonster_0043E720((*(this->unicornAura[1].First + v22) + 0x514), this);
      v23 = v22--;
     }
     while ( v23 > 0 );
   }
   sub_00448A40(&this->unicornAura[1]);
   v25 = std::vector<int>::size(this->unicornAura);
   v24 = v25 - 1;
   if ( v25 > 0 )
   {
     do
     {
      combatMonster_0043E720((*(this->unicornAura[0].First + v24) + 0x524), this);
      v26 = v24--;
     }
     while ( v26 > 0 );
   }
   sub_00448A40(this->unicornAura);
   army::add_aura(this);
   goto LABEL_41;

*(this->unicornAura[1].First + v22) + 0x514 - это, как Вы думаете, что? :smile2:

* * *
Проще всего поставить хук и посмотреть, что произойдёт с полями 0x514+ юнита, окружённого единорогами (или наоборот) при выходе из ауры (помните, что это, вероятно, вектор, а поэтому указатели на реальные отряды нужно получать по First и Last), но лучше просто кастануть Hypnotize, чтобы затриггерить пересчёт ауры без подключения алгоритмов построения пути (для чистоты эксперимента). Если верить смещению +0x514 и сигнатуре combatMonster_0043E720(), то первым аргументом (в ecx) мы передаём army*. А эта функция уже работает с 0-м полем army. Поэтому я и сделал предположение, что поля 0x514 и 0 связаны. Я уже смотрел другой код, работающий с 0-м полем army, но, опять же, если верить типам в базе, работают с ним экземпляры класса army.

Вот вам и задачка на ум и сообразительность :smile2: Разбирать типы данных не легче, чем сверять сигнатуры.

Снижение шанса срабатывания заклинания из-за ауры единорогов идёт в самом конце метода combatManager::SpellCastWorkChance(). Только здесь рассматривается только второй из двух векторов:

Код: Выделить всё
LABEL_92:
      if ( spellTargetType <= 0 && (First = Army->unicornAura[1].First) != 0 && (Army->unicornAura[1].Last - First) >> 2 )
        result = get_spell_work_chance(spell_1, MonType, DHero, Hero) * 0.80000001;
      else
        result = get_spell_work_chance(spell_1, MonType, DHero, Hero);
      break;

Но тогда зачем нужен первый?

Здесь ещё есть код, проливающий свет на поле 0x28:

Код: Выделить всё
case SPL_CLONE:
      if ( (flags & CF_CLONE) != 0 || *&Army->some_field[8] != -1 )
      {
LABEL_91:
        result = 0.0;
      }
     

(some_field c оффсетом 20 у меня). Кого нельзя клонировать? Клонов, боевые машины, что ещё там в FizMiG'е?

Цитата:
Клонированию подлежит любое существо, в том числе призванные элементали и поднятые
Демоны, любое количество раз за бой, кроме самого Клона, существ уже имеющих Клон, существ с
защитой от магии 4 уровня или магии в целом, а также существ с Продвинутой или Экспертной
Антимагией. Медаль уязвимости позволяет клонировать существ с защитой от магии 4 уровня.

Думаю, это этот случай. Юнит имеет клон. Нужно клонировать и посмотреть, как изменится это поле. Скорее всего, оно -1 до клонирования.

Сколько у Royal Griffins реально ответок? :smile4:

Код: Выделить всё
if ( type == CID_GRIFFIN )
    this->retaliations = 2;
  if ( type == CID_ROYAL_GRIFFIN )
    this->retaliations = 5000;


По 0-му полю вопрос снимается. Это что-то, связанное с гексами (не вникал). Однозначно не вектор.

* * *
Вот. Нашёл чем озадачить Вас, void17 :smile1: Восстановите, пожалуйста, сигнатуру следующей функции из exchange_spells:

Код: Выделить всё
sub_004AFA10((int *)v61.first->field_0, (int *)v61.last->field_0, v66, 0);

и мы закроем проблему нулевого поля :smile2: Если здесь, конечно, вектор армий.

Правило #1 при работе со структурами с неизвестными полями: смотри конструкторы/деструкторы:

Код: Выделить всё
void __thiscall army::~army(army *this)
{
  int i; // eax
  int v3; // ecx
  int v4; // eax
  int *shootingDef; // ecx
  int *def; // ecx

  operator delete(this->unicornAura[1].First);
  this->unicornAura[1].First = 0;
  this->unicornAura[1].Last = 0;
  this->unicornAura[1].End = 0;
  operator delete(this->unicornAura[0].First);
  this->unicornAura[0].First = 0;
  this->unicornAura[0].Last = 0;
  this->unicornAura[0].End = 0;
  operator delete(this->dendroidBinds.First);
  this->dendroidBinds.First = 0;
  this->dendroidBinds.Last = 0;
  this->dendroidBinds.End = 0;
  operator delete(this->dendroidBinder.First);
  this->dendroidBinder.First = 0;
  this->dendroidBinder.Last = 0;
  this->dendroidBinder.End = 0;
  for ( i = *(_DWORD *)&this->f_420[44]; i; i = *(_DWORD *)&this->f_420[44] )
  {
    v3 = *(_DWORD *)&this->f_420[12] + 4;
    v4 = i - 1;
    *(_DWORD *)&this->f_420[12] = v3;
    *(_DWORD *)&this->f_420[44] = v4;
    if ( !v4 || v3 == *(_DWORD *)&this->f_420[8] )
      sub_00448D80((army *)this->f_420);
  }
  `vector destructor iterator'(&this->moveSound, 4u, 8, (void (__thiscall *)(void *))sub_0043C760);
  shootingDef = this->shootingDef;
  if ( shootingDef )
    (*(void (__thiscall **)(int *))(*shootingDef + 4))(shootingDef);
  def = this->def;
  if ( def )
    (*(void (__thiscall **)(int *))(*def + 4))(def);
}
Вернуться к началу

Пред.След.

Вернуться в Общий раздел

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [bot] и гости: 7