Гайд Продолжение. вбе(партикли)

Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
Как я понял хук так работает, типо делается mov rax, [12345], дальше прыгаем на джамп rax и там выполняется наша функа которую мы написали и в конце те самые две инструкции после с прыжок на оригинал?
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Как я понял хук так работает, типо делается mov rax, [12345], дальше прыгаем на джамп rax и там выполняется наша функа которую мы написали и в конце те самые две инструкции после с прыжок на оригинал?
берешь оригинал функцию. находишь там приятное для хука место. 12 байт тебе нужно. в этом месте байтпатчишь на mov rax, [&my_obertka](указатель на указатель my_obertka, так как это не lea(load effective address,загрузить в регистр просто данное число которое может представлять из себя указатель а иногда может и не представлять его) а mov, то есть происходит считывание с данного указателя.), и потом jmp rax. твой my_obertka это участок либо аллоцированный(память выделена под него) через VirtualAlloc либо как у меня просто какая-то мусорная функция(лучше юзай VirtualAlloc, работают оба способа но мой слишком извращенский, он больше показывает идею что так можно делать чем практичный). в этом участке my_obertka находятся следующие инструкции:
call my_hooked_callback//call чтобы сохранять регистры и прочую хрень чтобы автоматом все подчистилось, однако можно и напрямую заинлайненый код функции вместо call сделать
original_instructions//то что ты в оригинале затер своим mov rax; jmp rax
mov rax, [&(original+offset)]//указатель на указатель. оффсет это следующая за твоим jmp rax в оригинале инструкция, а точнее ее адрес относительно адреса original
jmp rax
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
берешь оригинал функцию. находишь там приятное для хука место. 12 байт тебе нужно. в этом месте байтпатчишь на mov rax, [&my_obertka](указатель на указатель my_obertka, так как это не lea(load effective address,загрузить в регистр просто данное число которое может представлять из себя указатель а иногда может и не представлять его) а mov, то есть происходит считывание с данного указателя.), и потом jmp rax. твой my_obertka это участок либо аллоцированный(память выделена под него) через VirtualAlloc либо как у меня просто какая-то мусорная функция(лучше юзай VirtualAlloc, работают оба способа но мой слишком извращенский, он больше показывает идею что так можно делать чем практичный). в этом участке my_obertka находятся следующие инструкции:
call my_hooked_callback//call чтобы сохранять регистры и прочую хрень чтобы автоматом все подчистилось, однако можно и напрямую заинлайненый код функции вместо call сделать
original_instructions//то что ты в оригинале затер своим mov rax; jmp rax
mov rax, [&(original+offset)]//указатель на указатель. оффсет это следующая за твоим jmp rax в оригинале инструкция, а точнее ее адрес относительно адреса original
jmp rax
Спасибо
 
Забаненный
Статус
Оффлайн
Регистрация
5 Окт 2020
Сообщения
18
Реакции[?]
7
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
ты сейчас сломал 50% мозга мемберам этого форума
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
а откуда берутся впкф файлы партиклей?
gcfscape скачай для открытия .vpk файлов
потом steamapps\common\dota 2 beta\game\dota\pak01_dir.vpk открой этой прогой
там папка particles. и там дальше разберешься.
есть еще на подобии прога
Пожалуйста, авторизуйтесь для просмотра ссылки.
там можно большинство партиклей/моделей/прочей хрени прямо там же декодировать и просмотреть. в gcfscape можно только распаковывать файлы из впк но не просматривать их декодированное содержимое
 
