Перейти к содержанию

Блоги

 

[Dishonored] История о там как решал проблему с русской версией игры

Добро пожаловать на борт, мои юные любители моря и реверса. На этот раз мы решим проблему игры, разработчики которой не стали этого делать уже на протяжении 6 лет.   На весь реверс ушло порядка 50 рюмок рома, 6 подбитых кораблей британской империи и конечно же несколько портовых шл..., ах да, реверс. С языковыми winapi я не работал до этого момента и поэтому пришлось вручную дебажить весь код от инициализации игры, до создания интерфейсов и всякой не интересной ерунды.   Итак, изначально у нас было решение проблемы в виде костылей, что для фикса надо сменить язык в системе или текущую клавиатуру на английский, но кому это нравится? Можете спросить: «Зачем отлаживать код вручную, когда есть трассировка?»
Ну что-ж, мои маленькие пираты ответ прост, игра при использовании трассировки или отладки с обходом вызывает странный код и пропускает вообще все, что нам нужно исследовать, который при отладке с заходом не вызывается.     Всего пришлось дебажить около 10к инструкций, чтобы найти винапи которая выгружает, угадайте что? Правильно, идентификатор локали ввода. После вызова этой функции, у нас и пропадает из трея языковая панель и ломается локаль. Итак, мы нашли виновника, и что нам делать с ним? Нет, мы не будем скидывать разработчиков за борт. (а стоило бы)     Теперь нам нужно понять, как это все работает и откуда берется этот идентификатор локали ввода.   Отправляемся в бухту знаний и таинств…     Гуглим, гуглим, гуглим и наконец нагуглили winapi с именем LoadKeyboarLayout, круто,  отправляемся снова в дом к прекрасной иде, которую за все время нашего путешествия встречаем впервые, переходим на адрес инструкции с функцией выгрузки идентификатора. Вот и весь путь идентификатора.       Нашли мы LoadKeyboarLayout и теперь нас будет интересовать только первый аргумент этой функции, почему так? Да просто потому что мы умеем читать документацию и знаем, что значение первого аргумента равно 409, будет работать как положено, только если дефолтный язык в системе будет английский, для русского языка, необходимо использовать значение 419 это можно найти в мсдн.     В чем же заключалась проблема? Я думаю в лени разработчиков, а если судить о коде, проблему вызывала загрузка английской локали, но если её нет, то и загружать нечего, а значит и выгружать, а значит будут проблемы. Фикс заключается в исправлении значений загружаемой локали для распакованной версии, либо создании загрузчика для стимовской версии, который бы фиксил все это каждый запуск.   Всех с днем пиратства!   P.S Ах, да совсем забыл написать, все эксперименты проводились на распакованной версии игры, без Steam DRM т.к. со Steam DRM весь файл зашифрован и найти что-либо или пропатчить невозможно. Этим утром нашел ещё проблему некорректной инициализации steamapi, из-за чего игра время от времени крашилась. Сам по себе Steam-DRM инициализирует steamapi, но раз мы его вырезали, то естественно будут проблемы при обращении к нему. Для того чтобы решить проблему со steamapi, нам необходимо создать текстовый файл около файла steam_api.dll с именем steam_appid.txt и указать в нем ID игры для принудительно инициализации.    

partoftheworlD

partoftheworlD

 

Временное отсутствие

Привет всем. Я думаю, что меня может не быть на форуме продолжительное время от 2х месяцев в связи с обстоятельствами. Переезд, поиск работы и семейные обстоятельства. Второй момент. Я создал кнопки яндекс кошелька в некоторых темах моего блога. Толку от кнопок нет, т.к. там все по нулям. Поэтому я их удалю. Lua плагины для CE пока делать нет возможности. До встречи в Москве! ) Буду искать работу в новой игровой студии уже в Москве

MasterGH

MasterGH

 

[Counter-Strike Global Offensive]RCS аналог no recoil

Сегодня сделаем Recoil Control System, а точнее его простейшую реализацию. Используя такой способ можно добиться стрельбы в одну точку на любом расстоянии с учетом значений разброса и ускорения отдачи. Все как обычно, открываем иду и ищем смещения.  m_Local m_aimPunch   Ещё необходимо найти адрес управляющий координатами камеры, но это слишком просто чтобы останавливаться на этом. Итак, теперь надо компенсировать отдачу, для этого мы просто складывает старый вектор Punch с новым, можно умножать на 2, но точность будет отличаться на 10-15%.   DWORD m_dwLocal = 0x0; DWORD m_vecAimPunch = 0x0; vec3 m_vecOldPunch = {0,0,0}; auto CLocalPlayer = m->read<DWORD>(dwClient + 0x00C5C86C); auto CClientState = m->read<DWORD>(dwEngine + 0x586A74); vec3 m_vecAngles = m->read<vec3>(CClientState + 0x4D10); vec3 m_vecPunch = m->read<vec3>(CLocalPlayer + m_dwLocal + m_vecAimPunch) static vec3 *tempAngles = new vec3(m_vecAngles); tempAngles->x -= m_vecPunch.x + m_vecOldPunch.x; tempAngles->y -= m_vecPunch.y + m_vecOldPunch.y; tempAngles->z = 0; m->write<vec3>(dwvecAngles + 0x4D10, tempAngles); m_vecOldPunch = m_vecPunch; delete tempAngles; Это конечно не так просто как в Warface, но затруднений вызвать не должно.      

