Вопрос Как теперь получают EntityList?

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
24 Сен 2022
Сообщения
11
Реакции
1
Здравствуйте, я тупой школьник, который захотел научиться делать читы для доты по гайдам @Liberalist . У меня возникла проблема с получением EntityList, так как за последние 5 лет в доте изменились функции, используемые в гайде, а конкретно функция ent_find:
ent_find:
Expand Collapse Copy
__int64 __fastcall sub_1804EE1F0(__int64 a1, __int64 a2)
{
  int v4; // edi
  int v5; // eax
  int v6; // ebx
  __int64 v7; // rdi
  const char *v8; // rdx
  __int64 i; // rbx
  __int64 v10; // rax
  const char *v11; // r13
  __int64 v12; // rbp
  const char *v13; // r12
  int v14; // r14d
  const char *v15; // rcx
  const char *v16; // rax
  int v17; // eax
  const char *v18; // rcx
  __int64 v19; // rax
  bool v20; // bl
  const char *v21; // rsi
  const char *v22; // rax
  bool v23; // di
  const char *v24; // rax
  bool v25; // cl
  bool v26; // al
  bool v27; // cl
  bool v28; // al
  __int64 v29; // rcx
  void *v30; // r8
  void *v31; // rdx
  _BYTE v32[24]; // [rsp+20h] [rbp-58h] BYREF
  _UNKNOWN **v33; // [rsp+38h] [rbp-40h] BYREF
  int v34; // [rsp+88h] [rbp+10h]
  unsigned int v35; // [rsp+90h] [rbp+18h] BYREF
  __int64 v36; // [rsp+98h] [rbp+20h]

  if ( *(int *)(a2 + 1080) < 2 )
    return Msg("Format: ent_find substring [substring...] [-exclude_substring...] \n");
  v4 = 0;
  v34 = 0;
  Msg("Searching for entities with class/target name containing substrings: ");
  v5 = *(_DWORD *)(a2 + 1080);
  v6 = 1;
  if ( v5 > 1 )
  {
    v7 = 1;
    do
    {
      if ( v7 < 0 || v6 >= v5 )
        v8 = (const char *)&unk_1831462FA;
      else
        v8 = *(const char **)(*(_QWORD *)(a2 + 1088) + 8 * v7);
      Msg("\"%s\"", v8);
      if ( v6 != *(_DWORD *)(a2 + 1080) - 1 )
        Msg(", ");
      v5 = *(_DWORD *)(a2 + 1080);
      ++v6;
      ++v7;
    }
    while ( v6 < v5 );
    v4 = 0;
  }
  Msg("\n");
  sub_182BFB710(v32, &v33, 0);
  v33 = &off_183160F88;
  v36 = sub_182C063D0(v32);
  for ( i = v36; v36; i = v36 )
  {
    v10 = *(_QWORD *)(i + 16);
    v11 = (const char *)&unk_1831462FA;
    v12 = 1;
    v13 = (const char *)&unk_1831462FA;
    v14 = 1;
    v15 = *(const char **)(v10 + 32);
    v16 = *(const char **)(v10 + 24);
    if ( v15 )
      v11 = v15;
    if ( v16 )
      v13 = v16;
    v17 = *(_DWORD *)(a2 + 1080);
    if ( v17 <= 1 )
    {
LABEL_48:
      v34 = ++v4;
      sub_182C207E0(i, &v35);
      v29 = *(_QWORD *)(i + 16);
      v30 = &unk_1831462FA;
      v31 = &unk_1831462FA;
      if ( *(_QWORD *)(v29 + 24) )
        v30 = *(void **)(v29 + 24);
      if ( *(_QWORD *)(v29 + 32) )
        v31 = *(void **)(v29 + 32);
      Msg("   '%s' : '%s' (entindex %d) \n", v31, v30, v35);
    }
    else
    {
      while ( 1 )
      {
        if ( v12 < 0 || v14 >= v17 )
          v18 = (const char *)&unk_1831462FA;
        else
          v18 = *(const char **)(*(_QWORD *)(a2 + 1088) + 8 * v12);
        v19 = -1;
        do
          ++v19;
        while ( v18[v19] );
        v20 = (int)v19 > 0 && *v18 == 45;
        v21 = v18 + 1;
        if ( !v20 )
          v21 = v18;
        if ( v11 && *v11 )
        {
          v22 = V_stristr_fast(v11, v21);
          if ( v20 )
            v23 = v22 == 0;
          else
            v23 = v22 != 0;
        }
        else
        {
          v23 = 0;
        }
        if ( v13 && *v13 )
        {
          v24 = V_stristr_fast(v13, v21);
          if ( v20 )
            v25 = v24 == 0;
          else
            v25 = v24 != 0;
        }
        else
        {
          v25 = 0;
        }
        v26 = v25;
        v27 = v23 && v25;
        v28 = v23 || v26;
        if ( !v20 )
          v27 = v28;
        if ( !v27 )
          break;
        v17 = *(_DWORD *)(a2 + 1080);
        ++v14;
        ++v12;
        if ( v14 >= v17 )
        {
          i = v36;
          v4 = v34;
          goto LABEL_48;
        }
      }
      v4 = v34;
    }
    v36 = sub_182C0B0E0(v32);
  }
  return Msg("Found %d matches.\n", v4);
}
Как я понял (с помощью chatGPT), теперь вместо получения первой и последующих сущностей через CGameEntitySystem::NextEnt, для получения первой сущности используется одна функция (sub_182C063D0), а для следующих - другая (sub_182C0B0E0). Но вся проблема заключается вот в этом говне - sub_182BFB710(v32, &v33, 0);. Я не понимаю, что это за хуйня и что в нее надо передавать, а без нее нельзя будет получить ни первую, ни, соответственно, последующие сущности 😥. Может быть появились новые способы получения энтити листа? На UnknownCheats говорят, что первую сущность можно получить через CGameEntitySystem + 0x210, только я не знаю, как получить адрес CGameEntitySystem. Раньше как я понял это делали так:
auto GameResourceServiceClient =
((uintptr_t(*)(const char*, void*))GetProcAddress(GetModuleHandleA("engine2.dll"),
"CreateInterface"))("GameResourceServiceClientV001", nullptr);
CGameEntitySystem* gameEntitySystem = *(CGameEntitySystem**)((uintptr_t)GameResourceServiceClient + 0x58);
но теперь этот метод не работает.
 
Последнее редактирование:
в душе не ебу что ты написал, однако список сущностей который иногда еще именуют entity list либо item list который в основном находят либо по классам с дампера, либо с помощью отладчика по адресу на котором лежит сущность, находят что-то типа ofe перебора сущностей или цепочку по которой находится так нужный перебор сущностей
 
