• MONEY за подписку! Ничего делать не надо совсем, всего-то подписаться на тг одмена и нажать кнопку "Принять участие" в розыгрыше: https://t.me/govthing/7650

Вопрос Отдаление камеры в доте C++

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
26 Дек 2024
Сообщения
22
Реакции
0
Хотелось бы объяснения от знающих людей по теме отдаления камеры в доте, хочу начать с чего-то, что-то вроде понимаю, но не до конца.
 
что конкретно объяснить?
есть конвар dota_camera_distance, у него есть коллбек на изменение который срабатывает когда ты в консоли меняешь значение(нет смысла его менять без вызова коллбека оно не будет работать), этот коллбек пишет в глобальную переменную, значение этой переменной каждый кадр копируется в камеру доты, и потом используется при построении вьюматрицы которая потом идет в вертекс шейдер. любое из этих мест подходит для достижения целей(правда естественно с разными усилиями). самое элементарное - та самая глобальная переменная(назовём ее g_flCameraDistance). находится спокойно в чит енджине просто меняя в консольке квар dota_camera_distance(зелёный адрес у нее будет).
1740641936175.png

далее через хвбп(hardware breakpoint - в чит енджине называется "Find out what accesses this address") находишь инструкции которые работают с этой переменной и делаешь на них сигу(чтобы при апдейтах не надо было руками обновлять всё) и потом находишь их в доте и достаешь из них операнд и делаешь из него абсолютный адрес и пишешь туда что хочешь
C++:
Expand Collapse Copy
00007FFD5549A270 | 48:83EC 28                 | sub rsp,28                                                             | GetCameraDistance
00007FFD5549A274 | E8 D7FBFFFF                | call client.7FFD55499E50                                               | GetPtrTo_g_flCameraDistance
00007FFD5549A279 | F3:0F1000                  | movss xmm0,dword ptr ds:[rax]                                          |
00007FFD5549A27D | 48:83C4 28                 | add rsp,28                                                             |
00007FFD5549A281 | C3                         | ret                                                                    |
C++:
Expand Collapse Copy
00007FFD55499E50 | 40:53                      | push rbx                                                               | GetPtrTo_g_flCameraDistance
00007FFD55499E52 | 48:83EC 20                 | sub rsp,20                                                             |
00007FFD55499E56 | BA FFFFFFFF                | mov edx,FFFFFFFF                                                       |
00007FFD55499E5B | 48:8D0D 6E11B003           | lea rcx,qword ptr ds:[7FFD58F9AFD0]                                    |
00007FFD55499E62 | E8 09178201                | call client.7FFD56CBB570                                               |
00007FFD55499E67 | 48:85C0                    | test rax,rax                                                           |
00007FFD55499E6A | 75 0B                      | jne client.7FFD55499E77                                                |
00007FFD55499E6C | 48:8B05 6511B003           | mov rax,qword ptr ds:[7FFD58F9AFD8]                                    |
00007FFD55499E73 | 48:8B40 08                 | mov rax,qword ptr ds:[rax+8]                                           |
00007FFD55499E77 | 48:6318                    | movsxd rbx,dword ptr ds:[rax]                                          |
00007FFD55499E7A | 48:8D0D AF16AC03           | lea rcx,qword ptr ds:[7FFD58F5B530]                                    |
00007FFD55499E81 | BA FFFFFFFF                | mov edx,FFFFFFFF                                                       |
00007FFD55499E86 | E8 E5168201                | call client.7FFD56CBB570                                               |
00007FFD55499E8B | 48:85C0                    | test rax,rax                                                           |
00007FFD55499E8E | 75 0B                      | jne client.7FFD55499E9B                                                |
00007FFD55499E90 | 48:8B05 A116AC03           | mov rax,qword ptr ds:[7FFD58F5B538]                                    |
00007FFD55499E97 | 48:8B40 08                 | mov rax,qword ptr ds:[rax+8]                                           |
00007FFD55499E9B | 8038 00                    | cmp byte ptr ds:[rax],0                                                |
00007FFD55499E9E | 74 1F                      | je client.7FFD55499EBF                                                 |
00007FFD55499EA0 | 85DB                       | test ebx,ebx                                                           |
00007FFD55499EA2 | 7E 1B                      | jle client.7FFD55499EBF                                                |
00007FFD55499EA4 | 48:83FB 02                 | cmp rbx,2                                                              |
00007FFD55499EA8 | 73 15                      | jae client.7FFD55499EBF                                                |
00007FFD55499EAA | 48:8D045B                  | lea rax,qword ptr ds:[rbx+rbx*2]                                       |
00007FFD55499EAE | 48:8D0D 9B316802           | lea rcx,qword ptr ds:[7FFD57B1D050]                                    |
00007FFD55499EB5 | 48:8D04C1                  | lea rax,qword ptr ds:[rcx+rax*8]                                       |
00007FFD55499EB9 | 48:83C4 20                 | add rsp,20                                                             |
00007FFD55499EBD | 5B                         | pop rbx                                                                |
00007FFD55499EBE | C3                         | ret                                                                    |
00007FFD55499EBF | 8B15 7BEED403              | mov edx,dword ptr ds:[7FFD591E8D40]                                    |
00007FFD55499EC5 | 6548:8B0425 58000000       | mov rax,qword ptr gs:[58]                                              |
00007FFD55499ECE | B9 50000000                | mov ecx,50                                                             |
00007FFD55499ED3 | 48:8B04D0                  | mov rax,qword ptr ds:[rax+rdx*8]                                       |
00007FFD55499ED7 | 8B0401                     | mov eax,dword ptr ds:[rcx+rax]                                         |
00007FFD55499EDA | 3905 A88CB003              | cmp dword ptr ds:[7FFD58FA2B88],eax                                    |
00007FFD55499EE0 | 7F 0D                      | jg client.7FFD55499EEF                                                 |
00007FFD55499EE2 | 48:8D05 878CB003           | lea rax,qword ptr ds:[7FFD58FA2B70]                                    | g_flCameraDistance
00007FFD55499EE9 | 48:83C4 20                 | add rsp,20                                                             |
00007FFD55499EED | 5B                         | pop rbx                                                                |
00007FFD55499EEE | C3                         | ret                                                                    |
 