partoftheworlD

partoftheworlD

 

[IDA Pro] Отслеживание интересующего регистра по функции

Сегодня напишем простейшую реализацию функции поиска используемого регистра в коде при статическом анализе, как когда-то показывал этот функционал в radare2. Немного модифицированный скрипт стоит у меня на вооружении для динамического анализа т.е. определяет где впервые адрес появляется, как рассчитывается, дампит смещения и пробует найти сигнатуру на статический адрес в коде. В общем немного подумав и почитав доки по иде, тоже сможете такое сделать без особых проблем.   Скрипт пишется минут за 15-20, но в дальнейшем экономит нереально много времени.   Единственная проблема возникла с получением точно адреса инструкции, во избежании повторений в выводе и была написана альтернатива функции range.  # подключаем необходимые библиотеки import idc # стандартные модуля для общения между идой import idaapi import re # для расширения функционала поиска reg_value = r'.*\[r14\+.*' # то, что будем искать def range_reverse(start, stop): # аналог функции range for i in FuncItems(start): if i < start and i >= stop: yield i ea = ScreenEA() # получение текущего адреса курсора current_function = idaapi.get_func(ea) # получение информации о функции # перебор инструкций по адресам for inst_addr in range_reverse(ea, current_function.startEA): disasm_output = idc.GetDisasm(inst_addr) # вывод дизассемблированной инструкции по её адресу if re.findall(reg_value, disasm_output): # фильтрация по нужному тексту print("0x%X" % inst_addr, disasm_output) Раз скрипт уже написали(скопипастили), приступим к тестам.   И так, у нас есть инструкций работающая со скорострельностью, нам надо посмотреть всякие интересности, типа проверок, что ещё работает с базовым адресом таймера скорострельности и т.д.     Выполняем скрипт и получаем всю информацию о интересующем регистре, так же, чтобы избавится от инструкций чтения и выводить только инструкции записи, можно добавив одну проверку, но с этим вы сами сможете справиться, я надеюсь вы меня не расстроите.     Так же можем отследить как вычисляется база следуя за регистром, переходя двойным кликом по адресу в окне вывода.     Это ведь проще, чем руками скролить функцию под 10-20к инструкций. В общем, если лень, что-то делать — автоматизируй или не делай.  

partoftheworlD

partoftheworlD

 

[IDA Pro] Экспорт информации из старой базы в новую

Тыкался тут на днях в кнопочках у иды и как оказалось у неё есть экспорт, и давно был, просто находятся в самом неожиданном месте. Так что, я был удивлен и расстроен одновременно. А расстроен тем, что я писал плагин для экспорта, руководствуясь словами "раз нет какого-то функционала, то сделай".   Итак, чтобы задампить всю информацию из старой базы надо будет кликнуть на File->Produce file -> Dump database to IDC script.   В итоге ида создаст для нас скрипт со всей информацией, останется лишь после анализа нового файла запустить его и база восстановится. Пример скрипта.     Если вы анализировали дамп, то советую перебазировать его по первому сегменту к 0 старую и новую базу, перед созданием скрипта для экспорта. И восстановление занимает достаточное количество времени(возможно, зависит от того на сколько восстановлена база) поэтому это отличная возможность, чтобы сходить за чаем.

partoftheworlD

partoftheworlD

 

[Grand Theft Auto Online] Поиск скрытых структур за счет игровых скриптов

Необходимые инструменты чтобы начать искать и делать скрытые структуры: OpenIV, Cheat Engine, GTA HLD, какой-нибудь ЯП для автоматизации действий и конечно же GTA. По сути этот метод позволяет использовать нативные вызовы без инъекции/скриптов в игру и делать с ней все что вздумается, спавнить оружие, спавнить машины, накручивать деньги, перемещать других игроков и т.д возможности безграничны. Итак, открываем OpenIV, находим скрипт freemode, экспортируем и декомпилируем с помощью GTA HLD , на выходе получается такой псевдокод.     Нас интересуют только глобальные переменные - Global_XXXX, где XXXX это значение индекса по которому будем вычислять положение скрытой структуры, кстати все это делается в той же функции которая была в прошлой статье про гта и чтобы не создавать костыли, достаточно зареверсить функцию и скопировать из неё код.   Вычисления будут выглядеть примерно так, newGlobalPageBase = struct_array + 8 * (index >> 18 & 0x3F) , таким образом мы получаем страницы памяти по 2Мб в которых будут скрытые структуры, а чтобы получить конкретный адрес, для работы с глобальной переменной,  value = newGlobalPageBase + 8 * (index & 0x3FFFF) Рассмотрим все это на конкретном примере, например на таймере одной из заданий.     Теперь, нам необходимо посчитать, либо индекс до начала структуры 0x40001, либо сразу до значения просто сложив 0x40001+0x454B. Подставляем, индекс в наш код и хоба     У нас есть адрес таймера игрового скрипта, который бы мы не смогли найти вручную с помощью поисковика, просто  потому что это статическое значение. Этот способ проще, быстрее и дает нам безграничные возможности по взлому игры просто тыкаясь в файлы скриптов. Именно таким образом и работает накрутка денег, спавн машин в онлайне, только манипулируя памятью игры.   Благодарности:  Reversal Thread 7h3 7r14ngl3

