находишь с хрефа "CreateParticle" джаваскриптовую функцию. чекаешь ее код.
Посмотреть вложение 106535
бп ставишь на этот прыжок, вызываешь функцию несколько раз из джаваскрипта, благодаря бпшкам чекаешь какие прыжки выполняются/не выполняются, собираешь статистику и делаешь вывод например такой: первый прыжок всегда выполняется, второй выполняется когда параметр xx равен yy, третий никогда не выполняется и т.д., в общем динамически анализируешь что происходит - передаешь в функцию разные параметры по несколько раз и смотришь что происходит.
вот код после первого прыжка:
Посмотреть вложение 106536
mov rcx, CDOTA_ParticleManager*
mov r9, [rcx]
lea r8, [указатель_на_какую-то_структуру_которая_находится_в_стеке]
mov ebx, [rcx+MaxHandle_offset]
lea edx, [rbx+1]
mov [rcx+MaxHandle_offset], edx
mov edx,ebx
call [r9+38h]
вот и все что тебе нужно.
int handle = CDOTA_ParticleManager->MaxHandle();
CDOTA_ParticleManager->SetHandle(handle+1);
CDOTA_ParticleManager->VirtualCall<0x38/8(будет 7)>(CDOTA_ParticleManager(то есть this), &MyStruct, handle);
единственный вопрос который у тебя тут может возникнуть это что же именно за структура находится в стеке. кликаешь на нее в дампе(rsp+20) и видишь что там лежит имя партикли блаблабла еще какаято хрень. делаешь себе такую же структуру
struct {const char* a; int b; entity* c} MyStruct = {"",ParticleAttachment_t::XXX,Entity}
и пытаешься вызвать. и партикля у тебя не создастся.
поэтому расширяешь структуру
struct {const char* a; int b; entity* c; char pad[200];} MyStruct = {"",ParticleAttachment_t::XXX,Entity}//остальное автоматом в 0 ставится
тем самым добавив еще 200 байтов(200 перебор но работает и мне пох) нулей в структуру чтобы наверняка.
и теперь все работает. делаешь вывод что структура состоит из более чем 3 членов и для успешной работы один/несколько из членов которые ты не можешь понять что делают должны быть в нулину.