что конкретно объяснить?
есть конвар dota_camera_distance, у него есть коллбек на изменение который срабатывает когда ты в консоли меняешь значение(нет смысла его менять без вызова коллбека оно не будет работать), этот коллбек пишет в глобальную переменную, значение этой переменной каждый кадр копируется в камеру доты, и потом используется при построении вьюматрицы которая потом идет в вертекс шейдер. любое из этих мест подходит для достижения целей(правда естественно с разными усилиями). самое элементарное - та самая глобальная переменная(назовём ее g_flCameraDistance). находится спокойно в чит енджине просто меняя в консольке квар dota_camera_distance(зелёный адрес у нее будет).
Посмотреть вложение 299845
далее через хвбп(hardware breakpoint - в чит енджине называется "Find out what accesses this address") находишь инструкции которые работают с этой переменной и делаешь на них сигу(чтобы при апдейтах не надо было руками обновлять всё) и потом находишь их в доте и достаешь из них операнд и делаешь из него абсолютный адрес и пишешь туда что хочешь
C++:
Expand Collapse Copy
00007FFD5549A270 | 48:83EC 28                 | sub rsp,28                                                             | GetCameraDistance
00007FFD5549A274 | E8 D7FBFFFF                | call client.7FFD55499E50                                               | GetPtrTo_g_flCameraDistance
00007FFD5549A279 | F3:0F1000                  | movss xmm0,dword ptr ds:[rax]                                          |
00007FFD5549A27D | 48:83C4 28                 | add rsp,28                                                             |
00007FFD5549A281 | C3                         | ret                                                                    |
C++:
Expand Collapse Copy
00007FFD55499E50 | 40:53                      | push rbx                                                               | GetPtrTo_g_flCameraDistance
00007FFD55499E52 | 48:83EC 20                 | sub rsp,20                                                             |
00007FFD55499E56 | BA FFFFFFFF                | mov edx,FFFFFFFF                                                       |
00007FFD55499E5B | 48:8D0D 6E11B003           | lea rcx,qword ptr ds:[7FFD58F9AFD0]                                    |
00007FFD55499E62 | E8 09178201                | call client.7FFD56CBB570                                               |
00007FFD55499E67 | 48:85C0                    | test rax,rax                                                           |
00007FFD55499E6A | 75 0B                      | jne client.7FFD55499E77                                                |
00007FFD55499E6C | 48:8B05 6511B003           | mov rax,qword ptr ds:[7FFD58F9AFD8]                                    |
00007FFD55499E73 | 48:8B40 08                 | mov rax,qword ptr ds:[rax+8]                                           |
00007FFD55499E77 | 48:6318                    | movsxd rbx,dword ptr ds:[rax]                                          |
00007FFD55499E7A | 48:8D0D AF16AC03           | lea rcx,qword ptr ds:[7FFD58F5B530]                                    |
00007FFD55499E81 | BA FFFFFFFF                | mov edx,FFFFFFFF                                                       |
00007FFD55499E86 | E8 E5168201                | call client.7FFD56CBB570                                               |
00007FFD55499E8B | 48:85C0                    | test rax,rax                                                           |
00007FFD55499E8E | 75 0B                      | jne client.7FFD55499E9B                                                |
00007FFD55499E90 | 48:8B05 A116AC03           | mov rax,qword ptr ds:[7FFD58F5B538]                                    |
00007FFD55499E97 | 48:8B40 08                 | mov rax,qword ptr ds:[rax+8]                                           |
00007FFD55499E9B | 8038 00                    | cmp byte ptr ds:[rax],0                                                |
00007FFD55499E9E | 74 1F                      | je client.7FFD55499EBF                                                 |
00007FFD55499EA0 | 85DB                       | test ebx,ebx                                                           |
00007FFD55499EA2 | 7E 1B                      | jle client.7FFD55499EBF                                                |
00007FFD55499EA4 | 48:83FB 02                 | cmp rbx,2                                                              |
00007FFD55499EA8 | 73 15                      | jae client.7FFD55499EBF                                                |
00007FFD55499EAA | 48:8D045B                  | lea rax,qword ptr ds:[rbx+rbx*2]                                       |
00007FFD55499EAE | 48:8D0D 9B316802           | lea rcx,qword ptr ds:[7FFD57B1D050]                                    |
00007FFD55499EB5 | 48:8D04C1                  | lea rax,qword ptr ds:[rcx+rax*8]                                       |
00007FFD55499EB9 | 48:83C4 20                 | add rsp,20                                                             |
00007FFD55499EBD | 5B                         | pop rbx                                                                |
00007FFD55499EBE | C3                         | ret                                                                    |
00007FFD55499EBF | 8B15 7BEED403              | mov edx,dword ptr ds:[7FFD591E8D40]                                    |
00007FFD55499EC5 | 6548:8B0425 58000000       | mov rax,qword ptr gs:[58]                                              |
00007FFD55499ECE | B9 50000000                | mov ecx,50                                                             |
00007FFD55499ED3 | 48:8B04D0                  | mov rax,qword ptr ds:[rax+rdx*8]                                       |
00007FFD55499ED7 | 8B0401                     | mov eax,dword ptr ds:[rcx+rax]                                         |
00007FFD55499EDA | 3905 A88CB003              | cmp dword ptr ds:[7FFD58FA2B88],eax                                    |
00007FFD55499EE0 | 7F 0D                      | jg client.7FFD55499EEF                                                 |
00007FFD55499EE2 | 48:8D05 878CB003           | lea rax,qword ptr ds:[7FFD58FA2B70]                                    | g_flCameraDistance
00007FFD55499EE9 | 48:83C4 20                 | add rsp,20                                                             |
00007FFD55499EED | 5B                         | pop rbx                                                                |
00007FFD55499EEE | C3                         | ret                                                                    |
Спасибо, я это знал, но столкнулся с проблемой именно в визуал студио, также я не уточнил в самой теме, в чём собственно проблема
Можно ли какой-нибудь простенький пример для старта?
 