ну ты правильно понял(там две практически одинаковые функции для получения первой и последующей сущностей)
параметрами там какието структуры... ну и хуй с ними. можешь по оффсету просто брать первую айдентити и не париться с этими функциями
оффсет в функции подсмотри просто и сам делай то же самое что и функция делает, просто руками, там пара строк кода всего лишь полезных в функции этой - получение первой айдентити(от нее потом дальше будут все остальные браться поочерёдно)(CGameEntitySystem @ 0x210) если она не передана в функцию, или если передана то берется у переданной айдентити m_pNext(CEntityIdentity @ 0x60) (ну и в итоге возвращает ентити из айдентити(CEntityIdentity @ 0x0)).
ну и естественно сама CGameEntitySystem тебе ещё понадобится(откуда то же надо сущности брать, верно?), на неё миллион хрефов, он есть даже и в самих этих функциях(либо бери из GameResourceServiceClientV001)
(бтв такая итерация мусор всякий клиентсайд чисто визуальный типо деревьев тоже выдаёт, можно такое скипать там индексы у мусора будут >3fff т.е. MSB индекса в 1(индекс 15-битный), т.е. можно сказать что индекс есть юнион "полезного" индекса(14 битов) и бита который отвечает за клиентсайдность)
C++:
Expand Collapse Copy
#include <Windows.h>

#include <cstdint>
#include <cstddef>
#include <utility>
#include <format>

struct NormalClass
{
    template<class T>
    decltype(auto) Member(this auto&& self, std::ptrdiff_t offset)
    {
        return std::forward_like<decltype(self)&>
            (*reinterpret_cast<T*>(reinterpret_cast<std::uintptr_t>(&self) + offset));
    }
};


struct C_BaseEntity {};

template<class T>
struct CHandle
{
    int impl = -1;
    unsigned int index() const
    {
        return static_cast<unsigned int>(impl) & 0x7fff;
    }
    bool is_valid() const
    {
        return impl != -1
            && index() != 0x7fff;
    }
};

//client.dll/classes/CEntityIdentity
struct CEntityIdentity : NormalClass
{
    decltype(auto) m_pEntity(this auto&& self)
    {
        //undocumented
        return self.template Member<C_BaseEntity*>(0x0);
    }
    decltype(auto) m_hEntityHandle(this auto&& self)
    {
        //undocumented
        return self.template Member<CHandle<C_BaseEntity>>(0x10);
    }
    decltype(auto) m_pNext(this auto&& self)
    {
        //CEntityIdentity* m_pNext(offset 0x60, size 0x8, align 0x8)
        return self.template Member<CEntityIdentity*>(0x60);
    }
    decltype(auto) m_name(this auto&& self)
    {
        //CUtlSymbolLarge m_name(offset 0x18, size 0x8, align 0x8)
        return self.template Member<char const*>(0x18);
    }
    decltype(auto) m_designerName(this auto&& self)
    {
        //CUtlSymbolLarge m_designerName(offset 0x20, size 0x8, align 0x8)
        return self.template Member<char const*>(0x20);
    }
};