Начинающий
Статус
Оффлайн
Регистрация
12 Сен 2020
Сообщения
42
Реакции[?]
3
Поинты[?]
0
gcfscape скачай для открытия .vpk файлов
потом steamapps\common\dota 2 beta\game\dota\pak01_dir.vpk открой этой прогой
там папка particles. и там дальше разберешься.
есть еще на подобии прога
Пожалуйста, авторизуйтесь для просмотра ссылки.
там можно большинство партиклей/моделей/прочей хрени прямо там же декодировать и просмотреть. в gcfscape можно только распаковывать файлы из впк но не просматривать их декодированное содержимое
спасибо!
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
А что если сразу всю функцию хукать без трамплинов и потом вызвать оригинал функу? Вроде как еще до ее выполнения значения пихаются в регистры
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
А что если сразу всю функцию хукать без трамплинов и потом вызвать оригинал функу? Вроде как еще до ее выполнения значения пихаются в регистры
подробнее распиши что ты хочешь. ты хочешь просто хукнуть в другом месте, типа в начале функции?
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
подробнее распиши что ты хочешь. ты хочешь просто хукнуть в другом месте, типа в начале функции?
Да, я уже хукнул в начале функи и сделал вызов орига в конце (правда не смотрел работает ли он), вот так, чтобы удостоверится работает ли это, сделал вывод обычный в консоль, оно работает
C++:
typedef unsigned long long(*OTVC)(unsigned long long rcx, unsigned long long rdx, unsigned long long r8, unsigned long long r9);
unsigned long long OnTeamVisibilityChange_pattern = 0;

C_ConsoleMessage ConsoleMessage;

unsigned long long hkOTVC(unsigned long long rcx, unsigned long long rdx, unsigned long long r8, unsigned long long r9)
{
    for(int i = 0; i < 10; i++)
    {
        if (rcx == LocalEnt)
        {
            ConsoleMessage.CMSG("LocalEnt\n");
            Visible = (*(int*)r8 == 14 || *(int*)r8 == 30);
            break;
        }
        else
        {
            ConsoleMessage.CMSG("Wrond Entity\n");
        }
    }

    OTVC origin = (OTVC)OnTeamVisibilityChange_pattern;
    return origin(rcx, rdx, r8, r9);
}
На цикл там не смотри, херню написал :))
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Да, я уже хукнул в начале функи и сделал вызов орига в конце (правда не смотрел работает ли он), вот так, чтобы удостоверится работает ли это, сделал вывод обычный в консоль, оно работает
C++:
typedef unsigned long long(*OTVC)(unsigned long long rcx, unsigned long long rdx, unsigned long long r8, unsigned long long r9);
unsigned long long OnTeamVisibilityChange_pattern = 0;

C_ConsoleMessage ConsoleMessage;

unsigned long long hkOTVC(unsigned long long rcx, unsigned long long rdx, unsigned long long r8, unsigned long long r9)
{
    for(int i = 0; i < 10; i++)
    {
        if (rcx == LocalEnt)
        {
            ConsoleMessage.CMSG("LocalEnt\n");
            Visible = (*(int*)r8 == 14 || *(int*)r8 == 30);
            break;
        }
        else
        {
            ConsoleMessage.CMSG("Wrond Entity\n");
        }
    }

    OTVC origin = (OTVC)OnTeamVisibilityChange_pattern;
    return origin(rcx, rdx, r8, r9);
}
На цикл там не смотри, херню написал :))
ну кароче ты можешь делать все что угодно, исследуй, можешь даже без дллки хукать чисто в дебагере
сначала ставишь на паузу приложение в дебагере(там кнопка на панели там где старт стоп рестарт там и пауза есть), потом заходишь в Memory Map, там по пустому месту пкм, Allocate Memory, записываешь себе адрес куда-нибудь, потом в самой функе которую хукаешь просто нажимаешь пкм->Assemble(пробел), вводишь туда mov rax, [твой_адрес] и jmp rax.
твой_адрес это указатель на кусок твоего региона который ты аллоцировал, в этом куске региона в 8байтовую ячейку запиши начало своего хука
и в начале своего хука собираешь оригинальные инструкции которые ты затер, потом ради теста снова mov rax, [твой_адрес_2] и jmp rax
твой_адрес2 это указатель на кусок твоего региона в котором указатель на оригинал+12(ну то место которое идет после того хука)
типа
вкладка CPU:
My_Region:
<original_instrukcii>
mov rax, [My_Region+108]
jmp rax
окно Dump где ты собственно и записываешь данные:
My_Region+100(твой_адрес) My_Region
My_Region+108(твой_адрес_2) Original+12
в итоге оригинал функция считывает с My_Region+100 и прыгает туда
а это My_Region. она выполняет оттуда оригинал инстуркции и потом считывает с My_Region+108, а там оригинал+12
вот пример чистого хука просто с возвратом в оригинал без какого-либо лога или еще чего-то в самом дебагере
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
ну кароче ты можешь делать все что угодно, исследуй, можешь даже без дллки хукать чисто в дебагере
сначала ставишь на паузу приложение в дебагере(там кнопка на панели там где старт стоп рестарт там и пауза есть), потом заходишь в Memory Map, там по пустому месту пкм, Allocate Memory, записываешь себе адрес куда-нибудь, потом в самой функе которую хукаешь просто нажимаешь пкм->Assemble(пробел), вводишь туда mov rax, [твой_адрес] и jmp rax.
твой_адрес это указатель на кусок твоего региона который ты аллоцировал, в этом куске региона в 8байтовую ячейку запиши начало своего хука
и в начале своего хука собираешь оригинальные инструкции которые ты затер, потом ради теста снова mov rax, [твой_адрес_2] и jmp rax
твой_адрес2 это указатель на кусок твоего региона в котором указатель на оригинал+12(ну то место которое идет после того хука)
типа
вкладка CPU:
My_Region:
<original_instrukcii>
mov rax, [My_Region+108]
jmp rax
окно Dump где ты собственно и записываешь данные:
My_Region+100(твой_адрес) My_Region
My_Region+108(твой_адрес_2) Original+12
в итоге оригинал функция считывает с My_Region+100 и прыгает туда
а это My_Region. она выполняет оттуда оригинал инстуркции и потом считывает с My_Region+108, а там оригинал+12
вот пример чистого хука просто с возвратом в оригинал без какого-либо лога или еще чего-то в самом дебагере
Спасибо!
 