Последнее редактирование:
Спасибо, у меня проблема именно в визуал студио, уже пробовал и вылет, хотелось бы посмотреть на пример этого отдаления
вылет - дебажь. а так конечно нечему тут вроде вылетать.
а какой там пример то... WriteProcessMemory(экстернал) да и всё... для теста для начала можешь через RVA адрес сделать
 
вылет - дебажь. а так конечно нечему тут вроде вылетать.
а какой там пример то... WriteProcessMemory(экстернал) да и всё... для теста для начала можешь через RVA адрес сделать
Не, именно с кодом, желательно интернал, я хочу с чего-то начать, уже 2 месяца пытаюсь найти, так и не понимаю
 
Не, именно с кодом, желательно интернал, я хочу с чего-то начать, уже 2 месяца пытаюсь найти, так и не понимаю
интернал еще проще - там чтение и запись напрямую происходят
че конкретно то ты найти не можешь. "не понимаю" это ничего не значит, это как к доктору приходить и говорить "ой у меня всё болит везде" он тебе не поможет пока ты ничего конкретного не скажешь. как искал что делал на каком шаге потерпел неудачу, блаблабла
 
интернал еще проще - там чтение и запись напрямую происходят
че конкретно то ты найти не можешь. "не понимаю" это ничего не значит, это как к доктору приходить и говорить "ой у меня всё болит везде" он тебе не поможет пока ты ничего конкретного не скажешь. как искал что делал на каком шаге потерпел неудачу, блаблабла
Саму правильную реализацию, которая хоть как-то будет работать, в частности мне непонятно чтение памяти и её изменение
 