partoftheworlD

partoftheworlD

 

Основа для нейронной сети основанная на OpenCV

Сейчас это не совсем нейронка, больше напоминает робота ходящего по разметке, которую берет с помощью камеры, нужно добавить ещё агента, чтобы она самостоятельно обучалась, сохранение и загрузку базы данных с уже имеющимся опытом, и конечно же поправить настройки OpenCV для получения корректных линий.  

partoftheworlD

partoftheworlD

 

Плагин для ведения логов в CE

Плагин ведет историю поиска, отсева, отмены. Логи выглядят следующим образом Для чего может применятся На шаге отсева посмотреть в логах, какое значение искали до этого и какой способ поиска использовали. При неудачных поисках мы просматриваем как и что мы сканировали раньше. Если вообще ничего не получается при сканировании, то логами можно обмениваться. Горячие клавиши, которые настраиваются из окна настроек CE работают и в логах.   Установка: скопировать GHL_log.lua в директорию "/autorun" Lua скрипт:  В комментариях можно написать про ошибки или про идеи улучшения плагина.

MasterGH

MasterGH

 

Скин для Vivaldi

Начал модифицировать свой браузер и пока это выглядит примерно так, в планах поменять положения кнопочек их размер и удалить те, которыми я не пользуюсь, а так же сделать, чтобы футер использовал активные цвета страницы, ну и немного по выше сделать окно быстрых команд. В общем цель избавиться от всего лишнего, но улучшить интерфейс в плане производительности и сделать его минималистичным, но не слишком. Если это будет интересно, но кину проект на гитхаб и там по ходу дела буду его обновлять.  
 

partoftheworlD

partoftheworlD

Создаем мультихак, на примере игры Warface [3 часть]

И снова, здравствуйте)) В этой части, мы с вами создадим NoRecoil hack. Здесь, я уже не буду всё разжевывать. Опирайтесь на прошлые статьи, кому что-то не понятно. Открываем дамп из прошлых частей. Поиск по строкам. Для начала, нам нужно найти IGameFramework.   Вводим "Failed to create the GameFramework Interface!".   Двойной клик по строке, попадаем сюда   Через окно перекрестных ссылок, выходим на адрес   Итак, мы нашли адрес IGameFramewrok = 0x1AF7E2C   Теперь, в окне поиска строк, ищем "sp_difficulty"   Двойной клик по строке. Меню перекрестных ссылок. Открываем псевдокод.   Через ReClass x32 восстанавливаем классы. Переходим к написанию кода.   classes.h     Собираем проект. Внедряем в игру. Готово.  

JustHack

JustHack

 

[Grand Theft Auto Online] Stealth money или поиск скрытых структур для получения денег

