Гайд GetBoneIDByName

Забаненный
Статус
Оффлайн
Регистрация
16 Май 2017
Сообщения
40
Реакции[?]
4
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Решил выложить мануальчик от себя.
Данный метод был взят очень давно на UKC, теперь выложу его на Русском языке.

Cреда программирования будет у нас c++

дня начала определим внутриигровой метод типа int под название LookUpBone в виде спецификатора typedef.
Код:
typedef int(__thiscall* pLookupBone)(Entity* pEntity, const char* boneName); //Entity - класс игрока, у себя я назвал его именно так, у вас не знаю как оно, поправите это сами

Далее найдём в памяти игры адрес этого метода, он находится в client.dll
Идём в IDA, открываем вышеупомянутую dll... После того как IDA её открыла, во вкладке IDA View-a, жмём сочетании клавиш Shift + F12, нас перекидывает на вкладку со стоками... по нажатию сочетания клавиш Ctrl + F и в поисковой строке пишем "Bip01_Head", после этого дабл клик по найденной строке и видим следующее

Нам нужно это:​
Код:
DATA XREF: sub_101C9820+63o
Дабл клик по sub_101C9820
и видим следующее:​

Кликаем по "Bip01_Head" и жмём F5

и мы внутри нужного нам метода​
Код:
int __thiscall sub_101C9820(int this, int a2)
{
  int v2; // esi@1
  int v3; // ecx@4
  int v4; // ebx@6
  int v5; // eax@9
  int result; // eax@9
  int v7; // eax@11
  int v8; // eax@13

  v2 = this;
  if ( !*(_DWORD *)(this + 10556) && (*(int (__thiscall **)(int))(*(_DWORD *)(this + 4) + 32))(this + 4) )
    sub_101C9110(v2);
  v3 = *(_DWORD *)(v2 + 10556);
  if ( v3 && *(_DWORD *)v3 )
  {
    v4 = sub_106240B0(v3, a2);
    if ( v4 == -1 )
    {
      if ( sub_10720130(a2, "weapon_bone") )
        goto LABEL_18;
      if ( sub_10720130(a2, "Bip01_Head") )
      {
        v5 = sub_10195C20(v2);
        return sub_106240B0(v5, "head_0");
      }
      if ( sub_10720130(a2, "L_Hand") )
      {
        v7 = sub_10195C20(v2);
        return sub_106240B0(v7, "hand_L");
      }
      if ( sub_10720130(a2, "R_Hand") )
      {
LABEL_18:
        v8 = sub_10195C20(v2);
        v4 = sub_106240B0(v8, "hand_R");
      }
    }
    result = v4;
  }
  else
  {
    result = -1;
  }
  return result;
}
Имя метода в моём случае это "sub_101C9820" соответственно адрес метода это 101C9820, теперь нам нужен калькулятор, тк необходимо из полученного адреса вычесть адрес начала dll что бы получить офсет этого метода в памяти относительно client.dll
Переходим во вкладку IDA View-a и в самое начало dll​

И теперь из нашего адреса метода вычитаем адрес начала dll, показывать как на калькуляторе считать не буду, это и так все знают, у меня получилось 1C9820.

Теперь переходим обратно в студию и продолжаем писать.

Опишем метод GetBoneIDByName.​
Код:
int GetBoneIDByName(Entity* pEentity, const char* boneName)
{
      int bone = -1;
      return bone;
}
В методе присвоим нашему pLookupBone адрес найденного метода.​
Код:
pLookupBone LookupBone = (pLookupBone)((DWORD)GetModuleHandle("client.dll") + 0x1C9820); //адрес dll + полученный офсет
И вызовем метод:​
Код:
LookupBone(pEentity, boneName);
И вот что получилось у нас в конечном результате:​
Код:
int GetBoneIDByName(Entity* pEentity, const char* boneName)
{
                pLookupBone LookupBone = (pLookupBone)((DWORD)GetModuleHandle("client.dll") + 0x1C9820);
      int bone = -1;
      bone = LookupBone(pEentity, boneName);
      return bone;
}
Теперь при вызове метода мы подаём первым аргументом экземпляр класса нужного игрока, а вторым подаём имя кости
тк метод у нас типа int то мы получим ID кости соответствующий этому имени.