struct CGameEntitySystem : NormalClass
{
    decltype(auto) getFirstIdentity()
    {
        /*
        cf. cl_ent_find - xref "Format: ent_find substring [substring...] [-exclude_substring...] \n"

        $ ==>     | 41:57                      | push r15                                    | cl_ent_find
        $+2       | 48:83EC 70                 | sub rsp,70
        $+6       | 83BA 38040000 02           | cmp dword ptr ds:[rdx+438],2
        $+D       | 4C:8BFA                    | mov r15,rdx
        $+10      | 7D 14                      | jge client.7FFBD04BE216
        $+12      | 48:8D0D 8726C802           | lea rcx,qword ptr ds:[7FFBD3140890]         | 00007FFBD3140890:"Format: ent_find substring [substring...] [-exclude_substring...] \n"
        $+19      | FF15 F1E2C102              | call qword ptr ds:[<&Msg>]
        $+1F      | 48:83C4 70                 | add rsp,70
        $+23      | 41:5F                      | pop r15
        $+25      | C3                         | ret
        $+26      | 48:899C24 80000000         | mov qword ptr ss:[rsp+80],rbx
        $+2E      | 48:8D0D BB26C802           | lea rcx,qword ptr ds:[7FFBD31408E0]         | 00007FFBD31408E0:"Searching for entities with class/target name containing substrings: "
        $+35      | 48:897C24 58               | mov qword ptr ss:[rsp+58],rdi
        $+3A      | 33FF                       | xor edi,edi
        $+3C      | 89BC24 88000000            | mov dword ptr ss:[rsp+88],edi
        $+43      | FF15 C7E2C102              | call qword ptr ds:[<&Msg>]
        $+49      | 41:8B87 38040000           | mov eax,dword ptr ds:[r15+438]
        $+50      | BB 01000000                | mov ebx,1
        $+55      | 3BC3                       | cmp eax,ebx
        $+57      | 7E 5D                      | jle client.7FFBD04BE2A6
        $+59      | 8BFB                       | mov edi,ebx
        $+5B      | 0F1F4400 00                | nop dword ptr ds:[rax+rax],eax
        $+60      | 48:85FF                    | test rdi,rdi
        $+63      | 78 11                      | js client.7FFBD04BE266
        $+65      | 3BD8                       | cmp ebx,eax
        $+67      | 7D 0D                      | jge client.7FFBD04BE266
        $+69      | 49:8B87 40040000           | mov rax,qword ptr ds:[r15+440]
        $+70      | 48:8B14F8                  | mov rdx,qword ptr ds:[rax+rdi*8]
        $+74      | EB 07                      | jmp client.7FFBD04BE26D
        $+76      | 48:8D15 8D80C502           | lea rdx,qword ptr ds:[7FFBD31162FA]
        $+7D      | 48:8D0D B426C802           | lea rcx,qword ptr ds:[7FFBD3140928]         | 00007FFBD3140928:"\"%s\""
        $+84      | FF15 86E2C102              | call qword ptr ds:[<&Msg>]
        $+8A      | 41:8B87 38040000           | mov eax,dword ptr ds:[r15+438]
        $+91      | FFC8                       | dec eax
        $+93      | 3BD8                       | cmp ebx,eax
        $+95      | 74 0D                      | je client.7FFBD04BE294
        $+97      | 48:8D0D 1EFFC702           | lea rcx,qword ptr ds:[7FFBD313E1AC]         | 00007FFBD313E1AC:", "
        $+9E      | FF15 6CE2C102              | call qword ptr ds:[<&Msg>]
        $+A4      | 41:8B87 38040000           | mov eax,dword ptr ds:[r15+438]
        $+AB      | FFC3                       | inc ebx
        $+AD      | 48:FFC7                    | inc rdi
        $+B0      | 3BD8                       | cmp ebx,eax
        $+B2      | 7C AC                      | jl client.7FFBD04BE250
        $+B4      | 33FF                       | xor edi,edi
        $+B6      | 48:8D0D 4B80C502           | lea rcx,qword ptr ds:[7FFBD31162F8]
        $+BD      | FF15 4DE2C102              | call qword ptr ds:[<&Msg>]
        $+C3      | 45:33C0                    | xor r8d,r8d
        $+C6      | 48:8D5424 38               | lea rdx,qword ptr ss:[rsp+38]
        $+CB      | 48:8D4C24 20               | lea rcx,qword ptr ss:[rsp+20]
        $+D0      | E8 ABD47002                | call client.7FFBD2BCB770
        $+D5      | 48:8D05 BC2CC702           | lea rax,qword ptr ds:[7FFBD3130F88]
        $+DC      | 48:8D4C24 20               | lea rcx,qword ptr ss:[rsp+20]
        $+E1      | 48:894424 38               | mov qword ptr ss:[rsp+38],rax
        $+E6      | E8 55817102                | call client.7FFBD2BD6430                    | <--- GetFirstEnt
        $+EB      | 48:898424 98000000         | mov qword ptr ss:[rsp+98],rax
        $+F3      | 48:8BD8                    | mov rbx,rax
        $+F6      | 48:85C0                    | test rax,rax
        $+F9      | 0F84 DA010000              | je client.7FFBD04BE4C9
        $+FF      | 48:896C24 68               | mov qword ptr ss:[rsp+68],rbp
        $+104     | 48:897424 60               | mov qword ptr ss:[rsp+60],rsi



        $ ==>     | 40:53                      | push rbx                                    | GetFirstEnt
        $+2       | 48:83EC 20                 | sub rsp,20
        $+6       | 8079 11 00                 | cmp byte ptr ds:[rcx+11],0
        $+A       | 48:8BD9                    | mov rbx,rcx
        $+D       | 75 07                      | jne client.7FFBD2BD6446
        $+F       | 48:C701 00000000           | mov qword ptr ds:[rcx],0
        $+16      | C641 11 00                 | mov byte ptr ds:[rcx+11],0
        $+1A      | 48:8B05 5FCE8E02           | mov rax,qword ptr ds:[7FFBD54C32B0]
        $+21      | 48:85C0                    | test rax,rax
        $+24      | 0F84 8B000000              | je client.7FFBD2BD64E5
        $+2A      | 48:8B09                    | mov rcx,qword ptr ds:[rcx]
        $+2D      | 48:85C9                    | test rcx,rcx
        $+30      | 74 06                      | je client.7FFBD2BD6468
        $+32      | 48:8B41 60                 | mov rax,qword ptr ds:[rcx+60]
        $+36      | EB 16                      | jmp client.7FFBD2BD647E
        $+38      | 807B 10 00                 | cmp byte ptr ds:[rbx+10],0
        $+3C      | 75 09                      | jne client.7FFBD2BD6477
        $+3E      | 48:8B80 10020000           | mov rax,qword ptr ds:[rax+210]              | <--- offset
        $+45      | EB 07                      | jmp client.7FFBD2BD647E
        $+47      | 48:8B80 30020000           | mov rax,qword ptr ds:[rax+230]
        $+4E      | 48:8903                    | mov qword ptr ds:[rbx],rax
        $+51      | 48:85C0                    | test rax,rax
        $+54      | 74 4E                      | je client.7FFBD2BD64D4
        $+56      | 48:8B4B 08                 | mov rcx,qword ptr ds:[rbx+8]
        $+5A      | 48:85C9                    | test rcx,rcx
        $+5D      | 74 20                      | je client.7FFBD2BD64AF
        $+5F      | 8B50 30                    | mov edx,dword ptr ds:[rax+30]
        $+62      | C1EA 09                    | shr edx,9
        $+65      | F6C2 01                    | test dl,1
        $+68      | 75 2E                      | jne client.7FFBD2BD64C8
        $+6A      | 48:8B11                    | mov rdx,qword ptr ds:[rcx]
        $+6D      | 4C:8B02                    | mov r8,qword ptr ds:[rdx]
        $+70      | 48:8B10                    | mov rdx,qword ptr ds:[rax]
        $+73      | 41:FFD0                    | call r8
        $+76      | 84C0                       | test al,al
        $+78      | 75 05                      | jne client.7FFBD2BD64AF
        $+7A      | 48:8B03                    | mov rax,qword ptr ds:[rbx]
        $+7D      | EB 19                      | jmp client.7FFBD2BD64C8
        $+7F      | 44:8B43 14                 | mov r8d,dword ptr ds:[rbx+14]
        $+83      | 45:85C0                    | test r8d,r8d
        $+86      | 74 1C                      | je client.7FFBD2BD64D4
        $+88      | 48:8B03                    | mov rax,qword ptr ds:[rbx]
        $+8B      | 48:8B08                    | mov rcx,qword ptr ds:[rax]
        $+8E      | 48:8B51 10                 | mov rdx,qword ptr ds:[rcx+10]
        $+92      | 44:3942 38                 | cmp dword ptr ds:[rdx+38],r8d
        $+96      | 74 0C                      | je client.7FFBD2BD64D4
        $+98      | 48:8B40 60                 | mov rax,qword ptr ds:[rax+60]
        $+9C      | 48:8903                    | mov qword ptr ds:[rbx],rax
        $+9F      | 48:85C0                    | test rax,rax
        $+A2      | 75 B2                      | jne client.7FFBD2BD6486
        $+A4      | 48:8B03                    | mov rax,qword ptr ds:[rbx]
        $+A7      | 48:85C0                    | test rax,rax
        $+AA      | 74 09                      | je client.7FFBD2BD64E5
        $+AC      | 48:8B00                    | mov rax,qword ptr ds:[rax]
        $+AF      | 48:83C4 20                 | add rsp,20
        $+B3      | 5B                         | pop rbx
        $+B4      | C3                         | ret
        $+B5      | 33C0                       | xor eax,eax
        $+B7      | 48:83C4 20                 | add rsp,20
        $+BB      | 5B                         | pop rbx
        $+BC      | C3                         | ret
        */
        return Member<CEntityIdentity*>(0x210);
    }
};

std::string_view make_strview(char const* e)
{
    if (e)
    {
        return std::string_view{ e };
    }
    return std::string_view{};
}