Необходимые инструменты чтобы начать искать и делать стелс деньги: OpenIV, IDA, Cheat Engine и конечно же GTA с доступом к онлайну. Так же, если вы все собираетесь проделывать на основном аккаунте, то советую после всех манипуляций удалить персонажа и создать нового, так очищается список транзакций(но это не точно). Для начала нам необходимо зайти в одиночный режим, чтобы найти инструкции работающие с деньгами.     Это нам необходимо для того, чтобы не искать деньги в онлайне, в любом случае там найти мы их не сможем. Дальше, переходим в онлайн и так же переходим в дизассемблер. Нам необходимо узнать как рассчитывается rdx.     Ставим бряк на инструкцию mov rdx, [r8+rax*8] и в регистре rdx видим 00007FF739F26820, перейдем на этот адрес в IDA. Да это же массив с указателями на скрытые структуры, нам необходимо найти единственную работающую с деньгами, я думаю вы сами справитесь с этим, поэтому, как только мы нашли структуру связанную с деньгами высчитаем её индекс, он нам пригодится во время эмуляции транзакции.   (00007FF739F268A0 - 00007FF739F26820) / 8 = 0x10  
Теперь, нам придется восстановить смещения, проблема в том, что эта структура работает только с миссиями, ну что ж пойдем работать, но сначала необходимо найти начало структуры внутри указателя на структуру денег, для этого ещё немного по реверсим, зная адрес начала структуры поставим на инструкцию которую нашли до этого бряк с условием.     И идем выполнять миссию, главное получить деньги, поэтому советую выбрать одиночную миссию т.к. во время бряка с условием у вас будет фпс около 3-4 кадров(на моем компуктере миссия в 5 минут растянулась на 2 часа и пришлось перепроходить т.к. бряк не сработал, ага победитель по жизни.). Так что вас ожидает боль и страдания, но как только найдем начало нашей структуры, выставляем сравнение структур с блокировкой текущего состояния структуры и снова идем проходить миссию(в этот раз все будет на много лучше, обещаю)

  После прохождения миссии, снова смотрим в эту структуру, получаем вот такие значения, это и есть смещения работающие с транзакцией.   #1 000000000000004A * 8 = 1 (offset 0x250 ) //активатор транзакциии #2 0000000000000000 * 8 = 5 (offset 0x00 ) //5 счет банка, 4 наличка #3 0000000000000001 * 8 = 3587 (offset 0x08 ) //сумма #4 0000000000000002 * 8 = 1 (offset 0x10 ) //активатор #5 0000000000000003 * 8 = BC537E0D (offset 0x18 ) //хеш #6 0000000000000004 * 8 = 00000000 (offset 0x20 ) //сервисный хеш #7 0000000000000006 * 8 = 57DE404E (offset 0x30 ) //хеш #8 0000000000000007 * 8 = 00000000 (offset 0x38 ) //хеш типа действий #9 0000000000000047 * 8 = 4 (offset 0x238 ) //?? #10 0000000000000048 * 8 = 7 (offset 0x240 ) //?? #11 000000000000000A * 8 = -1 (offset 0x50 ) //?? #12 0000000000000028 * 8 = 0 (offset 0x140 ) //?? #13 0000000000000049 * 8 = 0 (offset 0x248 ) //?? #14 000000000000004B * 8 = 0 (offset 0x258 ) //?? #15 000000000000004F * 8 = 0 (offset 0x278 ) //?? Теперь нам необходимо найти новые хеши вместо нулей, для этого запускаем OpenIV и ищем файл с названием networkshop, и подставляем все хеши из блоков actiontype и services по нашим смещениям, actiontype задает тип транзакции т.е. добавить, отнять деньги и т.д, services задает от кого мы получили деньги, от R*, с гонок, со ставок и т.д.     Комбинаций много, но что делать, халява это дело времязатратное, тем самым перебирая хеши выстраиваем порядок выполнения транзакции, но иногда хеши фиксят, чтобы не допустить распространение читов.   BC537E0D
57DE404E
Эти 2 хеша предустановлены их можно найти в коде тем самым определив и функции работающие с транзакциями. Самое время начать писать код и тестировать. Хеши не рабочие в этом примере кода, чтобы любителям ничего не делать, пришлось пошевелиться.😉 //активация транзакции DWORD64 activate = 0x1; //установка хешей валидации транзакции WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x60), &activate, sizeof(activate), 0); DWORD64 value = 0xBC537E0D; WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x68), &value, sizeof(value), 0); //установка суммы транзакции int amount = 10000000; WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x58), &amount, sizeof(amount), 0); //установка хешей действий и откого будем получать деньги value = 0x762D6BF6; WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x70), &value, sizeof(value), 0); value = 0x3B6B7024; WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x88), &value, sizeof(value), 0); value = 0x57DE404E; WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x80), &value, sizeof(value), 0); //установка для того чтобы транзакция не зависла в ходе выполнения по разным причинам value = 0x7FFFFFFF; WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x50), &value, sizeof(value), 0); value = 0x07; WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x290), &value, sizeof(value), 0); //куда будем давать деньги 4 наличка, 5 счет банка value = 0x04; WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x288), &value, sizeof(value), 0); value = 0x01; WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x2a0), &value, sizeof(value), 0); //деактивация транзакции value = 0; WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x78), &value, sizeof(value), 0); WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x298), &value, sizeof(value), 0); WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x2a8), &value, sizeof(value), 0); WriteProcessMemory(hProcess, reinterpret_cast<PBYTE*>(buf + 0x2c8), &value, sizeof(value), 0); Инструкции работающие со значениями в функции.     Ну и результаты, так же я испытываю новый метод поиска подобного функционала, если все пройдет удачно, то скоро будет новая статья, в разы проще этой и быстрее. Ну, что вы молодцы, если дочитали до сюда, можете взять печеньку.      

partoftheworlD

partoftheworlD

 

Скрытые структуры, что это такое и с чем их едят.