Теперь мы можем рисовать скелеты и они будут правильно рендерится на разных моделях (их не будет косоёбить)

Ах да, чуть не забыл про список имён костей.​
Код:
char* boneNames[87] = {
   "pelvis",
   "spine_0",
   "spine_1",
   "spine_2",
   "spine_3",
   "neck_0",
   "head_0",
   "head_0_TWIST",
   "clavicle_L",
   "arm_upper_L",
   "arm_lower_L",
   "hand_L",
   "finger_middle_meta_L",
   "finger_middle_0_L",
   "finger_middle_1_L",
   "finger_middle_2_L",
   "finger_pinky_meta_L",
   "finger_pinky_0_L",
   "finger_pinky_1_L",
   "finger_pinky_2_L",
   "finger_index_meta_L",
   "finger_index_0_L",
   "finger_index_1_L",
   "finger_index_2_L",
   "finger_thumb_0_L",
   "finger_thumb_1_L",
   "finger_thumb_2_L",
   "finger_ring_meta_L",
   "finger_ring_0_L",
   "finger_ring_1_L",
   "finger_ring_2_L",
   "weapon_hand_L",
   "arm_lower_L_TWIST",
   "arm_lower_L_TWIST1",
   "arm_upper_L_TWIST",
   "arm_upper_L_TWIST1",
   "scapula_L",
   "clavicle_R",
   "arm_upper_R",
   "arm_lower_R",
   "hand_R",
   "finger_middle_meta_R",
   "finger_middle_0_R",
   "finger_middle_1_R",
   "finger_middle_2_R",
   "finger_pinky_meta_R",
   "finger_pinky_0_R",
   "finger_pinky_1_R",
   "finger_pinky_2_R",
   "finger_index_meta_R",
   "finger_index_0_R",
   "finger_index_1_R",
   "finger_index_2_R",
   "finger_thumb_0_R",
   "finger_thumb_1_R",
   "finger_thumb_2_R",
   "finger_ring_meta_R",
   "finger_ring_0_R",
   "finger_ring_1_R",
   "finger_ring_2_R",
   "weapon_hand_R",
   "arm_lower_R_TWIST",
   "arm_lower_R_TWIST1",
   "arm_upper_R_TWIST",
   "arm_upper_R_TWIST1",
   "pectAim_L",
   "pectTrans_L",
   "leg_upper_L",
   "leg_lower_L",
   "ankle_L",
   "ball_L",
   "leg_upper_L_TWIST",
   "leg_upper_L_TWIST1",
   "leg_upper_R",
   "leg_lower_R",
   "ankle_R",
   "ball_R",
   "leg_upper_R_TWIST",
   "leg_upper_R_TWIST1",
   "ValveBiped.weapon_bone",
   "lh_ik_driver",
   "lean_root",
   "lfoot_lock",
   "rfoot_lock",
   "primary_jiggle_jnt",
   "primary_smg_jiggle_jnt",
   "Bip01"
};
 
Эксперт
Статус
Оффлайн
Регистрация
12 Июн 2014
Сообщения
991
Реакции[?]
1,209
Поинты[?]
3K
Код:
typedef int(__thiscall* pLookupBone)(Entity*, const char*);
/*static*/ pLookupBone LookupBone = nullptr;

 
int GetBoneIDByName(Entity* pEentity, const char* boneName)
{
    if(pLookupBone == nullptr)
      (pLookupBone)((DWORD)GetModuleHandle("client.dll") + 0x1C9820);
 
      return LookupBone(pEentity, boneName);
}
 
Забаненный
Статус
Оффлайн
Регистрация
27 Сен 2018
Сообщения
45
Реакции[?]
0
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
No, just no, pasters
 
Сверху Снизу