BOOL APIENTRY DllMain(HMODULE, DWORD ul_reason_for_call, LPVOID)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        auto const engine2 = GetModuleHandleA("engine2.dll");
        if (engine2)
        {
            auto const create_interface_fn = GetProcAddress(engine2, "CreateInterface");
            int status = 0;
            auto const GRSC = (reinterpret_cast<void* (*)(const char*, int*)>(create_interface_fn))
                ("GameResourceServiceClientV001", &status);
            if (status == 0 && GRSC)
            {
                const auto entity_system = static_cast<NormalClass*>(GRSC)
                    ->Member<CGameEntitySystem*>(0x58);
                if (entity_system)
                {
                    for (CEntityIdentity const* identity = entity_system->getFirstIdentity();
                        identity;
                        identity = identity->m_pNext())
                    {
                        auto const* const entity = identity->m_pEntity();
                        if (entity)
                        {
                            auto const handle = identity->m_hEntityHandle();
                            if (handle.is_valid())
                            {
                                auto const index = handle.index();
                                if (index < 0x4000) /* networkable ents(not clientside) */
                                {
                                    OutputDebugStringA(std::format
                                            (R"(ent @ {} index {} name "{}" designerName "{}")",
                                            (void*)identity->m_pEntity(), index,
                                            make_strview(identity->m_name()),
                                            make_strview(identity->m_designerName()))
                                        .data());
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                OutputDebugStringA(std::format("CreateInterface GameResourceServiceClientV001 failure: {}", reinterpret_cast<void*>(status)).data());
            }
        }
        else
        {
            OutputDebugStringA("no engine2.dll");
        }
    }
    return TRUE;
}
1754686640352.png
 
Последнее редактирование:
Премногоблагодарен! Наконец-то я своими глазами увидел этот грёбаный EntityList
1754748279784.png

и теперь могу дальше продвигаться по твоим гайдам :pepehzo: Еще раз спасибо!
ну ты правильно понял(там две практически одинаковые функции для получения первой и последующей сущностей)
параметрами там какието структуры... ну и хуй с ними. можешь по оффсету просто брать первую айдентити и не париться с этими функциями
оффсет в функции подсмотри просто и сам делай то же самое что и функция делает, просто руками, там пара строк кода всего лишь полезных в функции этой - получение первой айдентити(от нее потом дальше будут все остальные браться поочерёдно)(CGameEntitySystem @ 0x210) если она не передана в функцию, или если передана то берется у переданной айдентити m_pNext(CEntityIdentity @ 0x60) (ну и в итоге возвращает ентити из айдентити(CEntityIdentity @ 0x0)).
ну и естественно сама CGameEntitySystem тебе ещё понадобится(откуда то же надо сущности брать, верно?), на неё миллион хрефов, он есть даже и в самих этих функциях(либо бери из GameResourceServiceClientV001)
(бтв такая итерация мусор всякий клиентсайд чисто визуальный типо деревьев тоже выдаёт, можно такое скипать там индексы у мусора будут >3fff т.е. MSB индекса в 1(индекс 15-битный), т.е. можно сказать что индекс есть юнион "полезного" индекса(14 битов) и бита который отвечает за клиентсайдность)
C++:
Expand Collapse Copy
#include <Windows.h>

#include <cstdint>
#include <cstddef>
#include <utility>
#include <format>

struct NormalClass
{
    template<class T>
    decltype(auto) Member(this auto&& self, std::ptrdiff_t offset)
    {
        return std::forward_like<decltype(self)&>
            (*reinterpret_cast<T*>(reinterpret_cast<std::uintptr_t>(&self) + offset));
    }
};


struct C_BaseEntity {};

template<class T>
struct CHandle
{
    int impl = -1;
    unsigned int index() const
    {
        return static_cast<unsigned int>(impl) & 0x7fff;
    }
    bool is_valid() const
    {
        return impl != -1
            && index() != 0x7fff;
    }
};

//client.dll/classes/CEntityIdentity
struct CEntityIdentity : NormalClass
{
    decltype(auto) m_pEntity(this auto&& self)
    {
        //undocumented
        return self.template Member<C_BaseEntity*>(0x0);
    }
    decltype(auto) m_hEntityHandle(this auto&& self)
    {
        //undocumented
        return self.template Member<CHandle<C_BaseEntity>>(0x10);
    }
    decltype(auto) m_pNext(this auto&& self)
    {
        //CEntityIdentity* m_pNext(offset 0x60, size 0x8, align 0x8)
        return self.template Member<CEntityIdentity*>(0x60);
    }
    decltype(auto) m_name(this auto&& self)
    {
        //CUtlSymbolLarge m_name(offset 0x18, size 0x8, align 0x8)
        return self.template Member<char const*>(0x18);
    }
    decltype(auto) m_designerName(this auto&& self)
    {
        //CUtlSymbolLarge m_designerName(offset 0x20, size 0x8, align 0x8)
        return self.template Member<char const*>(0x20);
    }
};

struct CGameEntitySystem : NormalClass
{
    decltype(auto) getFirstIdentity()
    {
        /*
        cf. cl_ent_find - xref "Format: ent_find substring [substring...] [-exclude_substring...] \n"

        $ ==>     | 41:57                      | push r15                                    | cl_ent_find
        $+2       | 48:83EC 70                 | sub rsp,70
        $+6       | 83BA 38040000 02           | cmp dword ptr ds:[rdx+438],2
        $+D       | 4C:8BFA                    | mov r15,rdx
        $+10      | 7D 14                      | jge client.7FFBD04BE216
        $+12      | 48:8D0D 8726C802           | lea rcx,qword ptr ds:[7FFBD3140890]         | 00007FFBD3140890:"Format: ent_find substring [substring...] [-exclude_substring...] \n"
        $+19      | FF15 F1E2C102              | call qword ptr ds:[<&Msg>]
        $+1F      | 48:83C4 70                 | add rsp,70
        $+23      | 41:5F                      | pop r15
        $+25      | C3                         | ret
        $+26      | 48:899C24 80000000         | mov qword ptr ss:[rsp+80],rbx
        $+2E      | 48:8D0D BB26C802           | lea rcx,qword ptr ds:[7FFBD31408E0]         | 00007FFBD31408E0:"Searching for entities with class/target name containing substrings: "
        $+35      | 48:897C24 58               | mov qword ptr ss:[rsp+58],rdi
        $+3A      | 33FF                       | xor edi,edi
        $+3C      | 89BC24 88000000            | mov dword ptr ss:[rsp+88],edi
        $+43      | FF15 C7E2C102              | call qword ptr ds:[<&Msg>]
        $+49      | 41:8B87 38040000           | mov eax,dword ptr ds:[r15+438]
        $+50      | BB 01000000                | mov ebx,1
        $+55      | 3BC3                       | cmp eax,ebx
        $+57      | 7E 5D                      | jle client.7FFBD04BE2A6
        $+59      | 8BFB                       | mov edi,ebx
        $+5B      | 0F1F4400 00                | nop dword ptr ds:[rax+rax],eax
        $+60      | 48:85FF                    | test rdi,rdi
        $+63      | 78 11                      | js client.7FFBD04BE266
        $+65      | 3BD8                       | cmp ebx,eax
        $+67      | 7D 0D                      | jge client.7FFBD04BE266
        $+69      | 49:8B87 40040000           | mov rax,qword ptr ds:[r15+440]
        $+70      | 48:8B14F8                  | mov rdx,qword ptr ds:[rax+rdi*8]
        $+74      | EB 07                      | jmp client.7FFBD04BE26D
        $+76      | 48:8D15 8D80C502           | lea rdx,qword ptr ds:[7FFBD31162FA]
        $+7D      | 48:8D0D B426C802           | lea rcx,qword ptr ds:[7FFBD3140928]         | 00007FFBD3140928:"\"%s\""
        $+84      | FF15 86E2C102              | call qword ptr ds:[<&Msg>]
        $+8A      | 41:8B87 38040000           | mov eax,dword ptr ds:[r15+438]
        $+91      | FFC8                       | dec eax
        $+93      | 3BD8                       | cmp ebx,eax
        $+95      | 74 0D                      | je client.7FFBD04BE294
        $+97      | 48:8D0D 1EFFC702           | lea rcx,qword ptr ds:[7FFBD313E1AC]         | 00007FFBD313E1AC:", "
        $+9E      | FF15 6CE2C102              | call qword ptr ds:[<&Msg>]
        $+A4      | 41:8B87 38040000           | mov eax,dword ptr ds:[r15+438]
        $+AB      | FFC3                       | inc ebx
        $+AD      | 48:FFC7                    | inc rdi
        $+B0      | 3BD8                       | cmp ebx,eax
        $+B2      | 7C AC                      | jl client.7FFBD04BE250
        $+B4      | 33FF                       | xor edi,edi
        $+B6      | 48:8D0D 4B80C502           | lea rcx,qword ptr ds:[7FFBD31162F8]
        $+BD      | FF15 4DE2C102              | call qword ptr ds:[<&Msg>]
        $+C3      | 45:33C0                    | xor r8d,r8d
        $+C6      | 48:8D5424 38               | lea rdx,qword ptr ss:[rsp+38]
        $+CB      | 48:8D4C24 20               | lea rcx,qword ptr ss:[rsp+20]
        $+D0      | E8 ABD47002                | call client.7FFBD2BCB770
        $+D5      | 48:8D05 BC2CC702           | lea rax,qword ptr ds:[7FFBD3130F88]
        $+DC      | 48:8D4C24 20               | lea rcx,qword ptr ss:[rsp+20]
        $+E1      | 48:894424 38               | mov qword ptr ss:[rsp+38],rax
        $+E6      | E8 55817102                | call client.7FFBD2BD6430                    | <--- GetFirstEnt
        $+EB      | 48:898424 98000000         | mov qword ptr ss:[rsp+98],rax
        $+F3      | 48:8BD8                    | mov rbx,rax
        $+F6      | 48:85C0                    | test rax,rax
        $+F9      | 0F84 DA010000              | je client.7FFBD04BE4C9
        $+FF      | 48:896C24 68               | mov qword ptr ss:[rsp+68],rbp
        $+104     | 48:897424 60               | mov qword ptr ss:[rsp+60],rsi



        $ ==>     | 40:53                      | push rbx                                    | GetFirstEnt
        $+2       | 48:83EC 20                 | sub rsp,20
        $+6       | 8079 11 00                 | cmp byte ptr ds:[rcx+11],0
        $+A       | 48:8BD9                    | mov rbx,rcx
        $+D       | 75 07                      | jne client.7FFBD2BD6446
        $+F       | 48:C701 00000000           | mov qword ptr ds:[rcx],0
        $+16      | C641 11 00                 | mov byte ptr ds:[rcx+11],0
        $+1A      | 48:8B05 5FCE8E02           | mov rax,qword ptr ds:[7FFBD54C32B0]
        $+21      | 48:85C0                    | test rax,rax
        $+24      | 0F84 8B000000              | je client.7FFBD2BD64E5
        $+2A      | 48:8B09                    | mov rcx,qword ptr ds:[rcx]
        $+2D      | 48:85C9                    | test rcx,rcx
        $+30      | 74 06                      | je client.7FFBD2BD6468
        $+32      | 48:8B41 60                 | mov rax,qword ptr ds:[rcx+60]
        $+36      | EB 16                      | jmp client.7FFBD2BD647E
        $+38      | 807B 10 00                 | cmp byte ptr ds:[rbx+10],0
        $+3C      | 75 09                      | jne client.7FFBD2BD6477
        $+3E      | 48:8B80 10020000           | mov rax,qword ptr ds:[rax+210]              | <--- offset
        $+45      | EB 07                      | jmp client.7FFBD2BD647E
        $+47      | 48:8B80 30020000           | mov rax,qword ptr ds:[rax+230]
        $+4E      | 48:8903                    | mov qword ptr ds:[rbx],rax
        $+51      | 48:85C0                    | test rax,rax
        $+54      | 74 4E                      | je client.7FFBD2BD64D4
        $+56      | 48:8B4B 08                 | mov rcx,qword ptr ds:[rbx+8]
        $+5A      | 48:85C9                    | test rcx,rcx
        $+5D      | 74 20                      | je client.7FFBD2BD64AF
        $+5F      | 8B50 30                    | mov edx,dword ptr ds:[rax+30]
        $+62      | C1EA 09                    | shr edx,9
        $+65      | F6C2 01                    | test dl,1
        $+68      | 75 2E                      | jne client.7FFBD2BD64C8
        $+6A      | 48:8B11                    | mov rdx,qword ptr ds:[rcx]
        $+6D      | 4C:8B02                    | mov r8,qword ptr ds:[rdx]
        $+70      | 48:8B10                    | mov rdx,qword ptr ds:[rax]
        $+73      | 41:FFD0                    | call r8
        $+76      | 84C0                       | test al,al
        $+78      | 75 05                      | jne client.7FFBD2BD64AF
        $+7A      | 48:8B03                    | mov rax,qword ptr ds:[rbx]
        $+7D      | EB 19                      | jmp client.7FFBD2BD64C8
        $+7F      | 44:8B43 14                 | mov r8d,dword ptr ds:[rbx+14]
        $+83      | 45:85C0                    | test r8d,r8d
        $+86      | 74 1C                      | je client.7FFBD2BD64D4
        $+88      | 48:8B03                    | mov rax,qword ptr ds:[rbx]
        $+8B      | 48:8B08                    | mov rcx,qword ptr ds:[rax]
        $+8E      | 48:8B51 10                 | mov rdx,qword ptr ds:[rcx+10]
        $+92      | 44:3942 38                 | cmp dword ptr ds:[rdx+38],r8d
        $+96      | 74 0C                      | je client.7FFBD2BD64D4
        $+98      | 48:8B40 60                 | mov rax,qword ptr ds:[rax+60]
        $+9C      | 48:8903                    | mov qword ptr ds:[rbx],rax
        $+9F      | 48:85C0                    | test rax,rax
        $+A2      | 75 B2                      | jne client.7FFBD2BD6486
        $+A4      | 48:8B03                    | mov rax,qword ptr ds:[rbx]
        $+A7      | 48:85C0                    | test rax,rax
        $+AA      | 74 09                      | je client.7FFBD2BD64E5
        $+AC      | 48:8B00                    | mov rax,qword ptr ds:[rax]
        $+AF      | 48:83C4 20                 | add rsp,20
        $+B3      | 5B                         | pop rbx
        $+B4      | C3                         | ret
        $+B5      | 33C0                       | xor eax,eax
        $+B7      | 48:83C4 20                 | add rsp,20
        $+BB      | 5B                         | pop rbx
        $+BC      | C3                         | ret
        */
        return Member<CEntityIdentity*>(0x210);
    }
};

std::string_view make_strview(char const* e)
{
    if (e)
    {
        return std::string_view{ e };
    }
    return std::string_view{};
}

BOOL APIENTRY DllMain(HMODULE, DWORD ul_reason_for_call, LPVOID)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        auto const engine2 = GetModuleHandleA("engine2.dll");
        if (engine2)
        {
            auto const create_interface_fn = GetProcAddress(engine2, "CreateInterface");
            int status = 0;
            auto const GRSC = (reinterpret_cast<void* (*)(const char*, int*)>(create_interface_fn))
                ("GameResourceServiceClientV001", &status);
            if (status == 0 && GRSC)
            {
                const auto entity_system = static_cast<NormalClass*>(GRSC)
                    ->Member<CGameEntitySystem*>(0x58);
                if (entity_system)
                {
                    for (CEntityIdentity const* identity = entity_system->getFirstIdentity();
                        identity;
                        identity = identity->m_pNext())
                    {
                        auto const* const entity = identity->m_pEntity();
                        if (entity)
                        {
                            auto const handle = identity->m_hEntityHandle();
                            if (handle.is_valid())
                            {
                                auto const index = handle.index();
                                if (index < 0x4000) /* networkable ents(not clientside) */
                                {
                                    OutputDebugStringA(std::format
                                            (R"(ent @ {} index {} name "{}" designerName "{}")",
                                            (void*)identity->m_pEntity(), index,
                                            make_strview(identity->m_name()),
                                            make_strview(identity->m_designerName()))
                                        .data());
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                OutputDebugStringA(std::format("CreateInterface GameResourceServiceClientV001 failure: {}", reinterpret_cast<void*>(status)).data());
            }
        }
        else
        {
            OutputDebugStringA("no engine2.dll");
        }
    }
    return TRUE;
}
Посмотреть вложение 312781
 
Премногоблагодарен! Наконец-то я своими глазами увидел этот грёбаный EntityList Посмотреть вложение 312856
и теперь могу дальше продвигаться по твоим гайдам :pepehzo: Еще раз спасибо!
почитай https://yougame.biz/threads/354750/#post-3312023
со всеми вложенными ссылками(и там еще тоже вложены)
если вкратце то есть айдентити(это чтото типо паспорта сущности там есть имя айди флаги класс и прочая служебная хуйня), в айдентити также есть и указатель на саму ентити(а в ентити есть обратно на ее айдентити); в энтитисистеме хранятся листы айдентитей, хранятся они по 512 штук в одном листе, и таких айендити-листов 64 штуки и они лежат в энтитисистеме(итого в доте макс 32768(512*64) сущностей(32768 = 0x7FFF)). айдентити между собой связаны в дабли линкед лист(у любой айдентити можно взять следующую за ней или предыдущую перед ней), в энтитисистеме есть самая первая айдентити(голова линкед листа) (и возможно последняя(хвост линкед листа) тоже может быть я не тестил в другом направлении), так можно итерировать ентитей - берешь голову и идешь некст некст некст пока нуллптр не будет; раньше можно было просто по индексу от 0 до последнего итерировать но вроде щас убрали последний индекс. однако получение по индексу(GetEntityByIndex, там на этих ссылках есть или поиск сделаешь на форуме этом) всё еще важно для нормальной работы с ентитями(потому что существуют CHandle'ы всякие, там на ссылках тоже всё есть или поиск сделаешь)
 
ну ты правильно понял(там две практически одинаковые функции для получения первой и последующей сущностей)
параметрами там какието структуры... ну и хуй с ними. можешь по оффсету просто брать первую айдентити и не париться с этими функциями
оффсет в функции подсмотри просто и сам делай то же самое что и функция делает, просто руками, там пара строк кода всего лишь полезных в функции этой - получение первой айдентити(от нее потом дальше будут все остальные браться поочерёдно)(CGameEntitySystem @ 0x210) если она не передана в функцию, или если передана то берется у переданной айдентити m_pNext(CEntityIdentity @ 0x60) (ну и в итоге возвращает ентити из айдентити(CEntityIdentity @ 0x0)).
ну и естественно сама CGameEntitySystem тебе ещё понадобится(откуда то же надо сущности брать, верно?), на неё миллион хрефов, он есть даже и в самих этих функциях(либо бери из GameResourceServiceClientV001)
(бтв такая итерация мусор всякий клиентсайд чисто визуальный типо деревьев тоже выдаёт, можно такое скипать там индексы у мусора будут >3fff т.е. MSB индекса в 1(индекс 15-битный), т.е. можно сказать что индекс есть юнион "полезного" индекса(14 битов) и бита который отвечает за клиентсайдность)
C++:
Expand Collapse Copy
#include <Windows.h>

#include <cstdint>
#include <cstddef>
#include <utility>
#include <format>

struct NormalClass
{
    template<class T>
    decltype(auto) Member(this auto&& self, std::ptrdiff_t offset)
    {
        return std::forward_like<decltype(self)&>
            (*reinterpret_cast<T*>(reinterpret_cast<std::uintptr_t>(&self) + offset));
    }
};


struct C_BaseEntity {};

template<class T>
struct CHandle
{
    int impl = -1;
    unsigned int index() const
    {
        return static_cast<unsigned int>(impl) & 0x7fff;
    }
    bool is_valid() const
    {
        return impl != -1
            && index() != 0x7fff;
    }
};

//client.dll/classes/CEntityIdentity
struct CEntityIdentity : NormalClass
{
    decltype(auto) m_pEntity(this auto&& self)
    {
        //undocumented
        return self.template Member<C_BaseEntity*>(0x0);
    }
    decltype(auto) m_hEntityHandle(this auto&& self)
    {
        //undocumented
        return self.template Member<CHandle<C_BaseEntity>>(0x10);
    }
    decltype(auto) m_pNext(this auto&& self)
    {
        //CEntityIdentity* m_pNext(offset 0x60, size 0x8, align 0x8)
        return self.template Member<CEntityIdentity*>(0x60);
    }
    decltype(auto) m_name(this auto&& self)
    {
        //CUtlSymbolLarge m_name(offset 0x18, size 0x8, align 0x8)
        return self.template Member<char const*>(0x18);
    }
    decltype(auto) m_designerName(this auto&& self)
    {
        //CUtlSymbolLarge m_designerName(offset 0x20, size 0x8, align 0x8)
        return self.template Member<char const*>(0x20);
    }
};

struct CGameEntitySystem : NormalClass
{
    decltype(auto) getFirstIdentity()
    {
        /*
        cf. cl_ent_find - xref "Format: ent_find substring [substring...] [-exclude_substring...] \n"

        $ ==>     | 41:57                      | push r15                                    | cl_ent_find
        $+2       | 48:83EC 70                 | sub rsp,70
        $+6       | 83BA 38040000 02           | cmp dword ptr ds:[rdx+438],2
        $+D       | 4C:8BFA                    | mov r15,rdx
        $+10      | 7D 14                      | jge client.7FFBD04BE216
        $+12      | 48:8D0D 8726C802           | lea rcx,qword ptr ds:[7FFBD3140890]         | 00007FFBD3140890:"Format: ent_find substring [substring...] [-exclude_substring...] \n"
        $+19      | FF15 F1E2C102              | call qword ptr ds:[<&Msg>]
        $+1F      | 48:83C4 70                 | add rsp,70
        $+23      | 41:5F                      | pop r15
        $+25      | C3                         | ret
        $+26      | 48:899C24 80000000         | mov qword ptr ss:[rsp+80],rbx
        $+2E      | 48:8D0D BB26C802           | lea rcx,qword ptr ds:[7FFBD31408E0]         | 00007FFBD31408E0:"Searching for entities with class/target name containing substrings: "
        $+35      | 48:897C24 58               | mov qword ptr ss:[rsp+58],rdi
        $+3A      | 33FF                       | xor edi,edi
        $+3C      | 89BC24 88000000            | mov dword ptr ss:[rsp+88],edi
        $+43      | FF15 C7E2C102              | call qword ptr ds:[<&Msg>]
        $+49      | 41:8B87 38040000           | mov eax,dword ptr ds:[r15+438]
        $+50      | BB 01000000                | mov ebx,1
        $+55      | 3BC3                       | cmp eax,ebx
        $+57      | 7E 5D                      | jle client.7FFBD04BE2A6
        $+59      | 8BFB                       | mov edi,ebx
        $+5B      | 0F1F4400 00                | nop dword ptr ds:[rax+rax],eax
        $+60      | 48:85FF                    | test rdi,rdi
        $+63      | 78 11                      | js client.7FFBD04BE266
        $+65      | 3BD8                       | cmp ebx,eax
        $+67      | 7D 0D                      | jge client.7FFBD04BE266
        $+69      | 49:8B87 40040000           | mov rax,qword ptr ds:[r15+440]
        $+70      | 48:8B14F8                  | mov rdx,qword ptr ds:[rax+rdi*8]
        $+74      | EB 07                      | jmp client.7FFBD04BE26D
        $+76      | 48:8D15 8D80C502           | lea rdx,qword ptr ds:[7FFBD31162FA]
        $+7D      | 48:8D0D B426C802           | lea rcx,qword ptr ds:[7FFBD3140928]         | 00007FFBD3140928:"\"%s\""
        $+84      | FF15 86E2C102              | call qword ptr ds:[<&Msg>]
        $+8A      | 41:8B87 38040000           | mov eax,dword ptr ds:[r15+438]
        $+91      | FFC8                       | dec eax
        $+93      | 3BD8                       | cmp ebx,eax
        $+95      | 74 0D                      | je client.7FFBD04BE294
        $+97      | 48:8D0D 1EFFC702           | lea rcx,qword ptr ds:[7FFBD313E1AC]         | 00007FFBD313E1AC:", "
        $+9E      | FF15 6CE2C102              | call qword ptr ds:[<&Msg>]
        $+A4      | 41:8B87 38040000           | mov eax,dword ptr ds:[r15+438]
        $+AB      | FFC3                       | inc ebx
        $+AD      | 48:FFC7                    | inc rdi
        $+B0      | 3BD8                       | cmp ebx,eax
        $+B2      | 7C AC                      | jl client.7FFBD04BE250
        $+B4      | 33FF                       | xor edi,edi
        $+B6      | 48:8D0D 4B80C502           | lea rcx,qword ptr ds:[7FFBD31162F8]
        $+BD      | FF15 4DE2C102              | call qword ptr ds:[<&Msg>]
        $+C3      | 45:33C0                    | xor r8d,r8d
        $+C6      | 48:8D5424 38               | lea rdx,qword ptr ss:[rsp+38]
        $+CB      | 48:8D4C24 20               | lea rcx,qword ptr ss:[rsp+20]
        $+D0      | E8 ABD47002                | call client.7FFBD2BCB770
        $+D5      | 48:8D05 BC2CC702           | lea rax,qword ptr ds:[7FFBD3130F88]
        $+DC      | 48:8D4C24 20               | lea rcx,qword ptr ss:[rsp+20]
        $+E1      | 48:894424 38               | mov qword ptr ss:[rsp+38],rax
        $+E6      | E8 55817102                | call client.7FFBD2BD6430                    | <--- GetFirstEnt
        $+EB      | 48:898424 98000000         | mov qword ptr ss:[rsp+98],rax
        $+F3      | 48:8BD8                    | mov rbx,rax
        $+F6      | 48:85C0                    | test rax,rax
        $+F9      | 0F84 DA010000              | je client.7FFBD04BE4C9
        $+FF      | 48:896C24 68               | mov qword ptr ss:[rsp+68],rbp
        $+104     | 48:897424 60               | mov qword ptr ss:[rsp+60],rsi



        $ ==>     | 40:53                      | push rbx                                    | GetFirstEnt
        $+2       | 48:83EC 20                 | sub rsp,20
        $+6       | 8079 11 00                 | cmp byte ptr ds:[rcx+11],0
        $+A       | 48:8BD9                    | mov rbx,rcx
        $+D       | 75 07                      | jne client.7FFBD2BD6446
        $+F       | 48:C701 00000000           | mov qword ptr ds:[rcx],0
        $+16      | C641 11 00                 | mov byte ptr ds:[rcx+11],0
        $+1A      | 48:8B05 5FCE8E02           | mov rax,qword ptr ds:[7FFBD54C32B0]
        $+21      | 48:85C0                    | test rax,rax
        $+24      | 0F84 8B000000              | je client.7FFBD2BD64E5
        $+2A      | 48:8B09                    | mov rcx,qword ptr ds:[rcx]
        $+2D      | 48:85C9                    | test rcx,rcx
        $+30      | 74 06                      | je client.7FFBD2BD6468
        $+32      | 48:8B41 60                 | mov rax,qword ptr ds:[rcx+60]
        $+36      | EB 16                      | jmp client.7FFBD2BD647E
        $+38      | 807B 10 00                 | cmp byte ptr ds:[rbx+10],0
        $+3C      | 75 09                      | jne client.7FFBD2BD6477
        $+3E      | 48:8B80 10020000           | mov rax,qword ptr ds:[rax+210]              | <--- offset
        $+45      | EB 07                      | jmp client.7FFBD2BD647E
        $+47      | 48:8B80 30020000           | mov rax,qword ptr ds:[rax+230]
        $+4E      | 48:8903                    | mov qword ptr ds:[rbx],rax
        $+51      | 48:85C0                    | test rax,rax
        $+54      | 74 4E                      | je client.7FFBD2BD64D4
        $+56      | 48:8B4B 08                 | mov rcx,qword ptr ds:[rbx+8]
        $+5A      | 48:85C9                    | test rcx,rcx
        $+5D      | 74 20                      | je client.7FFBD2BD64AF
        $+5F      | 8B50 30                    | mov edx,dword ptr ds:[rax+30]
        $+62      | C1EA 09                    | shr edx,9
        $+65      | F6C2 01                    | test dl,1
        $+68      | 75 2E                      | jne client.7FFBD2BD64C8
        $+6A      | 48:8B11                    | mov rdx,qword ptr ds:[rcx]
        $+6D      | 4C:8B02                    | mov r8,qword ptr ds:[rdx]
        $+70      | 48:8B10                    | mov rdx,qword ptr ds:[rax]
        $+73      | 41:FFD0                    | call r8
        $+76      | 84C0                       | test al,al
        $+78      | 75 05                      | jne client.7FFBD2BD64AF
        $+7A      | 48:8B03                    | mov rax,qword ptr ds:[rbx]
        $+7D      | EB 19                      | jmp client.7FFBD2BD64C8
        $+7F      | 44:8B43 14                 | mov r8d,dword ptr ds:[rbx+14]
        $+83      | 45:85C0                    | test r8d,r8d
        $+86      | 74 1C                      | je client.7FFBD2BD64D4
        $+88      | 48:8B03                    | mov rax,qword ptr ds:[rbx]
        $+8B      | 48:8B08                    | mov rcx,qword ptr ds:[rax]
        $+8E      | 48:8B51 10                 | mov rdx,qword ptr ds:[rcx+10]
        $+92      | 44:3942 38                 | cmp dword ptr ds:[rdx+38],r8d
        $+96      | 74 0C                      | je client.7FFBD2BD64D4
        $+98      | 48:8B40 60                 | mov rax,qword ptr ds:[rax+60]
        $+9C      | 48:8903                    | mov qword ptr ds:[rbx],rax
        $+9F      | 48:85C0                    | test rax,rax
        $+A2      | 75 B2                      | jne client.7FFBD2BD6486
        $+A4      | 48:8B03                    | mov rax,qword ptr ds:[rbx]
        $+A7      | 48:85C0                    | test rax,rax
        $+AA      | 74 09                      | je client.7FFBD2BD64E5
        $+AC      | 48:8B00                    | mov rax,qword ptr ds:[rax]
        $+AF      | 48:83C4 20                 | add rsp,20
        $+B3      | 5B                         | pop rbx
        $+B4      | C3                         | ret
        $+B5      | 33C0                       | xor eax,eax
        $+B7      | 48:83C4 20                 | add rsp,20
        $+BB      | 5B                         | pop rbx
        $+BC | C3 | ret
        */
        return Member<CEntityIdentity*>(0x210);
    }
};

std::string_view make_strview(char const* e)
{
    if (e)
    {
        return std::string_view{ e };
    }
    return std::string_view{};
}

BOOL APIENTRY DllMain(HMODULE, DWORD ul_reason_for_call, LPVOID)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        auto const engine2 = GetModuleHandleA("engine2.dll");
        if (engine2)
        {
            auto const create_interface_fn = GetProcAddress(engine2, "CreateInterface");
            int status = 0;
            auto const GRSC = (reinterpret_cast<void* (*)(const char*, int*)>(create_interface_fn))
                ("GameResourceServiceClientV001", &status);
            if (status == 0 && GRSC)
            {
                const auto entity_system = static_cast<NormalClass*>(GRSC)
                    ->Member<CGameEntitySystem*>(0x58);
                if (entity_system)
                {
                    for (CEntityIdentity const* identity = entity_system->getFirstIdentity();
                        identity;
                        identity = identity->m_pNext())
                    {
                        auto const* const entity = identity->m_pEntity();
                        if (entity)
                        {
                            auto const handle = identity->m_hEntityHandle();
                            if (handle.is_valid())
                            {
                                auto const index = handle.index();
                                if (index < 0x4000) /* networkable ents(not clientside) */
                                {
                                    OutputDebugStringA(std::format
                                            (R"(ent @ {} index {} name "{}" designerName "{}")",
                                            (void*)identity->m_pEntity(), index,
                                            make_strview(identity->m_name()),
                                            make_strview(identity->m_designerName()))
                                        .data());
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                OutputDebugStringA(std::format("CreateInterface GameResourceServiceClientV001 failure: {}", reinterpret_cast<void*>(status)).data());
            }
        }
        else
        {
            OutputDebugStringA("no engine2.dll");
        }
    }
    return TRUE;
}
Посмотреть вложение 312781
u are beast dude as usual thanks a lot for your precious time and effort <3
 
Назад
Сверху Снизу