в частности мне непонятно чтение памяти и её изменение
в интернале? в интернале работа с памятью осуществляется напрямую в соответствии с языком(с++).
если честно лень тебе объяснять как с++ работает... всё сложно я заебусь расписывать. почитай про указатели и ссылки. одна из основных концепций это "переменная". как следует из названия, ее значение неопределено(зависит от времени - сейчас оно одно а через 5 секунд может быть другое) и его нужно каждый раз заново смотреть, в отличии от заведомо известной константы(стоит различать константную переменную(которая один раз приняла значение и потом уже не будет меняться, но ее значение все равно заведомо неизвестно, все равно нужно его смотреть, оно просто меняться потом уже не будет; константная переменная особо ничем не отличается от обычной с технической точки зрения) и заведомо известные константы(то что уже заведомо известно еще на стадии компиляции программы; обычно они вхуяриваются напрямую в генерируемые компилятором инструкции как непосредственные значения)). любая переменная - это адрес, на котором лежит некое значение. соответственно узнать значение = прочитать с этого адреса данные, присвоить значение = записать по этому адресу данные. переменная и ее значение это разные вещи. для простоты (это не совсем так но) давай представим что работа с памятью возможна только через ссылки, а не через указатели(это одно и то же в техническом плане просто у них разные фичи с точки зрения языка). указатель превращается в ссылку через *, а ссылка в указатель через &. у ссылок нет арифметики, у указателей она есть(но она уебанская т.к. указатели это массивы неопределённой размерности и прибавление к ним это как индексация в массиве; там прибавляются элементы а не байты(например +1 для указателя на инт это будет +4 байта потому что один инт это четыре байта, +2 это будет +8 байт и т.д.)).
запись по ссылкам через =
C++:
Expand Collapse Copy
char* client = (char*)GetModuleHandle("client.dll");//ASLR
float* g_flCameraDistance = (float*)(client + 0x51E2B70);//RVA
*g_flCameraDistance = 2000.0f;//указатель в ссылку и дальше вызов метода operator= который встроен в язык для примитивного типа float
само чтение происходит когда ссылка кастуется в свой подлежащий тип(int& в int, например)(компилятор сам это автоматически вставляет где надо), т.е. когда она из адреса "деградирует" до значения находящегося на этом адресе(это и есть считывание)
Код:
Expand Collapse Copy
int A = 123;//еще раз, 123 это инт, A это не int это ссылка на инт(адрес где лежит наше 123)
...
int B = A;//ссылка A деградировала до 123(произошло чтение - мы же не знаем какое значение лежит в A, это же переменная - ее значение меняется, надо проверять каждый раз) и потом 123 записалось по ссылке B
указатель если что это просто число(4/8 байт на x86/x64), можно спокойно кастовать указатели в числа(std::uintptr_t) и обратно
 