Начинающий
Статус
Оффлайн
Регистрация
12 Сен 2020
Сообщения
42
Реакции[?]
3
Поинты[?]
0
handle у партиклей это их динамический индекс, и прибавляя единицу при создании он автоматически присваивается к нашему партиклю?
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
handle у партиклей это их динамический индекс, и прибавляя единицу при создании он автоматически присваивается к нашему партиклю?
handle это индекс чисто для этого CDOTAParticleManagerSystem. вне этого класса вроде он не юзается. прибавляя единицу ты просто увеличиваешь max_particle_index в этом классе, чтобы потом снова его получить и создать с ним партикль, и снова к нему прибавить единицу. он присваивается на этапе создания партикли, а единицу ты просто сам прибавляешь после этого. а потом чтобы получить партиклю ты берешь ее индекс и находишь его в этом классе и делаешь что хочешь.
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
Мне получается нужна функа CreateParticle? Этак которая принимает название партикля, тип, и для какой энтити создать
Particles.CreateParticle( cstring pParticleName, integer nAttachType, integer nEntityToAttach )
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Мне получается нужна функа CreateParticle? Этак которая принимает название партикля, тип, и для какой энтити создать
Particles.CreateParticle( cstring pParticleName, integer nAttachType, integer nEntityToAttach )
да, название партикля(путь в впк файле(particles\items_fx\abyssal_blade.vpcf_c условно), тип привязки(
Пожалуйста, авторизуйтесь для просмотра ссылки.
), айди сущности к которой нужно привязать(0 это world, то есть спавн партикли на каком-то месте на самой карте))
вызываешь ее из джаваскрипта ставишь бпшки и т.д. и реверсишь, потом повторяешь то что делает функция но на своем с++ уже
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Тут их кста несколько, и есть еще какой то для игрока, CreateParticleForPlayer
тебе он не нужен. и лучше ищи в дебагере хрефы, там как раз легче понять что есть что потому что там есть указатель на CDOTAParticleManagerSystem, сразу понятно что ты нашел что искал так как понятия по смыслу связаны - искал создание партиклей, нашел какой-то класс с говорящим названием.
в ида это просто какой-то qword_xxxx нихрена не понятно.
в итоге ты зашел в дебагер нашел в client.dll все хрефы и чекаешь функи которые там в регистры после этих хрефов загружаются, а в этих функах чекаешь movы всякие на предмет указателя на этот CDOTAParticleManagerSystem(RTTI)
 
Сверху Снизу