Подпишитесь на наш Telegram-канал, чтобы всегда быть в курсе важных обновлений! Перейти

Вопрос Script Functions

  • Автор темы Автор темы Trna
  • Дата начала Дата начала
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
16 Авг 2022
Сообщения
51
Реакции
4
Hi, Is there any tutorial related to how we can find and call script functions?
Пожалуйста, авторизуйтесь для просмотра ссылки.
For example I want to find "IsInRangeOfFountain". I searched for "IsInRangeOfFountain" in IDA. I found a bunch of things but I can't reach to the function.

I would be grateful if anyone could help me.
 
1679849412999.png

Пожалуйста, авторизуйтесь для просмотра ссылки.
1679849391582.png

Пожалуйста, авторизуйтесь для просмотра ссылки.
1679849466467.png

vBAWGQs.png

kAR1dtt.png

rEo4zTj.png

Код:
Expand Collapse Copy
function IsInRangeOfFountain(e_idx) //pseudo code
{
    ent = GetEntity(e_idx)
    ent_team = ent?.IsNpc()?.GetTeamNum()
    ent_pos = ent?.IsNpc()?.GetPos()
    fountain = GetEntity(Gamerules.TeamFountains[ent_team])
    return fountain?.GetPos().distance(ent_pos) <= 1250.0
}
 
Последнее редактирование:
There are also huge functions with array-like arrangements of RegisterJSMethod calls
xrefs of most JS functions lead to a lea rcx instruction
This is the "array":
Screenshot_585.png

Function pointers are above xrefs
Best reversed in IDA
Screenshot_587.png

And then the distance checking logic goes as Liberalist explained
Screenshot_586.png
 
thanks. I find out that there is a dylib file.
from what you said I also found the actual function and how it works:

C++:
Expand Collapse Copy
__int64 __fastcall C_DOTA_BaseNPC::IsInRangeOfFountain(C_DOTA_BaseNPC *this)
{
  return C_DOTAGamerules::IsInRangeOfFountain((C_DOTAGamerules *)g_pGameRules, this);
}
sig if anybody needs it: "48 8B D1 48 8B 0D ? ? ? ? E9 ? ? ? ? CC 32 C0"

It's outdated a bit, but still helpful

C++:
Expand Collapse Copy
bool __fastcall C_DOTAGamerules::IsInRangeOfFountain(C_DOTAGamerules *this, C_DOTA_BaseNPC *a2)
{
  unsigned __int64v2; // rbx
  const __m128i *AbsOrigin; // r14
  unsigned int v5; // eax
  __int64v6; // rcx
  __int64v7; // rsi
  C_BaseEntity **v8; // rdx
  C_BaseEntity *v9; // rdi
  __m128iv10; // xmm0
  floatv11; // xmm1_4

  v2 = *((unsigned __int8 *)a2 + 667);
  AbsOrigin = (const __m128i *)C_BaseEntity::GetAbsOrigin(a2);
  if ( v2 > 0xD )
    return 0;
  v5 = *((_DWORD *)this + v2 + 359);
  if ( v5 > 0xFFFFFFFD )
    return 0;
  v6 = *(_QWORD *)(CEntityHandle::gm_pEntityList + 8LL * ((v5 >> 9) & 0x3F) + 8);
  if ( !v6 )
    return 0;
  v7 = 120LL * (v5 & 0x1FF);
  v8 = (C_BaseEntity **)(v7 + v6);
  if ( !(v7 + v6) )
    return 0;
  if ( *(_DWORD *)(v6 + v7 + 16) != v5 )
    return 0;
  v9 = *v8;
  if ( !*v8 )
    return 0;
  if ( !*((_BYTE *)v9 + 1044) )
    return 0;
  v10 = (__m128i)_mm_sub_ps(
                   (__m128)_mm_loadl_epi64(AbsOrigin),
                   (__m128)_mm_loadl_epi64((const __m128i *)C_BaseEntity::GetAbsOrigin(v9)));
  v11 = *(float *)_mm_shuffle_epi32(v10, 1).i32;
  return fsqrt((float)(v11 * v11) + (float)(*(float *)v10.i32 * *(float *)v10.i32)) < 1150.0;
}
 
Последнее редактирование:
thanks. I find out that there is a dylib file.
from what you said I also found the actual function and how it works:

C++:
Expand Collapse Copy
__int64 __fastcall C_DOTA_BaseNPC::IsInRangeOfFountain(C_DOTA_BaseNPC *this)
{
  return C_DOTAGamerules::IsInRangeOfFountain((C_DOTAGamerules *)g_pGameRules, this);
}

It's outdated a bit, but still helpful


C++:
Expand Collapse Copy
bool __fastcall C_DOTAGamerules::IsInRangeOfFountain(C_DOTAGamerules *this, C_DOTA_BaseNPC *a2)
{
  unsigned __int64v2; // rbx
  const __m128i *AbsOrigin; // r14
  unsigned int v5; // eax
  __int64v6; // rcx
  __int64v7; // rsi
  C_BaseEntity **v8; // rdx
  C_BaseEntity *v9; // rdi
  __m128iv10; // xmm0
  floatv11; // xmm1_4

  v2 = *((unsigned __int8 *)a2 + 667);
  AbsOrigin = (const __m128i *)C_BaseEntity::GetAbsOrigin(a2);
  if ( v2 > 0xD )
    return 0;
  v5 = *((_DWORD *)this + v2 + 359);
  if ( v5 > 0xFFFFFFFD )
    return 0;
  v6 = *(_QWORD *)(CEntityHandle::gm_pEntityList + 8LL * ((v5 >> 9) & 0x3F) + 8);
  if ( !v6 )
    return 0;
  v7 = 120LL * (v5 & 0x1FF);
  v8 = (C_BaseEntity **)(v7 + v6);
  if ( !(v7 + v6) )
    return 0;
  if ( *(_DWORD *)(v6 + v7 + 16) != v5 )
    return 0;
  v9 = *v8;
  if ( !*v8 )
    return 0;
  if ( !*((_BYTE *)v9 + 1044) )
    return 0;
  v10 = (__m128i)_mm_sub_ps(
                   (__m128)_mm_loadl_epi64(AbsOrigin),
                   (__m128)_mm_loadl_epi64((const __m128i *)C_BaseEntity::GetAbsOrigin(v9)));
  v11 = *(float *)_mm_shuffle_epi32(v10, 1).i32;
  return fsqrt((float)(v11 * v11) + (float)(*(float *)v10.i32 * *(float *)v10.i32)) < 1150.0;
}
Good thing such functions don't change a lot
They can also call virtual functions sometimes, like GetEffectiveCastRange for C_DOTA_BaseAbility, and that's even better because you don't need to reverse the actual function to save time on sigscanning
 
Назад
Сверху Снизу