в интернале? в интернале работа с памятью осуществляется напрямую в соответствии с языком(с++).
если честно лень тебе объяснять как с++ работает... всё сложно я заебусь расписывать. почитай про указатели и ссылки. одна из основных концепций это "переменная". как следует из названия, ее значение неопределено(зависит от времени - сейчас оно одно а через 5 секунд может быть другое) и его нужно каждый раз заново смотреть, в отличии от заведомо известной константы(стоит различать константную переменную(которая один раз приняла значение и потом уже не будет меняться, но ее значение все равно заведомо неизвестно, все равно нужно его смотреть, оно просто меняться потом уже не будет; константная переменная особо ничем не отличается от обычной с технической точки зрения) и заведомо известные константы(то что уже заведомо известно еще на стадии компиляции программы; обычно они вхуяриваются напрямую в генерируемые компилятором инструкции как непосредственные значения)). любая переменная - это адрес, на котором лежит некое значение. соответственно узнать значение = прочитать с этого адреса данные, присвоить значение = записать по этому адресу данные. переменная и ее значение это разные вещи. для простоты (это не совсем так но) давай представим что работа с памятью возможна только через ссылки, а не через указатели(это одно и то же в техническом плане просто у них разные фичи с точки зрения языка). указатель превращается в ссылку через *, а ссылка в указатель через &. у ссылок нет арифметики, у указателей она есть(но она уебанская т.к. указатели это массивы неопределённой размерности и прибавление к ним это как индексация в массиве; там прибавляются элементы а не байты(например +1 для указателя на инт это будет +4 байта потому что один инт это четыре байта, +2 это будет +8 байт и т.д.)).
запись по ссылкам через =
C++:
Expand Collapse Copy
char* client = (char*)GetModuleHandle("client.dll");//ASLR
float* g_flCameraDistance = (float*)(client + 0x51E2B70);//RVA
*g_flCameraDistance = 2000.0f;//указатель в ссылку и дальше вызов метода operator= который встроен в язык для примитивного типа float
само чтение происходит когда ссылка кастуется в свой подлежащий тип(int& в int, например)(компилятор сам это автоматически вставляет где надо), т.е. когда она из адреса "деградирует" до значения находящегося на этом адресе(это и есть считывание)
Код:
Expand Collapse Copy
int A = 123;//еще раз, 123 это инт, A это не int это ссылка на инт(адрес где лежит наше 123)
...
int B = A;//ссылка A деградировала до 123(произошло чтение - мы же не знаем какое значение лежит в A, это же переменная - ее значение меняется, надо проверять каждый раз) и потом 123 записалось по ссылке B
указатель если что это просто число(4/8 байт на x86/x64), можно спокойно кастовать указатели в числа(std::uintptr_t) и обратно
Спасибо, это я и искал, очень помог
 