Сегодня у нас будет прелюдия перед основной статьей, так что желательно быть готовым ко всему. Поехали. Скрытые структуры, что они из себя представляют? Скрытая структура это какая-то структура находящаяся в любой части используемой кодом структурой(назовем её мега-структурой), обычно мега-структуры огромных размеров(не зря же мы её так назвали) и содержат в себе по 10-100 скрытых структур, в ГТА например она занимает около 105кб. Как вообще игра находит скрытые структуры? Да, как и везде адрес мега-структуры + index * 0x8 для 64 битных приложений. А теперь поговорим о том как они работают, по сути скрытые структуры просто принимают в себя значения, а в коде это выглядит как обычная функция примерно так.

  Если по простому, то скрытые структуры можно представить как обработчики значений, которые работают постоянно, но как только определенное смещение будет равно определенному значению, то что-то случится. Одна из проблем при использовании таких структур им необходимо подавать все переменные в определенном порядке, например, если мы не активируем транзакцию, то и значение передаваемое не будет обработано, оно будет просто пропущено. Находить такие структуры обычным поиском практически не реально, значения попадающие в неё перезаписываются нулями через 10-20 мс в среднем. Поэтому нам и необходим реверс-инжиниринг. Еще одна проблема конкретно для гта, это расширение функционала структуры, а именно получение рабочих хешей, скажем так, хеши нужны для того чтобы транзакция считалась валидной для определенного количества денег, например для значений денег от 100к до 1 миллиона будет один хеш, для того чтобы получить от 1 миллиона до 10 миллионов нужен другой, но об этом расскажу в следующей статье. Думаю, пока информации хватит, если возникнут вопросы по таким структурам, то пишите в комментариях.    

partoftheworlD

partoftheworlD

 

[RTTI] Автоматизация дампа структур класса

