-
Постов
410 -
Зарегистрирован
-
Посещение
-
Победитель дней
16
Тип контента
Профили
Форумы
Загрузки
Блоги
Весь контент Antonshka
-
Снова возник вопрос для следующей задачи, - нужно сделать чтобы одна логическая единица была равна 1/16 дюйма. Вот решение из книги Petzold, где он сам эту задачу и ставит и решает, Вот выписка касательно этого решения Мой монитор по оси Х по результату HORZSIZE имеет 598 миллиметров. Переводя 598 в дюймы (598 / 25.4) получается 23.543 дюйма. И вот собственно сам вопрос, - почему нужно именно умножать, 23.543 на 16? А не делить? На 16, я так понимаю, потому что 1/16. 23.543 х 16 = 376,688 GetDeviceCaps(hdc, HORZRES) возвращает 1920 (пикселей по оси Х, ширина). Следовательно получается отношение 376 к 1920 , а именно 1920 / 376 = 5.106 (одна логическая единица будет равна 1/16 дюйма (1.587 миллиметра), или 5.106 пикселя, если в пикселях). Почему умножение на 16, как это работает? С одной стороны отношения, 23.543 дюйма умноженные на 16, с другой стороны, 1920 пикселей. Отношение дюймов к пикселям?
-
Разобрался. Спасибо книге от Petzold. Ну и заморочка. Если кто-то так же затрудняется понять, то вот: Окно - это клиентская область приложения, то есть внешний вид программки без рамки и заголовка. Область вывода - тоже клиентская область приложения, то есть внешний вид программки без рамки и заголовка. (Область вывода может быть и клиентской областю с рамкой и заголовком, и даже всем экраном). Разница лишь в том у них, что позиция курсора, например наведенного на какое-нибудь место клиентской области, в случае "Области вывода" измеряется в пикселах, а в случае когда мы говорим и имеем в виду "Окно", то измеряется в логических единицах. А логическая единица может быть равна как одному пикселу, тогда позиции курсора в обоих терминах (Окно и Область вывода) измеряются в пикселах, так и нескольким пикселам, если самому предварительно это определить. Сейчас читаю книгу Щупака, но чувствую теперь, что в книге Petzold материал преподается более подробно и доходчиво. Так что советую книгу Petzold . Хотя я и ту и эту намерен прочитать.
- 3 ответа
-
- 2
-
-
-
Привет, кто-нибудь, скажите мне, что в GDI подразумевается под Window и Viewport. Под понятиями "Окно" и "Область вывода". Я прочитал в книге Щупака, затем на MSDN, затем на нескольких сайтах, затем у Petzold, сейчас буду у Фень Юань. Не понимаю! Неужели трудно им сказать, к примеру, Окно - это сама программа, ее габариты, а Область вывода - это весь рабочий стол. Также приложить нормальную картинку где это изображено. Нет же, пишут пишут, а толку. Никак не зайдет тема о Режиме отображения и системах координат, с их физическими и логическими единицами. На пальцах так сказать, объясните, что это все. Или на картинке, где это все обозначается.
- 3 ответа
-
- 1
-
-
То что мы используем функции нашей DLL и используем их в чужом адресном пространстве, - это понятно. Для того собственно мы их и пишем, чтобы их использовать. Мне не понятно как происходит взаимодействие инструкций игры с функциями в библиотеке. Сам механизм. Вот есть байты DLL в памяти игры, мы их туда загрузили, (по сути просто скопировали, как я понимаю). Есть также байты инструкций игры. И то и это представляют из себя функции. Как же теперь оживить нашу DLL? Что нужно сделать чтобы функции в DLL заработали, и заработали каждая для своей определенной игровой функции/инструкции. Я смотрел у тебя в профиле, видел только трейнеры. С удовольствием и интересом посмотрю.
-
Я полагал что загрузка DLL - это простое копирование её байт в память игры. Затем навешивание каким-то образом потоков на нее. Также связывание определенных инструкций игры с определенными функциями в DLL. А в функциях DLL идет каким-то образом получение значений из регистров, с дальнейшим их использованием и применением обратно. Вот мое представление об схеме работы internal чита, при DLL. Моя картина в голове. Говорю же, мне нужно общее представление об ее работе, на пальцах так сказать. Я же понятия не имею, как там все устроено.
-
Посмотрю сейчас. Размер шрифта в первом видео, где стрим, для меня самый комфортный. Ни мелкий, ни крупный, самое-то. Я посмотрел твои трейнеры, - у тебя DLL отдельно от файла EXE. Не пробовал помещать DLL в ресурсы EXE, а затем просто оттуда считывать её байты в память игры? Поделись источниками, в которых есть что-нибудь действительно полезное про DLL и хуки. Для меня самое сложное в изучении программирования, - это найти нормальный источник. Где нет "воды", где не обсасывают одну мысль десять минут, где автор действительно объясняет, а не показывает лишь то что он это знает и умеет. Таких пруд пруди в инете. И ты сидишь и тратишь время, как идиот. Книги, ясное дело, самый лучший вариант. Я и намеревался почитать про DLL. Но сперва хотел понять общую картину.
-
Привет всем, Вчера смотрел видео на канале Gamehacklab. Про написание трейнера на С++. (Замечательное видео, за исключением того что Автор зачем то в последствии уменьшил шрифт. Тяжело стало смотреть, у меня же зрение не очень. Но ничего, досмотрел. Вообще, не понимаю авторов подобных роликов, ну неужели не понимают они что тяжело людям смотреть. Выставят мизерный шрифт и давай записывать.) В видео, @Xipho выделил память и записал уже готовые байты новой и старой инструкции. Это понятно. Но в видео ничего не говорится к сожалению про метод "internal" чит. Так как тема на "external". Подскажите, какова общая схема создания и использования трейнера/приложения, который работает по средствам написанной dll. Как перенаправить потоки от оригинальных инструкций в соответствующие им функции в dll. Как получить данные из регистров и использовать их опять же в функциях dll. Есть ли разница в получении данных из регистров в 32 и 64 битных версиях. Хочу иметь общее представление, общую картину, план, как это реализовывается. Можно ли например написать DLL в которой будет основной код для инструкций игры, а также код для создания окна, кнопочек, менюшек, в общем разных контролов, затем написать небольшой EXE, в ресурсах которого будет эта DLL. То есть приложение/трейнер будет состоять всего из EXE файла, внутри которого будет нужная DLL. Затем, при запуске EXE, методом описанным в самой этой EXE, берется из ресурсов DLL, копируется напрямую в память игры, делаются хуки, и готово. Создается наверно отдельный поток на управление окном и контролами. В общем вопросы может быть глупые, но у меня пока просто нет понимания общей картины. Мне бы только понять план, о мелочах я читаю на MSDN.
-
Я в свое время делал что-то подобное. Мне нужно было сохранить часть выделенной памяти в СЕ в файл в момент выполнения определенной игровой инструкции. Делал я это используя WinApi. Игра была 64 битная, поэтому было достаточно просто. Вот большая часть кода. Я не помню сейчас уже что там и к чему в точности. Не хочется вспоминать. Но из некоторых комментарием должно быть понятно. Есть еще часть скрипта для считывания данных из файла в память, но она здесь не нужна. Как написал @Xipho, нужно лишь прочитать про соглашения, про правила передачи аргументов.
-
fbstp как раз таки преобразовывает Hex в String. Мне нужно наоборот, - String в Hex. Hex в String String в Hex Разобрался почему не работал способ с fbld. Нужно было перед инструкцией обнулить значение следующего адреса. Спасибо @Xipho за наводку. Вызов Atoi работает как надо Также в том первом способе что я написал выше, ошибка была в том, что нужно было умножать не на 10, а на 0A
- 3 ответа
-
- 1
-
-
Привет, помогите пожалуйста с преобразованием числа ASCII в Hex число. Например, в памяти приложения есть строка, - Player12. Задача, - взять число 12, стоящее после Player, и преобразовать его в Hex, то есть в C. Сделать это нужно на ассемблере. Число 12, в виде строки, записывается в памяти как 3132, в Hex. Можно воспользоваться следующим способом преобразования: 1) регистр RAX = 0; 2) RAX * 10 + (31 - 30); // (RAX теперь равен 1) 3) RAX * 10 + (32 - 30); // (RAX теперь равен 12) Но проблема в том, что на выходе мы имеем число 12, а не C, в регистре RAX. Добраться до 12 в Player12, - не проблема. Вычесть 30, умножить на 10, сложить, - тоже не проблема. Проблема в том, как преобразовать в Hex. FPU сопроцессор имеет для преобразования числа 12 (которое уже в RAX), в C (Hex), специальную команду - fbld. Например: 1) mov [memory],rax 2) fbld [memory] //загружаем 12 3) fistp [memory] //выгружаем уже C (Hex) Но у меня такой способ не работает, выгружает всегда 8000 (если fistp word ptr).
-
Потока два, ага. Но в каждом из них происходит несвоевременная запись в переменную, как видно на видео. Вообще эту функцию вызывают 12 разных вызовов, судя по тому что показывает Ghidra. Но разве может один вызов заместить другой, пока тот еще в процессе выполнения.
-
Регистры да, не меняются. Вот как это выглядит
-
Привет всем! Кто-нибудь сталкивался с такою же странностью при дебагинге в СЕ как и я? Вот как она себя проявляет: Есть некая инструкция, работающая с координатами текстур. Я делаю на неё инжект, добавляя к имеющемуся вот такой вот код затем ставлю брейкпоинт на инструкцию "movdqu [rcx],xmm0", и начинаю двигаться по коду, клавишей F7 (Step). Иногда запись в "Alloc_Address_1" происходит своевременно, то есть сразу после шага "mov [Alloc_Address_1],r9". Но иногда, запись повторяется, например спустя один или два шага, на "pop r10" или "pop r9". Причем записывается уже совсем другое число. Как такое возможно, если я двигаюсь пошагово? Может быть есть какой-то иной независящий от брейкпоита поток игры, который использует эту же инструкцию? Возможно он перезаписывает значение в адрес? С другой стороны, как этот отдельный поток не перезаписывает значение постоянно, но только тогда, когда я делаю очередной шаг по F7. Перезапись не сделается пока я не сделаю шаг, перезапись может произойти и выше "mov [Alloc_Address_1],r9", например "mov r9,[rcx]". СЕ 7.2.Я пробовал и 7.0.
-
Спасибо, буду разбираться.
-
Привет всем! Вам когда-либо приходилось делать эффект тряски для игровой камеры? То есть такое движение камеры как если бы снимали на телефон, к примеру. Некоторое время назад я использовал такой алгоритм. Он хоть и работает нормально, но движение все-равно не естественное. (0 - 20 / 1000) - здесь число 20 это рандомное число, генерируемое lua нструкцией math.random. То есть при 20, число генерируется от -20 до 20. Далее длится на 1000. После того как динамическое число сравняется с этим полученным числом, снова сработает math.random. И цикл повторится. Движения хоть и получаются в разных диапазонах, но они все протекают с одинаковым характером. Вначале увеличение скорости, потом уменьшение. В реальности же, все не так. Рандомайзер установлен на каждую координату и на каждый угол. То есть 6 независимых друг от друга движений. Сейчас думаю как сделать его более реалистичным. По идее получается нужно задать координате или углу такое движение. Значит нужно менять время и менять силу.
-
Спасибо! Но мне всё же WinAPI более пригляделся.
-
Что делает твой пример кода? И что значит статик стек? Никак не пойму. Нашел вот в описании соглашений для 64 (по той ссылке что выложил выше) Поэтому регистр RSP неизменяется в 64 битном приложении до и после вызова функции? Потому что вызываемая функция должна восстановить его? Запись/чтение из файла, если кому-нибудь понадобится. Тест проводился на СЕ туториал 64 бит Запись Чтение
-
Спасибо за направление. Прочитал про соглашения. Для 64 и 32 битных приложений способ передачи параметров оказался различный. Вот описание передачи параметров, если кому интересно. Протестировал на 32 и 64 битных приложениях. Файл создается, хендл закрывается, все хорошо. Завтра допишу методы на запись и чтение. В ходе экспериментов я наткнулся на одну интересную особенность. Объясните мне кто знает, почему так происходить. В 32 битном приложении, функция CreateFileA, после своего выполнения увеличивает ESP на количество переданных ей параметров умноженное на размер их типа (4 байта). То есть перед вызовом функции и после ее вызова ESP разный. Тоже с функцией CloseHandle, в 32 разрядном приложении, ESP после выполнения больше на 4 (функция принимает один параметр). То есть функции увеличивают ESP автоматически. В 64 битном приложении, RSP до и после вызова всегда одинаковый. Никакой автоматизации нет. Это такая особенность которую нужно просто принять как должное? Где можно прочитать о ней?
-
Привет всем! У меня появилась необходимость записи и чтения файла через ассемблер СЕ. Через Lua CE это делается либо через writeRegionToFile readRegionFromFile либо через io.open Но я не могу использовать Lua потому что мне нужно производить запись или чтения файла именно в момент выполнения ассемблерной инструкции. На данный момент знаю лишь то что для осуществления записи и чтения файла через ассемблер СЕ нужно предварительно подготовить необходимые для этого аргументы и вызвать метод CreateFileA а затем WriteFile или ReadFile Но как это сделать через ассемблер СЕ я пока не понял. Именно, в какие регистры нужно записывать аргументы. Есть мысль что можно попробовать собрать СЕ трейнер или С++ приложение с функцией записи и чтения файла. Затем отладить их через например СЕ. Но это пока только мысль.
-
Посмотрел, спасибо. Для пожилых людей думаю это будет сложно. После нескольких часов поиска и тестов остановился на следующем: 0 - Телефон-смартфон на ОС андроид 1 - Совершение исходящего звонка- Google Assistent (управление голосом "Ok Google позвони туда-то/тому-то") 2 - Завершение звонка/отмена звонка- приложение номер 1 из Play Market (нажатие кнопки выключения телефона, для перевода экрана в заблокированный режим). 3 - Озвучивание имени входящего звонка - приложение номер 2 4 - Принятие входящего звонка - приложение номер 1 из Play Market (Простое поднесение телефона к уху).
-
Привет всем, кто-нибудь имел опыт использования устройств которые бы могли осуществлять вызовы посредством голосовых команд? Дело в том что у моей бабушки осталось 10% зрения, пользоваться обычным кнопочным телефоном она уже не может. Я пробовал тестировать Google Assistent, но как я понял, он не понимает команду "Завершить вызов". Теперь смотрю в сторону специальных колонок.