в интернале? в интернале работа с памятью осуществляется напрямую в соответствии с языком(с++).
если честно лень тебе объяснять как с++ работает... всё сложно я заебусь расписывать. почитай про указатели и ссылки. одна из основных концепций это "переменная". как следует из названия, ее значение неопределено(зависит от времени - сейчас оно одно а через 5 секунд может быть другое) и его нужно каждый раз заново смотреть, в отличии от заведомо известной константы(стоит различать константную переменную(которая один раз приняла значение и потом уже не будет меняться, но ее значение все равно заведомо неизвестно, все равно нужно его смотреть, оно просто меняться потом уже не будет; константная переменная особо ничем не отличается от обычной с технической точки зрения) и заведомо известные константы(то что уже заведомо известно еще на стадии компиляции программы; обычно они вхуяриваются напрямую в генерируемые компилятором инструкции как непосредственные значения)). любая переменная - это адрес, на котором лежит некое значение. соответственно узнать значение = прочитать с этого адреса данные, присвоить значение = записать по этому адресу данные. переменная и ее значение это разные вещи. для простоты (это не совсем так но) давай представим что работа с памятью возможна только через ссылки, а не через указатели(это одно и то же в техническом плане просто у них разные фичи с точки зрения языка). указатель превращается в ссылку через *, а ссылка в указатель через &. у ссылок нет арифметики, у указателей она есть(но она уебанская т.к. указатели это массивы неопределённой размерности и прибавление к ним это как индексация в массиве; там прибавляются элементы а не байты(например +1 для указателя на инт это будет +4 байта потому что один инт это четыре байта, +2 это будет +8 байт и т.д.)).
запись по ссылкам через =
C++:
Expand Collapse Copy
char* client = (char*)GetModuleHandle("client.dll");//ASLR
float* g_flCameraDistance = (float*)(client + 0x51E2B70);//RVA
*g_flCameraDistance = 2000.0f;//указатель в ссылку и дальше вызов метода operator= который встроен в язык для примитивного типа float
само чтение происходит когда ссылка кастуется в свой подлежащий тип(int& в int, например)(компилятор сам это автоматически вставляет где надо), т.е. когда она из адреса "деградирует" до значения находящегося на этом адресе(это и есть считывание)
Код:
Expand Collapse Copy
int A = 123;//еще раз, 123 это инт, A это не int это ссылка на инт(адрес где лежит наше 123)
...
int B = A;//ссылка A деградировала до 123(произошло чтение - мы же не знаем какое значение лежит в A, это же переменная - ее значение меняется, надо проверять каждый раз) и потом 123 записалось по ссылке B
указатель если что это просто число(4/8 байт на x86/x64), можно спокойно кастовать указатели в числа(std::uintptr_t) и обратно
А как допустим указатели разыменовывать?
Я просто вообще новичок
 
А как допустим указатели разыменовывать?
Я просто вообще новичок
братанчик, гугл и чат гпт существуют, тебе дали полный раскрытый ответ как сделать что ты хочешь, в интернете том же самом сотни примеров кода где меняют значение через writeprocessmemory, тебе просто нужно получить адресс камеры через тот же самый чит енжин и поставить его
 
братанчик, гугл и чат гпт существуют, тебе дали полный раскрытый ответ как сделать что ты хочешь, в интернете том же самом сотни примеров кода где меняют значение через writeprocessmemory, тебе просто нужно получить адресс камеры через тот же самый чит енжин и поставить его
Щас распробую
 
А как допустим указатели разыменовывать?
Я просто вообще новичок
это уебанское слово "разыменовывать" забудь его. указатели и ссылки - одно и то же просто с разными фичами в языке(указатели для арифметики(это массивы неограниченного размера по факту) и вызова функций, ссылки для работы с памятью(точнее вызова методов но не суть)), оба туда сюда переделываются, указатель через * перед ним переделывается в ссылку, ссылка через & перед ней переделывается в указатель. можно хоть
C++:
Expand Collapse Copy
*&*&*&*&*&*&*&*&*&A
и это выражение будет полностью эквивалентно выражению A(при условии что A - ссылка, т.е. переменная, например)(т.е. ничего не произойдет)
C++:
Expand Collapse Copy
void** fn()
{
    std::cout << "shit" << std::endl;
    return nullptr;
}

void fn2(void*& x)
{
    std::cout << &x << std::endl;
}