Хехей для начала мне лень писать статью с картинками и прочим, кто поймет, тот молодец, а кто нет, значит не особо нужно. Ну в общем я когда-то показывал что можно сделать с динамической типизацией, а точнее с классами, так что мы будем использовать код сканера сигнатур, немного переписав его чтобы сканировать всю память компьютера, чтобы дампить все предметы которые используют выбранный нами класс. Для начала подготовим базу, берем свой сканер сигнатур, либо из паблика. 
Теперь нам необходимо изменить  код который указывает диапазон по которому мы будем брать страницы виртуальной памяти.
Он выглядит примерно так: while(offset < size) { VirtualQueryEx ... Для того, чтобы получить минимальный и максимальный адрес памяти будем использовать GetSystemInfo.
  SYSTEM_INFO si; GetSystemInfo(&si); auto seg_base = si.lpMinimumApplicationAddress; while (seg_base <= si.lpMaximumApplicationAddress) { if (VirtualQueryEx(hProcess, reinterpret_cast<DWORD64*>(seg_base), &mbi, sizeof(MEMORY_BASIC_INFORMATION))) ... Необходимо отфильтровать страницы, чтобы уменьшить время поиска значений и работы программы, для этого добавляем такую проверку.   if ((mbi.State == MEM_COMMIT) && (!(mbi.Protect & PAGE_GUARD)) || (!(mbi.Protect & PAGE_NOACCESS))) Теперь в цикле будем считывать адреса с шагом в 4 байта каждой оставшейся страницы памяти.
  for (auto i = 0; i < mbi.RegionSize; i+=4) { ... ReadProcessMemory(hProcess, reinterpret_cast<PBYTE*>(base + i), &wrBuff, sizeof(wrBuff), nullptr); Настало время для проверки значений, это можно сделать с помощью memcmp и загрузить результат в контейнер для удобного хранения. Выглядит это примерно так.     Из минусов такой способ относительно долгий, повысить скорость работы можно за счет многопоточности.
А из плюсов это дает нам возможность забить на поиски структур хранящих список вещей, списки оружия или же игроков. Т.е. нам достаточно сгенерировать сигнатуру указывающую на нужный нам класс, чтобы находить адреса всех структур, которые используют выбранный нами класс. Сделать ESP, Radar Hack или просто взломать список вещей в инвентаре не прикладывая усилий, вот что я люблю.

partoftheworlD

partoftheworlD

 

[Grand theft Auto Online v1.43] Stealth Money (20 миллионов в секунду) Update 2

Пока выложу видео т.к. я доволен проделанной работой и рад результату, как только пофиксят используемый метод для добавления денег, так напишу статью о том как находить скрытые структуры, как работать с ними и что это вообще такое.     Во-второй версии добавил возможность отнимать деньги.

partoftheworlD

partoftheworlD

Создаем мультихак, на примере игры Warface [2 часть]

Продолжаем создавать наш noflash хак. В этой части, мы восстановим классы и напишем код. Открываем Reclass x32 и создаем новый класс.     Далее, переименовываем название класса в SSystemGlobalEnvironment. Сейчас наш класс очень мал. Нарастите класс до смещения 0x90, используя панель модификации.     Переходим на смещение 0x88, жмем по зеленой стрелке, выбираем тип - Указатель.     Переименовываем указатель в p3DEngine. Ниже строчкой, переименовываем класс в I3DEngine. Спускаемся еще на строчку ниже. Создаём виртуальную таблицу, указав тип VTable.     Открываем и видим, что функций всего 9, а нам нужно 143. Смещение 572 / 4 т.к. 32 битный процесс. Если бы был 64 битный, то делили бы на 8. 143 это и есть наша функция SetPostEffectParam()     Наращиваем количество функций, как делали с классом. Переходим на 143 функцию, двойной клик, вписываем саму функцию. И очищаем лишнее в классе. Далее жмем "генерировать" класс.     Получаем готовый код класса, копируем в удобное место.     Открываем Visual Studio, создаем пустой проект, тип проекта "Библиотека DLL". Добавляем исходный файл main.cpp и заголовочный файл classes.h . В main.cpp подключаем  #include <windows.h> #include "classes.h"   Прописываем нашу функцию void no_flash(){ SSystemGlobalEnvironment* pEnv = (SSystemGlobalEnvironment*)(*(DWORD*)(0x18C23DC)); while (true){ if (!pEnv)continue; I3DEngine* p3DEngine = pEnv->p3DEngine; if (!p3DEngine)continue; p3DEngine->SetPostEffectParam("Flashbang_Time", 0, true); } }   В точке входа пишем CreateThread(0, 0, (LPTHREAD_START_ROUTINE)no_flash, 0, 0, 0);   Открываем файл classes.h и вставляем туда сгенерированный код из ReClass. В итоге файл classes.h будет выглядеть вот так     Собираем проект. Внедряем в игру. Готово.    

JustHack

JustHack

Создаем мультихак, на примере игры Warface [1 часть]

Итак, мы вооружились всеми нужными инструментами и поверхностным пониманием того, что будем делать. Теперь, можно приступать к самому интересному 👀 В этой части, перед нами стоит задача найти SSystemGlobalEnvironment и I3DEngine. Сразу скажу, что буду разжевывать максимально подробно, дабы избежать лишних вопросов (а как сдампить, а как открыть перекрестные ссылки и т.п.). Поэтому, не обижайтесь на меня, профи этого дела, кому это покажется слишком "жидким"😆   Запускаем игру, открываем PeTools и делаем полный дамп   Далее, запускаем IDA PRO и выбираем "новый проект"   Открываем наш дамп игры. Выбираем   IDA PRO, предложит указать расположение 3 библиотек. Выбираем место установки игры и нажимаем ОК.   Дождёмся, пока IDA проанализирует файл. Вы услышите звуковый сигнал, по окончании. Также, можно будет видеть надпись "idle" (в простое).   После окончания анализа, открываем список всех строк. Через меню View или нажав Shift+F12.   Жмем Ctrl+F и вводим "ai_CompatibilityMode"   Двойной клик по строке и оказываемся тут   Выделяем строку и жмем 'X', в открывшемся окне перекрестных ссылок, нажимаем ОК   Оказываемся тут   dword_18C23DC это и есть адрес нашего SSystemGlobalEnvironment = 0x18C23DC. Можете переименовать сразу (выделив и нажав 'N' ), можете оставить так. Кому как удобнее. Самое главное мы нашли. Теперь нам нужно найти  I3DEngine и SetPostEffectParam. Повторяем шаги с поиском SSystemGlobalEnvironment , только теперь вводим "Dof_Active" в строке поиска.     Нашли, выделили, перешли в окно перекрестных ссылок, выбираем первую и жмем ОК.   Попадаем сюда   Выделяем, жмем 'F5', для перехода к псевдокоду. Видим такую запись.    Выделяем смещение '+136', жмем ПКМ, переводим в HEX.   И получаем SSystemGlobalEnvironment + 0x88 это и есть смещение до I3DEngine
  В итоге имеем: SSystemGlobalEnvironment = 0x18C23DC SSystemGlobalEnvironment + 0x88 = I3DEngine   Продолжение следует...

JustHack

JustHack

Создаем мультихак, на примере игры Warface [Введение]

Привет всем, кто это читает, а может даже, пытается повторить)) По просьбам некоторых злодеев с форума, дискорда и ютуба, я буду пытаться написать цикл статей, по созданию мультихака через внутренние классы, на примере игры Варфейс. А может, я не буду вас мучать и ограничимся всего 1-2 публикациями. Всё зависит от вашего интереса и моего свободного времени. Все описанные действия, могут быть реализованы в какой-то степени и в других играх, на движке CryEngine3. Итак, начнем пожалуй с самого простого, а далее будем двигаться к более сложному. Здесь не будет объяснений, что такое дизассемлер, указатели, классы, интерфейсы, смещения и прочее. Если вы не знаете, что это, то вам придется самостоятельно восполнять эти пробелы. Движок CryEngine3, сделан на основе глобальных объектов. Глобальные объекты завёрнуты в одну структуру и являются указателями на абстрактные сущности, которые инициализируются в нужный момент, в нужном месте программы. Никаких дополнительных накладных расходов, никаких лишних надстроек, контроль за типом во время компиляции. CryEngine3 представляет собой достаточно старый проект, где все интерфейсы устаканились, а новое прикручивается подобно тому, что существует на данный момент. Поэтому нет необходимости придумывать дополнительные обёртки или способы работы с глобальными объектами. SSystemGlobalEnvironment - это основной базовый класс, где хранятся указатели на "стартовые классы". Примерное описание и содержание можно посмотреть на GitHub. Т.к. мы решили начать с самого простого, то на этом этапе, мы сделаем хак, который будет убирать эффект ослепления от светошумовых гранат (антислепа / noflash). Для этого, нам понадобится класс - I3DEngine; Он находится по такому пути SSystemGlobalEnvironment->I3DEngine. И вызвать метод SetPostEffectParam (ознакомиться)       Итак, наша задача найти адрес базового класса SSystemGlobalEnvironment, затем указатель на I3DEngine, восстановить класс и вызывать метод SetPostEffectParam, с нужными нам параметрами. Делов то 😆
Необходимый софт: Официальный SDK движка Visual Studio 2015+ PeTools IdaPro версии 6.6+ ReClass x32      Продолжение следует...

JustHack

JustHack

 

[JS] Старая творческая студия для youtube

Начал учить JS еще и из-за того, что меня ютуб начал раздражать перекидывая постоянно на новый дизайн творческой студии, даже если переходить на классический и писать матерные слова в окне фидбека. Так, что если я не один такой, то вот скрипт для Tampermonkey и его альтернатив под разные браузеры. Скрип во время загрузки страницы подменяет новый адрес кнопки ведущий на обновленный дизайн, на старый.   // ==UserScript== // @name Old youtube video manager // @version 0.1 // @author partoftheworlD // @include https://www.youtube.com/* // ==/UserScript== (function() { function replace_C() { var vm_button = document.querySelector("a.yt-uix-button.yt-masthead-picker-button.yt-masthead-picker-button-primary.yt-uix-sessionlink.yt-uix-button-default.yt-uix-button-size-default"); if(vm_button && vm_button.href.includes("dashboard") || vm_button.href.includes("studio")) { vm_button.href = "/my_videos?ar=1&o=U"; vm_button.text = "Творческая студия"; } } document.addEventListener('DOMContentLoaded', replace_C()); })();  

partoftheworlD

partoftheworlD

[IDA7] Function String Associate скрипт Update 0.05

Накидал небольшой скрипт, который выполняет тоже самое что и плагин FunctionStringAssociate, просто потому что, для новой версии плагин часто вылетает, нет кроссплатформенности, его нет под x86, для того чтобы был необходимо качать несколько библиотек, какие-то файлы и настраивать VS, никаких альтернатив не нашел, а также скрипт наверняка будет работать после следующих обновлений, даже если вдруг Hex-Rays снова решат обновить API. Сейчас это просто скрипт, в дальнейшем прилеплю меню и доступ из вкладки плагинов и увеличу скорость работы (как разберусь с новомодными модулями, которые нагуглю). Если кто-то будет пользоваться скриптом, то пожалуйста пишите, если возникнут какие-то проблем, а баги сразу на гите оформляйте.   Для чего нужен?     Плагин пригодится для беглого анализа всех функций в виртуальной таблице, при рассматривании скриптовых движков, может помочь найти всякие функции, относящиеся к обработке скриптов скриптовым движком игры, ну и конечно же помогает восстановить виртуальные таблицы из библиотеки игры с подписанными функциями MacOS в библиотеке Windows.   Как пользоваться? Кидаем в иду нужный нам файл, так же кидаем файл с плагином в папку plugins Заходим в пункт Edit/Plugins будет надпись FunctionStringassociate тыкаем на неё. Как только запустится скрипт в окне Output window будет надпись Launching По завершению анализа в том же окне получаем информацию о том сколько было просканировано функций и добавлено комментариев.     Возможно работоспособность может зависеть от степени анализа файла т.е. некая зависимость от количества анализированных функций относительно всех возможных Вроде бы все проверил, но так как скрипт писался всю ночь и день тестировался, то могут быть баги, которые я упустил.   Demo:     https://github.com/partoftheworlD/IDA7py_FunctionStringAssociate/     Обновления    

partoftheworlD

partoftheworlD

 

CE 6.8 Обзор нового инструмента поиска по структурам

1. Открываем trainme Dark Byte. 2. Проходим первый шаг (там нужно сделать One Hit Kill чит через прогресс бар, количество патронов тоже интересно поломать) 3. Так вот на Step2  ищем адрес здоровья нашего космического корабля. Ставим брейкпоинт на доступ, стреляем. Видим, три адреса и вот теперь новые функции в контекстном меню как на скриншоте   На "(1)-(2)" - вызываем контекстное меню выделив адрес своего корабля и добавляем его в группу1. Тоже самое делаем для красных адресов кораблей противников На "(2)" вызываем опцию сканирования и видим "(3)" На (3) выбираем скан по RAX или по другим значениям. Например, когда по RAX не нашли ничего.   Дальше видим окно и галку ставим "Only find matching groups" и сканим. Видим результат    Т.е. по +70 и другим смещениям можно сделать фильтр свой - чужой.  В общем замечательный инструмент для работы со структурами с заданием уровня сканирования по оффестам

MasterGH

MasterGH

[Hotline Miami] Бессмертие за счет отключения коллизии

Даже удивительно почему никто не сделал бессмертие для этой игры, ведь все достаточно просто. Раз у нас нет индикатора здоровья, значит необходимо найти триггер, который бы говорил "вот тебе дали по лицу и ты умер", а значит нам нужны *эффекты смерти и грустная музыка*. Если подумать из всего, от чего мы можем оттолкнуться стремясь к бессмертию, использовать сможет только координаты. Итак, план действий: Находим координаты Находим участок кода отвечающий за коллизию Делаем бессмертие за счет отключения коллизии, фильтруя для чего нам нужна коллизия, а для чего нет или переходим к пункту 4. Делаем бессмертие за счет нахождения триггера, изменяя условный переход, который больше не будет выводить сообщение о смерти и грустную музыку.   Бессмертие за счет отключения коллизии это самый простейший способ, но он для любителей поглазеть в структуры игрока, npc, стен, в поисках их уникальных ID, чтобы написать хороший фильтр. Бессмертие за счет изменения триггера это немного дольше, плюс могут быть проблемы, если игра использует скрипты, то скорее всего после отключения триггера и когда нам дадут по лицу мы получим софтлок и тут уже спасет только перезапуск.   Находим координаты, ставим бряк на доступ, необходимо немного побегать, чтобы отделить инструкции для передвижения от инструкций работающими с расчетом коллизии.     До красной линии это все инструкции которые работают с персонажем при движении, зеленым помечены инструкции, появляющиеся после того как нас ударили. Как только переходим по самой первой инструкции после удара, видим такой интересный код.     В общем здесь и происходит вся магия, загружаются значения, загружается коллизия предметов и npc, так же значения коллизии к пример стен статичны 1.875, немного пореверсив, можем написать скрипт, но чтобы он работал как бессмертие, его необходимо будет дописать с учетом состояния врага или же дистанции от врага, чтобы коллизия отключалась когда враг собирается нас атаковать. Это нужно для того чтобы игра не крашилась при переходе между локациями, т.к. при отключении коллизии игра не будет знать где можно спавнить игрока, а где нет.   А вот и функция расчета коллизии, входные данные для функции это размер коллизии предметов, текущие координаты npc/врага, а так же скорость:   Ну вот и все, небольшая демка и бонус будут чуть ниже, а так же скрины показывающие, что будет если изменять размер коллизий. По времени на взлом ушло около 20 минут, самое сложное было найти координаты. 😁 Если будет интерес, то напишу ещё одну статью в которой будем рассматривать бессмертие с помощью второго способа, а т.е. поиск триггера который бы говорил "вот тебе дали по лицу и ты умер", а значит нам нужны *эффекты смерти и грустная музыка*   Демо 1:     Демо 2:     Размер коллизий:          

partoftheworlD

partoftheworlD

[Radare 2] Статическая "отладка" кода

Всем радар, пацаны. Сегодня расскажу про эмуляцию кода или ESIL, это очень крутая штука позволяющая "отлаживать" код без отладки, но для начала небольшой экскурс.   Вы можете спросить, а какова цель ESIL, да и кому он нужен, когда есть отладчики? Ну, во-первых, не всегда нужный код срабатывает, когда нам это нужно, а ждать минуты, часы, дни, пока он сработает тоже не вариант. Во-вторых, при анализе малвари даже под виртуалкой опасно запускать исследуемую программу т.к. она может нанести вред хосту. В-третьих, иногда нет физического устройства со специфичной архитектурой.   Для того чтобы решить эти проблемы и придумали эмуляцию. Radare2 поддерживает для эмуляции множество архитектур, но не полный список инструкций, для некоторых из них (но это решается со временем), а только основные для облегчения нам с вами жизни, ну и конечно ESIL можно использовать в скриптах. Список поддерживаемых архитектур на 2015 год:   Итак, начнем. Для начала посмотрим на все команды для работы с ESIL.     Нам понадобятся только несколько из них. Для инициализации виртуальной машины используется команда:   Теперь необходимо установить начало, откуда начнем эмулировать код т.е. установить адрес в регистр EIP. Для примера накидал небольшую программку, которая что-то считает.   Выберем 0x1400010c7, как раз до этой инструкции загружается значение из буфера в eax.   Таким же образом загрузим в rax какое-нибудь значение, например 0x1234   И теперь необходимо установить триггер, чтобы эмуляция выполнялась только до этого адреса или условия. Триггер является неким подобием бряка во время отладки. Для триггера по адресу используем   теперь, как только RIP станет равным нашему адресу, то эмуляция остановится.   Для триггера с условием будем использовать другую команду к примеру, нам надо чтобы триггер сработал, когда eax станет больше 0x1234.   Конструкция выражений не самая удобная, но понятная, к примеру инструкция sub rsp, 8; будет выглядеть как "8, rsp, -"  т.е даже не зная опкодов каждый сможет понять, что делает инструкция на любой архитектуре.   Для наглядности посмотрим состояния регистров до эмуляции и после. До:   (Забыл сделать скрин по xmm регистрам, но там были одни нули)   После:   Так же можно эмулировать код пошагово с помощью команд   Ну думаю на этом все, надо будет испробовать такой способ в следующем видео для статического расчета указателей на разные статы игрока, типа здоровья или еще чего от базового адреса.

partoftheworlD

partoftheworlD

×

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.