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

keng

Ветераны
  • Постов

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

  • Посещение

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

    55

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

  1. [terminus]Я попробую по-другому текст структурировать (тот пост писал в спешке - времени мало было), а заодно с размером шрифта поиграюсь. Сам сижу с этим шрифтом по 12 часов в сутки на работе и ничего. Хотя, возможно, я просто привык.[/terminus]
  2. [terminus]Почему нужно использовать стандартные шрифты только на этом сайте?[/terminus]
  3. [terminus]Я люблю шрифты, которыми пишу код и документацию. А условие в if всегда приводится к булевому типу, так что если в теле условия стоит просто переменная, то при проходе она проверяется на 0. Вернет, соответственно, False, если там 0, и True во всех остальных случаях.[/terminus]
  4. Привет!Тебе нужны координаты только двум осям (карта ведь двухмерная), а так же уметь проецировать эти координаты на картинку. Для этого нужно почитать про видовую матрицу (view matrix) и зачем она нужна. Почитать можно, например, [тут]. Суть в том, что тебе нужно перевести координаты игрового объекта в Y-проекции (вид сверху) на плоскость, плюс учесть масштаб. Последнее, думаю, подбирается экспериментально - или можно взять размер объекта и отношение его к размеру карты.
  5. [terminus]Думаю, понадобится следующее. Для примера буду считать, что брони у крипов не бывает, промахов у героя - тоже. 0. Находим здоровье одного крипа методом поиска точного значения. 1. Находим указатель на коллекцию всех крипов на карте на данный момент. 2. Находим адрес, хранящий количество крипов на карте на данный момент. 3. Находим текущий урон, наносимый атаками нашего героя. 4. В цикле бежим по коллекции крипов и проверяем, что: - Здоровье крипа > 0. - Здоровье крипа <= текущему урону нашего героя. Если п. 4 выполняется, то подсвечиваем крипа тем или иным образом (GDI, DirectX, как-то еще - без разницы). Задачу можно оптимизировать путем ограничения цикла только до тех крипов, которые находятся в поле зрения от героя. Или даже в радиусе его атаки.[/terminus]
  6. [terminus]Я когда-то сам не знал ответ на этот вопрос. PS: Лет до 10. [/terminus]
  7. Привет! 1. Что означает конструкция if () {}: if - это условный оператор. Все, что идет в круглых скобках - это тело условия. Оно подчиняется законам булевой алгебры и результат всегда должен приводиться к bool, оно же Boolean, оно же (удивительно, но факт!) int. Значения может быть всего два - ноль и не ноль. Работает оно примерно так: if ( 1 == 1 ); /* вернет True, или 1, потому что единица равна единице */ if ( 1 != 1 ); /* вернет False, или 0, потому что "не равна ли единица единице" - это ложь */ if ( 2*2 == 4 ) /* вернет True, потому что 2*2 действительно равно 4 */ Бывает: равно (1 == 1) не равно (1 != 0) больше (1 > 0) меньше (0 < 1) больше или равно (2 >= 1) меньше или равно (1 <= 2) Не одним if едины, еще есть else. Работает он следующим образом: if (условие) { действие А } else { действие Б } Если условие истинно (возвращает True), то проваливается в действие А, иначе (если условие ложно и возвращает False) - в действие Б. PS: Внутри условия еще действует дискретная математика - это всякие веселые штучки вроде &&, || и другие. Для начала знать нужно только эти две веселые штучки. Поясняю подробнее. if ( (1 == 1) && (2 == 2) ) /* Если условие 1 И условие 2 истинны, то проваливаемся внутрь, иначе - идем дальше или в ветку else. && - значит, что оба (все) условия должны выполниться */ if ( (a != c) || (b == 0) ) /* Если условие 1 ИЛИ условие 2 истинны, то см. выше. || - значит что хоть одно условие должно выполниться */ 2. Можно ли создать отдельный указатель имени функции? Да, можно. По большому секрету скажу, что имя функции - это указатель на нее. Синтаксически я могу и ошибиться, но проверил этот код в gcc: #include <stdio.h> int foo() { return 0; } int main() { int (*bar)() = &foo; return bar(); } 3. Поиск в d3d по сигнатуре байт. DirectX - это набор COM-объектов. За подробностями - в [википедию], а я объясню на пальцах. Это чудо-технология от Microsoft, позволяющая вынести некоторый код, лежащий чаще всего в DLL, практически на уровень всей системы. Т.е. Это очень абстрактная фигня - пользоваться можно, а сделать себе хорошую такую копию, которую можно пощупать - нельзя. Ты можешь подгрузить себе нужную dll и попросить видеокарту что-нибудь нарисовать, но сделать "объект" и приказывать ему, как объекту класса - не получится. Так как вся высокоуровневая фигня в любом случае упирается в указатели, то выглядит это как указатель на указатель на таблицу указателей. Да, это не опечатка. Таблица эта висит где-то в виртуальном адресном пространстве игры и дергается вский раз, когда игра хочет что-нибудь нарисовать. Для определенных версий directx(?) и для определенных игр(?) эта таблица ищется при помощи сигнатуры байт, потому что это простое и быстрое решение. Дальше в таблице ищется смещение до нужной функции, указатель по этому смещению меняется на свой - вуаля, hook готов. 4. Как сделать code-injection на С++. Сразу предупрежу, что не буду приводить код, а только лишь опишу алгоритм. Во-первых, неужели тебе никогда не было любопытно, как инъекция выглядит в СЕ? Напомню: 0x11223344 - адрес для инъекции. alloc(1024) a; a: nop nop nop ret 0x11223344: jmp a nop Это - типичная секция [ENABLE], пусть и в псевдокоде. Я когда-то рисовал для одного нашего не очень опытного любителя поломать NFS картинки, но сейчас их под рукой нету. В общем, что происходит, когда мы нажимаем на кнопку [ENABLE]? А вот что: 0. По адресу "a" (который в CE обозначается буквами чисто для удобства) выделяется кусок памяти в 1024 байта. 1. В этот кусок записывается ассемблерный код инъекции. В нашем случае - nop nop nop jmp 0x11223344+5. 2. По адресу 0x11223344 записывается команда "jmp a nop", потому что jmp+адрес - это 4 байта, а нам нужно 5 для сохранения целостности кода. Потому что все прыжки по коду - относительные, т.е. по строгим смещениям. 3. Готово! Вы великолепны! Когда игра добегает до адрес 0x11223344, она там видит команду безусловного перехода. Послушно прыгает, выполняет нашу инъекцию, а затем прыгает обратно (0x11223344+5 - сразу после jmp a nop). Вопрос, как нам такую штуку реализовать программно? Рассмотрим случай, что мы не внутри адресного пространства dll. У нас есть адрес, куда нужно сделать инъекцию, и код. Делаем: 0. Получаем все нужные права через OpenProcess и VirtualProtectEx. 1. Выделяем себе кусок памяти в адресном пространстве игры через VirtualAllocEx. 2. Через WriteProcessMemory записываем в него код инъекции (в 16-ричной системе счисления. На конце - jmp. Все ассемблерные команды - в опкодах, т.е. как бы после компиляции). 3. Берем адрес для инъекции. Берем место, куда записали код. Нам нужно сделать относительный прыжок, верно? Отнимаем один адрес из другого. Все время путаю, какой откуда, но это можно проверить в отладчике. 4. Разворачиваем задом наперед этот адрес (в 16-ричном представлении!), сохраняем куда-нибудь. 5. Берем адрес, куда записали код инъекции + длину инъекции в байтах + 4. Отнимаем этот адрес из адреса для инъекции + еще пять байт. Потому что сначала мы прыгаем из игры в наш код, а потом из нашего кода обратно в игровой. +5, чтобы не прыгнуть на то место, с которого прыгали изначально - прыгать нужно _после_ этого места. 6. Записываем через тот же WriteProcessMemory адрес в конец кода инъекции (чтобы было jmp + адрес). 7. Записываем в место инъеции "jmp + смещение для кода инъекции + nop". 8. Готово! Все это - в идеальном случае, т.к. у нас может или не быть места под jmp + смещение (слишком короткая команда) - в этом случае ее нужно будет перенести внутрь кода инъекции, или наоборот - команда слишком длинная, так что для сохранения порядка байт нужно будет после jmp + смещение подставить большее количество nop. Я это первый раз давным-давно делал на ассемблере - сломал камаз граблей и убил пару недель времени. Лучше всего наблюдать за процессом через отладчик (рекомендую OllyDbg) и запастись не игрой, а программой, которая маленькая и быстро запускается. Ибо вылетать она будет часто. 5. Как правильно писать .h-файлы. Тут я помочь мало чем смогу - разве что отослать к прочтению какого-нибудь учебника по Си (не по С++), а так же документации по самим хидерам и по стандартным хидерам, которые подсовывает в проект visual studio. 6. Почему хуки через сигнатуры можно использовать в игре А, а в игре Б - нельзя? Как сделать, чтобы было можно? На этот вопрос я уже частично ответил в предыдущем вопросе по этой теме, если коротко - сигнатуры отличаются. Как сделать, чтобы было можно - трудно, нудно и долго, потому что очень много совершенно вырвиглазной отладки. У меня ушла пара месяцев на первую сколько-нибудь стабильно работающую версию под DX9. Сейчас она все еще сыровата, но доделывать уже работающее - гораздо проще и приятнее, чем ковырять с нуля. Если коротко - я создаю временный dx-интерфейс для невидимого окна размером 1х1 пиксель, сохраняю его адрес и потом ищу такой же в куче (heap) целевого приложения. Для этого никакие сигнатуры не нужны и это работает всегда, потому что версия dx - единая в рамках компьютера, на котором запускается мой сканер и приложение. Докрутить dx10-11-12 (когда последний выйдет) и OpenGL - дело времени, которого толком нет. Одна проблема - подмена указателей на функции работает довольно хреново, сплайсинг тоже - приходится постоянно мониторить состояние каждой функции и ежели что не так - чинить, пока игра не обрушилась. Примерно такой же метод используется в Steam и Fraps. Как результат - я могу рисовать в любой игре и что захочу.
  8. Дык тогда разницы никакой и не будет - изучить нужно только синтаксис. Найди, как в дельфях вызывать WinAPI - все, вопрос решен. Для этого не нужны уроки, нужно 3 минуты погуглить.
  9. Какая разница, на чем именно писать, если для реализации трейнера необходим доступ только к WinAPI? Если вы не можете сами для себя внятно и четко ответить, зачем нужна ООП-парадигма в движке трейнера - не нужен вам C++. Технология выбирается под задачу, а не наоборот.
  10. Привет! String - строка. Strings - строки.
  11. Gitlab - это по сути веб-сайт, который дополняет систему контроля версий по имени git. Последняя нужна для того, чтобы организованно и упорядоченно хранить исходный код. Можно создавать проекты (репозитории), хранить в них файлы с исходным кодом, историю их изменений и все такое. Gitlab просто добавляет к этому веб-обертку - пользователи, страницы проектов, комментарии и так далее, все это можно посмотреть в браузере. Про системы контроля версий можно подробнее почитать в [википедии].
  12. keng

    OLLY.Tools 2014

    Ну так ведь и не все нынешние игры выпускаются исключительно под x86_64.
  13. Мне интересно, как оно у тебя вообще скомпилировалось, если DllMain ничего не возвращает. Для чего, кстати, тебе потоки понадобились? CreateThread, насколько я помню, в последний свой аргумент при вызове возвращает идентификатор потока, а сама фунция - хэндл. Во-первых, с этими данными можно управлять потоком(-ами), а во-вторых - проверить, корректно ли он(и) запустились.
  14. Я остановился на 15-й, дальше пришлось все-таки сесть за работу, а не за игры.
  15. Мы вчера сошлись на идее о глобальной очереди нажатых кнопок на этаже, лифты же в свободное время проверяют состояние этой очереди и исходя из своего текущего графика движения (направления и загруженности) и расстояния до этажа решали, будут ли останавливаться и забирать пассажира. Алгоритм работает довольно неплохо, но из-за особенностей JS иногда тупит. Вообще, игра - отличная демонстрация возможностей и принципов работы языка как такового.
  16. А мне сегодня весь день работать, ммм, нужно было.
  17. Pinvoke - он для C#. Идешь в гугл, вбиваешь "имяфункции С++", читаешь, видишь внизу страницы .h-файл, нужный для работы функции. Подключил его - и вызывай, сколько захочется. Собственно, на главной странице сайта написано:
  18. Наткнулись буквально сегодня с утра вместе с коллегами. Краткая суть - даны этажи, лифты и API (Application Programming Interface, набор функций, если коротко) для управления лифтами. Код - на javascript, но интуитивно-понятен, есть документация и примеры. Очень затягивает! Вот [ссылка].
  19. keng

    Чат

    Так в сообщении ведь все написано.
  20. По поводу второго пункта - в MSVS давно есть поддержка типа "общих" вызовов функций (без аффикса A или W), а нужная функция выбирается исходя из настроек проекта. Зачем так сделано - хз, да и я уже давно на вижле не пишу, но факт. Закрывать хэндлы и освобождать память, которая выделилась - таки полезная привычка, ибо не придется помнить, в потоке твой код или еще где-нибудь. Как правильно сказал кодер, современные AV - параноики и подозревают любые бинарники сколько-нибудь нестандартного вида - маленького размера, с собственным заголовком\загрузчиком, с "кривыми" секциями, без импорта, использующие функции работы с памятью. От всего этого избавляет пометка "false positive" в nfo, но это - уже другая история. Автор, я не зря спросил, в чем особенность твоего будущего инжектора. Ты ответил, что сформулировать идею полностью не можешь. Это плохо, так как если не можешь сформулировать полностью идею - реализовать тоже не сможешь, а пытаться реализовывать "по ходу" - так себе затея.
  21. Для отладочных целей текст можно выводить не на экран, а в файл. В чем такая офигенная особенность, кроме того что dll будет лежать в ресурсах?
  22. Кодер прав - надо понять хотя бы на уровне абстракций, как игры работают вообще. Написать что-нибудь простенькое, в духе крестики-нолики - тетрис - танчики - арканоид (в порядке возрастания сложности). В итоге будут развиваться две такие офигенные штуки, как способность мыслить как программист и, что еще важнее, как программист в области разработки копьютерных игр. Постепенно многие вещи встанут на место, причем очень намертво. Я вот когда начал изучать 3D-графику и пытаться писать по ней уроки - я тоже ни черта не знал толком, так что сидел и писал собственные приложения, которые рисуют квадратики, примитивно так. Для конкретно реверсинга еще неплохо на уровне чтения знать ассемблер - то есть писать на нем не обязательно, а вот читать и понимать происходящее в коде - это да, важно и полезно.
  23. Зачем давать предупреждения во флудилке? :с
×
×
  • Создать...

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

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