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

Sergey99

Пользователи
  • Постов

    97
  • Зарегистрирован

  • Посещение

  • Победитель дней

    2

Весь контент Sergey99

  1. Теперь ясно, по такой логике скажем так для определенного патча игры можно не пытаться даже найти указатель. Достаточно находить адрес структуры, чтобы если например машин такси на карте 5 то и адресов CE найдет 5, можно даже сделать такой классный счётчик всех типов машин на карте. P.S. уже проверял да это работает
  2. То есть не важно DMA или нет если есть данные которые в exe файле то они по любому будут по статическим адресам расположены?
  3. Небольшое дополнение к вопросу: Выше я простенько описал последовательность того как расположены адреса памяти по СИшному, вот нормальный пример: *Car taxi; taxi->xCoordinate = X; taxi->yCoordinate = Y; taxi->ZCoordinate = Z; Из этого понятно, что Car - это та самая базовая структура, а такси это уже указатель или адрес начала машины такси грубо говоря. Так вот Car хранится в статике.
  4. Всем привет, решил поламать игрушку GTA 3 и в процессе возник вопрос. Пускай игра и использует DMA, НО к примеру я нашёл X координату (которая естественно лежит по динамическому адресу) и с помощью отладчика по смещением перешёл к базовому адресу структуры игрока скажем так, которая тоже лежит в динамических адресах, то первый адрес этой структуры указывает уже на статику, тоже самое с машинами и вертолётами. Я посидел и немножко подумал, а что если базовый адрес структуры будто игрока или машины указывает на скажем так базовую структуру, которая уже определяет что это за объект в игровом мире (игрок, машина, вертолёт и тд.) Опишу простенько по СИшному: car->taxi->xCoordinate; helicopter->policeHelicopter->xCoordinate; И соотвественно при поиске задом наперёд скажем так можно прийти к этой базовой структуре, но вот в чём дилема, игра то у нас DMA, а адрес статический. Вопрос, почему в играх с DMA всё же есть статические адреса? P.S. при поиске указателей мы тоже в конце получаем статику, что собственно изначально но мысль о вопросе и навело.
  5. Разобрался как работают функции рисования примитивов в этих библиотечках. Всё очень просто, оказывается, что так как функция вызывается очень много раз, практически каждый кадр в игре, то и соответственно рисует она каждый кадр и каждый кадр количество примитивов, которые необходимо нарисовать может отличаться. К примеру в первый кадр рисуется мир, а во второй рисуется картинка с камеры игрока, через которую мы и видим мир игры и штука вся в том, что количество примитивов для рисования картинки с камеры нужно меньше чем для рисования мира (мир - от 100 примитивов, камера от 2 до ~10 примитивов).
  6. Такая же штучка и в D3D работает к примеру в 9 версии, я пробовал, проверяя значение параметра primCount метода DrawIndexedPrimitive, похоже что функция не рендерит всё сразу а как то по очереди обрабатывает каждый примитив.
  7. Вот в функции перехвата я проверяю параметр count, который пришёл в функцию glDrawElements, он хранит количество примитивов для рендера и вот по идее рисование линиями должно работать для всех примитивов так как условие выполняется. К примеру если count равен 100 (то есть в функцию пришёл аргумент count со значением 100 то функция не будет рисовать линиями так как условие count > 260, а вот если в функцию придёт 261 то по идее он должен всё нарисовать линиями а получается только один примитив так как 261 > 260. Это то что нужно но сам алгоритм не понятен. Так как по логике условие сработало и выполняется glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); (по идее для всех примитивов)
  8. Решил проблемку, как оказалось перехватывать нужно было не glBegin а функцию именно для рисования как в том же Direct3D. Функция называется glDrawElements и рисует примитивы из массива, который приходит четвёртым аргументом. Конечно если почитать справочки от Microsoft и от Khronos, то из описания параметром понятно что где лежит, а вот если почитать справочку [здесь] по этой функции, то немножко запутаться можно в описании четвёртого параметра ну да ладно. Всё рисуется всё работает, проблема была в том, что как оказалось сам экран или камера через которую мы смотрим на мир игры тоже является примитивом и если мы отключаем рисование для него то он соответственно не будет обновляться и будет якобы висеть с одним изображением. Проблема решена через проверку сколько примитивов рисует функция (второй параметр): При таком раскладе функция будет рисовать линиями только если число примитивов больше 260, а если нет, то рисовать сплошной заливкой. Вопрос теперь в том как сама функция это понимает? Ведь это хук и выполняется также в потоке или в цикле в игре. Эта функция вызывается и ей приходят аргументы и вот пришли ей на пример 261 примитив, то она рисует только один примитив линиями, хотя по логике должна все ведь условие стоит на это. Как такое происходит? Если посмотреть справочку то можно понять что второй параметр это число примитивов для рисования (то есть они все рисуются в этой функции), а условие будто выполняется для конкретного диапазона от 260 как так? Вот результат стараний, темновато но думаю видно:
  9. Функция wglSwapBuffers принимает один параметр HDC контекст устройства, а wglSwapLayerBuffers два параметра, контекст HDC и собственно для чего выполнить смену буферов будто плоскости или overlay. Сами функции разные хотя бы потому что принимают разное число аргументов и разные имена имеют.
  10. Да действительно между glBegin и glEnd обычно указывают вершины, по типу такого: glBegin(GL_QUADS); glVertex3f(x, y, z); glVertex3f(x, y, z); glVertex3f(x, y, z); glVertex3f(x, y, z); glEnd(); Тут указываются вершины, так как в аргументах glBegin пришёл GL_QUADS то и вершин соответственно 4 По поводу перехватов, я пытался перехватить wglSwapBuffers из той же библиотеки opengl32.dll, читал на зарубежных форумах, там её используют но для рисования всяких там квадратиков и менюшек на эране. Но результат практически тот же что и при перехвате glBegin. К тому же очень странно но справочки по wglSwapBuffers я не нашёл однако она как бы работает и в opengl32.dll как бы есть. Вы предлагаете искать через отладку а в каком смысле? Я же DLL инжектирую, а VS не позволяет отлаживать так как DLL это не исполняемый файл. И разумеется функция GetProcAddress не найдёт больше адресов функции glBegin так как в библиотеке opengl32.dll вроде как не может быть больше таких функций, она же как бы одна и зачем там больше. glBeginAddress = (DWORD)GetProcAddress(Moduleandle, "glBegin");
  11. Если я пытаюсь очистить буфер экрана и буфер глубины к примеру зелёным цветом без рисования линиями, то оно как бы работает, но вот так вот: Код: OpenGL Microsoft docs - glColorMask, glClearColor, glClear glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE); glClearColor(0.0, 1.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); И пример после очистки зелёным цветом: Примечательно то что что если я буду рисовать линиями GL_LINE то экран будет весь зелёный будто весь очищается цветом. Также переменная glBeginAddress хранит адрес функции которую собственно я и перехватываю, вот тут даже jmp на инъекцию есть так как DLL уже загружена:
  12. Всем привет, решил я написать простенький хук для OpengGL. Игрушка, которую я хочу ломать использует как раз OpenGL, это можно понять если присоединиться через Cheat Engine к процессу игры и вызвать функцию для перечисления всех DLL загруженных в процесс (Enumerate DLL's). Игрушка использует opengl32.dll соответственно и ломать я буду OpengGL. И так вот небольшой кусок кода для функции GetOpenGLFunctions, весь код написан на C++, он естественно закоментирован на английском языке так как английский это круто и по хорошему код нужно коментить: Эта функция получает адрес функции glBegin из модуля opengl32.dll, который подргужен самой игрой и сохраняет его в переменную glBeginAddress. После этого вызывается функция HookOpenGLFunctions: По сути это инъекция кода то есть jmp [address] вместо оригинальной функции glBegin. Я не использую Detours от Microsoft потому что вижу в них смысл если требуется перехват функции в x64 играх, так как там способ перехвата и инъекции кода немножко отличается от x86. И вот собственно сам код инъекции: Тут происходит восстановление байт оригинальной функции, чтобы она смогла выполнится в конце хука, потом идёт проверка включён ли чит и вызов функции glPolygonMode, котоая устанавливает режим отрисовки полигонов грубо говоря. Соответственно GL_FRONT_AND_BACK - полигоны которые рисуются спереди и сзади, GL_LINE - отрисовка линиями и GL_FILL - полная заливка полигонов текстурами. Ну а дальше вызов оригинальной функции glBegin и восстановление байт для инъекции и всё это крутится в цикле. Вот тут ссылки на документацию по функциям только не с сайта Microsoft а уже с сайта OpenGL документации: glBegin, glPolygonMode Уж не знаю кому как удобнее ну вот сайтик с документацией от разработчика: Khronos В чём может быть проблема? Всё работает только вот при отрисовке линиями игра почему отображает мне предыдущий кадр в цикле, как будто изображение заморожено, вот пример до: И вот как это выглядит после хука: Тут видно наверное плохо но изображение как бы замараживается и не обновляется (даже сохраняется и рисуется предыдущая позиция курсора), но в момент выключения на долю секунды можно заметить отрисовку только линиями как здесь (пример из d3d9 игры):
  13. Всё нашёл, я создал топик на иностранном форуме там мы вместе решили вопрос, так как я понимаю принцип работы матрицы и знаю технический английски . Я готовлю детальный разбор по этой теме для этого топика или выведу в отдельный гайдик, не знаю в общем.
  14. И так тоже, но разве это не через инъекции кода делается, например, все хаки для Phasmophobia, которые существуют они все поголовно являются .dll файлами, которые инжектятся внутрь. А моя задача состоит в том чтобы получить координаты на экране, зная координаты в 3D и видовую матрицу (чтобы не использовать инъекции когда всегда). И да, я знаю что через Mono тоже можно инжектиться. Хех ну да, Windows бывает капризная Или же ты имеешь ввиду вызывать через движк Lua в Cheat Engine или Auto Assembler? Просто конкретно как вызывать методы через Auto Assembler не знаю, а вот документацию по CE Lua успел почитать.
  15. Получи координаты центра твоего второго окна путём деления ширины и высоты на 2. К примеру для Windows Form .NET C#: System.Int32 CenterX = this.Width / 2; System.Int32 CenterY = this.Height / 2; //Где "this" - указатель на текущий экземляр класса, описывающий твою форму //System.Int32 - структура описывающая тип данных integer Найди свои координаты, потом найди расстояния от своих до координат другого объекта путём вычитания значений каждой оси и эту разность прибавляй к переменным CenterX, CenterY, таким образом центр радара - это "ты" грубо говоря. System.Int32 PosX = CenterX + Convert.ToInt32(/*разность координат по оси X*/); System.Int32 PosY = CenterY + Convert.ToInt32(/*разность координат по оси Y*/); //Convert.ToInt32 - потому что на Windows Form позиция X, Y является целым числом особенно если использовать структуру Point //Далее можно спользовать PosX и PosY для рисования объекта на "радаре"
  16. В общем спустя много времени я нашёл структуру очень похожу на видовую матрицу, однако есть одно отличие от тех, скриншоты которых были выше по теме: - Синий прямоугольник (предположительно видовая матрица), зелёный - координаты (меняются когда я передвигаюсь, мышь и соответственно камера не двигается). В общем всё как для Cod:MW2 и Amnesia. А вот есть ещё оранжевый прямоугольник (поверх зелёного следовательно затрагивает зелёный). Значения в нём изменяются когда я хожу только влево и вправо (клавиши A, D). Это очень сильно похоже на поведение когда я прыгаю в Amnesia и CoD:MW2, так как там меняется лишь одна координата Z, а тут видимо эту особенность переняла другая координата, ведь если я с клавишами A, D буду ещё и камеру двигать то остальные координаты тоже начнут меняться. Похоже здесь каждый элемент матрицы разбит на два значения, тогда вопрос: такое разве возможно? И как тогда мне конвертировать координаты объекта в экранные координаты с такой видовой матрицей? Если каждый элемента матрицы действительно разбит на 2 значения, как тогда одномерный массив (32 элемента для такой матрицы 4x8 = 32) использовать в моей функции WorldToScreen()? Нужно складывать эти два значения или как-то по другому? Решил через Mono попробовать, как раз нашёл метод класса Camera -> Camera.WorldToScreenPoint, который как раз таки должен использовать видовую матрицу для преобразования координат из 3D в 2D, вот только как найти эту самую матрицу, которую использует эта функция. Нужно регистры проверять или адреса (если использовать средства Cheat Engine)? Потому что, по моему мнению, метод того же класса Camera.GetStereoViewMatrix, не совсем подходит хотя, возможно, я ошибаюсь.
  17. Я тоже думаю что матрица представлена в памяти как-то "не по обычному". Но вряд ли думаю что байты будут представлены так как ты описал выше (6 значений). Так как в любой игре всё это должно храниться в виде матрицы (как я читал) иначе от куда функция WorlsToScreen() будет брать все три вектора + 4 вектор (позиция), ведь каждый вектор это 4 байта => матрица 4x4 = 16 байт.
  18. И да, Cheat Engine даже 7.0 не предлагает Dissest Mono, а отладчик OllyDbg не может присоединиться к процессу даже. Учитывая что в Cheat Engine если нашёл адрес с координатой и потом ищешь инструкцию, который пишет туда, то из Memory Viewer'а на ту же инструкцию тыкаешь правой кнопкой и хочешь найти к чему получает доступ эта инструкция, то он тебе выдает либо ничего либо какой-то левый адрес. Похоже это игра не до конца закончена оно и понятно, ранний доступ всё-таки, но всё равно даже так она как-то не так работает (это я про проблему описанную выше).
  19. Да, как раз на C# уже написал алгоритм для записи в одномерный массив column-major матрицы, таким же образом чтобы в обработку WorldToScreen() мой массив приходил таким же упорядоченным как и в других играх. Надеюсь что для column-major матрицы функцию WorldToScreen() не придётся переписывать.
  20. Потому что я её рисую и перерисовываю каждый кадр + Bandicam пишет параллельно, потом упрощу немного задачу.
  21. Ищу я видовую матрицу для игрока, вот как он смотрит на 3D мир (вид от первого лица, никакого геймплея через "камеру" нет, просто грубо говоря глаза игрока), а вообще выше по теме было целых два видео где я её использую так что думаю очевидно что я ищу в этой игре.
  22. А может быть такое что байты видовой матрица перевёрнуты? то есть порядок столбцов тот же, а вот строки снизу вверх?
  23. Да, идея хорошая, учитывая то что игра на Unity с использование скриптинга на C#, но не каждая же игра написана на таких общедоступных движках, к примеру CoD:MW2 была написана на C++ и "IW Engine" (движок разработчиков - они сами его написали и сами же модернизировали).
×
×
  • Создать...

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

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