int main()
{
    fn2(*&*&*&*&*&*&*&*&*(fn()));
    return 0;
}
здесь память никак не трогается(ссылка * fn() никогда не "деградируется" до void*)
выдаст
надо прибавлять(арифметика) - юзай указатели(или еще в число их можно кастануть - std::uintptr_t, для какой-нибудь хуйни, например достать какой-то бит указателя или еще что-нибудь), нужно читать/писать в память/вызывать методы или операторы - юзай ссылки. туда сюда спокойно они все переделываются.
C++:
Expand Collapse Copy
*(float*)((char*)GetModuleHandle("client.dll") + 0x51E2B70) = 2000.0f;
(из char* делается float*, потом делается float&, потом вызывается operator=)
и
C++:
Expand Collapse Copy
(float&)(*((char*)GetModuleHandle("client.dll") + 0x51E2B70)) = 2000.0f;
(из char* делается char&, потом делается float&, потом вызывается operator=)
эквивалентны(правда первый вариант гораздо более популярный и понятный/привычный для людей)
 
это уебанское слово "разыменовывать" забудь его. указатели и ссылки - одно и то же просто с разными фичами в языке(указатели для арифметики(это массивы неограниченного размера по факту) и вызова функций, ссылки для работы с памятью(точнее вызова методов но не суть)), оба туда сюда переделываются, указатель через * перед ним переделывается в ссылку, ссылка через & перед ней переделывается в указатель. можно хоть
C++:
Expand Collapse Copy
*&*&*&*&*&*&*&*&*&A
и это выражение будет полностью эквивалентно выражению A(при условии что A - ссылка, т.е. переменная, например)(т.е. ничего не произойдет)
C++:
Expand Collapse Copy
void** fn()
{
    std::cout << "shit" << std::endl;
    return nullptr;
}

void fn2(void*& x)
{
    std::cout << &x << std::endl;
}

int main()
{
    fn2(*&*&*&*&*&*&*&*&*(fn()));
    return 0;
}
здесь память никак не трогается(ссылка * fn() никогда не "деградируется" до void*)
выдаст

надо прибавлять(арифметика) - юзай указатели(или еще в число их можно кастануть - std::uintptr_t, для какой-нибудь хуйни, например достать какой-то бит указателя или еще что-нибудь), нужно читать/писать в память/вызывать методы или операторы - юзай ссылки. туда сюда спокойно они все переделываются.
C++:
Expand Collapse Copy
*(float*)((char*)GetModuleHandle("client.dll") + 0x51E2B70) = 2000.0f;
(из char* делается float*, потом делается float&, потом вызывается operator=)
и
C++:
Expand Collapse Copy
(float&)(*((char*)GetModuleHandle("client.dll") + 0x51E2B70)) = 2000.0f;
(из char* делается char&, потом делается float&, потом вызывается operator=)
эквивалентны(правда первый вариант гораздо более популярный и понятный/привычный для людей)
не ворк, но спасибо за ответ.
благодаря тебе хоть что-то понял :)
 
не ворк, но спасибо за ответ.
благодаря тебе хоть что-то понял :)
ты про код
C++:
Expand Collapse Copy
*(float*)((char*)GetModuleHandle("client.dll") + 0x51E2B70) = 2000.0f;
?
конеш не ворк, там же RVA юзается, оно смещается с каждым апдейтом файла. надо сигскан потому что юзать.
 
ты про код
C++:
Expand Collapse Copy
*(float*)((char*)GetModuleHandle("client.dll") + 0x51E2B70) = 2000.0f;
?
конеш не ворк, там же RVA юзается, оно смещается с каждым апдейтом файла. надо сигскан потому что юзать.
Браааат, спасибо за помощь, у меня получилось.
Проблема была не в коде, а в оффсете, он не 0x51E2B70, а 0x51E2BA0
Браааат, спасибо за помощь, у меня получилось.
Проблема была не в коде, а в оффсете, он не 0x51E2B70, а 0x51E2BA0
Скорее всего поменяли после патча
 
Скорее всего поменяли после патча
он автоматически компилятором меняется по мере добавления/удаления данных в секциях. и так будет практически с каждым апдейтом доты(клиент.длл часто меняется).
 
Назад
Сверху Снизу