Секция ресурсов в FASM

Метки:  , , , , , , , ,

Откровенно говоря, когда программист впервые сталкивается с необходимостью использования ресурсов в своем коде, каких-либо особых трудностей у него не возникает, благо в Сети имеется некоторое (не сказать что большое) количество материала, на основе которого можно составить некое начальное представление. Действительно, организация секции ресурсов на уровне описания в исходном коде выполнена на доступном уровне. Тем не менее, существует ряд неудобств, первое из которых заключается в том, что для формата ассемблера FASM перед глазами нет настольного материала, к которому можно время от времени возвращаться за разного рода уточнениями. Ну а второе (и основное) состоит в совершенно не тривиальной внутренней организации ресурсов приложения на низком уровне (уровне исполняемого модуля). Поэтому, думаю будет не лишним обратить внимание на эту тему и составить своего рода памятку по основным терминам и определениям, да и понимание принципов построения ресурсов не является лишним как для разработчика, так и для реверс-инженера (реверсера), изучающего внутреннее устройство Windows.

продолжить изучение секции ресурсов в FASM

Шестнадцатеричное число в строку на ассемблере

Метки:  ,

В своё время в практике разработчика довольно часто можно было встретить задачи по преобразованию типов данных, одним из подвидов которых является конвертация шестнадцатеричного числа в строку, иными словами преобразование байта/слова/двойного слова в строку символов ASCIIZ (упрощенно: текстовое представление) для последующего использования. Проблема стара как мир ЭВМ и на низком уровне состоит в последовательной конвертации полубайтов (ниббла, 4 бит) в представление ASCIIZ. Чаще всего полученное представление числа используется для вывода на устройство отображения (экран). И все было бы достаточно тривиально, если бы между шестнадцатеричными значениями (0..F) и соответствующими кодами таблицы (набора) ASCII имелось прямое соответствие, но разработчики стандарта решили иначе, итогом чего явился досадный факт разделения ряда ASCII-кодов символов на границе '9' и 'A' (шестнадцатеричные значения 39h и 41h соответственно). Существующая реальность имеет два независимых ряда: 0-9 и A-F, и именно по этой вот несуразной причине алгоритмы конвертации несколько усложнились.

больше информации о конвертации шестнадцатеричного числа в строку

Длина строки на ассемблере

Метки:  , ,

Вычисление длины строки на ассемблере, как одна из наиболее часто возникающих задач, занимала умы разработчиков еще на заре компьютерной эпохи :) Однако впоследствии, с появлением и развитием операционных систем, и, соответственно, доступностью многочисленных встроенных сервисных функций работы со строками (в числе которых предоставляется и функция вычисления длины строки), подобные помысли практически перестали волновать умы представителей сообщества. С развитием высокоуровневых языков все меньше людей задумываются о том, "а как же там на низком уровне всё это реализовано", редко кого волнует оптимизация кода по быстродействию. Даже разработчики, что-либо пишущие на ассемблере, охотнее обращаются к встроенному функционалу, предоставляемому программным интерфейсом, нежели собственными наработкам, и их можно понять, поскольку производительности предоставляемых системой функций, да и языка в целом вполне хватает для того, что бы в большинстве задач не отвлекаться на пару сотен лишних тактов.
К вычислению/заданию длины строки в исходном коде применимы две основных стратегии:

  • Статическая - когда длины строк известны заранее и задаются в исходном коде в виде констант;
  • Динамическая - когда длины строк заранее неизвестны (данные, полученные в процессе работы) и вычисляются в ходе выполнения кода;

читать полностью про вычисление длины строки на ассемблере

Простой 32-битный драйвер на ассемблере

Метки:  ,

В предыдущей статье, описывающей алгоритм установки драйвера в систему Windows, мы слегка разбирались в том, как проходят стадии обнаружения оборудования и установки соответствующих драйверов. Вскоре после этого родилась идея перейти к практической части и сделать попытку написания собственного, самого простого драйвера на ассемблере. Нет, не каких-то монументальных циклов статей, а исключительно для себя, так сказать, что бы как-то уже начать изучение области разработки драйверов на Ассемблере под операционную систему Windows. После продолжительного исследования направления выяснилось, что более-менее серьезная разработка драйверов для Windows ведется на языке программирования C/C++, это объясняется тем, что данный язык является фактически "языком системы", то есть на нем, собственно, многие части системы и написаны. Однако это вовсе не исключает утверждения, что и на ассемблере вполне себе можно разработать драйвер. Да, соглашусь что делать это не так уж и сподручно, по сравнению, например, с тем же C, поскольку для последнего даже выпущен специализированный пакет разработки (DDK), но тем не менее все же возможно.

подробнее о простом драйвере на ассемблере

Генератор случайных чисел на ассемблере

Метки:  , ,

Задач, в которых возникает необходимость генерировать случайные числа в заданном диапазоне значений, существует великое множество: это и игры, где создание разнообразных игровых полей, движение объектов да и довольно большое количество логики может быть подчинено так называемой случайности, это и более серьезные направления, такие как шифрование (криптография) и некоторые другие области. Иными словами, любой уважающий себя разработчик всегда должен иметь под рукой генератор случайных чисел. Тем не менее термин генератор случайных чисел не совсем корректен, поскольку считается, что источники настоящих случайных чисел найти довольно сложно. Поэтому, применительно к компьютерным системам архитектуры x86 используется несколько иное название - генератор псевдослучайных чисел (сокращенно ГПСЧ).

Генератор псевдослучайных чисел (ГПСЧ, англ. pseudorandom number generator, PRNG) — алгоритм, создающий последовательность чисел, элементы которой "независимы" друг от друга и подчиняются заданному распределению.

Практически у всех реализаций ГПСЧ имеется некая внутренняя переменная (или несколько переменных), которая называется инициализатором (стартовым значением) ГПСЧ. При первом выполнении функции ГПСЧ значение этой переменной присваивается из псевдослучайного источника, определяемого той или иной архитектурой (например на x86 можно задействовать для этой цели инструкцию rdtsc). В процессе дальнейшего выполнения функции ГПСЧ, та же переменная становится уже "текущим" значением ГПСЧ и содержит очередное псевдослучайное число. То есть, каждый раз при вызове функции ГПСЧ со значением этой переменной производятся некоторые операции (могут быть любыми, зависит от конкретной реализации алгоритма), целью которых является получение значения, (в идеале) максимально независимого от предыдущего.

еще о генераторе случайных чисел на ассемблере

Размер окна приложения на ассемблере

Метки:  ,

Время от времени в разделе будут появляться короткие заметки по разнообразным, зачастую необходимым на практике, фрагментам кода на языке ассемблера. В этом посте я хотел бы сохранить фрагмент кода, предназначенный для получения размеров окна приложения ассемблере и вывода их в графическое окно. Иногда у начинающих встречаются задачи, в которых необходимо получить размеры (ширина/высота) областей произвольного окна собственного приложения. Что бы не рыскать каждый раз по Сети в поисках ответов, решил сохранить код решения задачи в качестве автономной заметки на собственном блоге. Код, приведенный далее в примере, рассчитан на диалект препроцессора FASM. Исходный код небольшого приложения, выводящего в окно размеры собственного окна:

Получить размер окна приложения

Драйвер Windows

Метки:  , , , , , , , , ,

Как мы знаем, на аппаратном уровне современный компьютер состоит из функциональных узлов, представляющих собой те или иные электронные компоненты. Широкому кругу пользователей персональных компьютеров знакомы такие функциональные блоки как: процессор, память, видеокарта, звуковая карта, жесткий диск, контроллер ввода-вывода (обеспечивающий работу клавиатуры, мыши, джойстика, USB-носителей (флешек)), принтер, сканер и некоторые другие. На физическом уровне данные устройства взаимодействуют между собой посредством специальных шин и протоколов, создавая совокупностью своего взаимодействия симбиоз операций, который, в общем случае, характеризует функционирование компьютера. Но разве компьютер представляет собой только лишь набор электронных компонентов? Конечно же нет, ведь один из основных аппаратных модулей, центральный процессор, спроектирован для выполнения машинных инструкций, из последовательностей которых, как мы знаем, состоят программы, в свете этого было бы уместно упомянуть еще об одном уровне - программном. Теперь давайте вернемся в не столько далекое прошлое; на заре компьютерной эры код программ (которые часто писались непосредственно в машинных кодах/на низкоуровневых языках) мог легко взаимодействовать с аппаратурой напрямую, поскольку аппаратная архитектура была относительно простой. Однако со временем технологии развивались, аппаратный и программный уровни эволюционировали взаимосвязано, и первый пришел к появлению большого многообразия устройств, а второй к появлению огромного разнообразия программных модулей, обусловивших, в дальнейшем, появление операционных систем. Операционная система явилась ключевой вехой в истории развития компьютерной индустрии, поскольку именно она, среди прочего, выполняла роль связующего звена, своеобразного координатора (диспетчера), обеспечившего взаимодействие между устройствами и программами: принимала запросы от программного слоя (например, пользовательских программ) на обмен данными с тем или иным устройством и наоборот, то есть фактически выполняла роль сопряжения между аппаратной и программной частями. Операционные системы тоже не стояли на месте, и если по началу взаимодействие операционной системы с аппаратурой компьютера было относительно простым, то по мере усложнения архитектуры и введения новых аппаратных возможностей, усложнялась и структура операционной системы. На протяжении всего времени развития операционных систем, разработчики пытались создать код, обеспечивающий полноценное взаимодействие с максимально возможным количеством имеющимся на рынке аппаратных устройств. Тем не менее, подобный подход, по мере усложнения архитектуры персональных компьютеров x86, привел к появлению концепции обособленного программного слоя, носящего название драйвер, ответственного за взаимодействие с тем или иным классом/типом устройств. Концепция драйвера оказалась настолько удачной, что помимо основного направления - поддержки физических устройств, была экстраполирована и на некоторые категории логических/виртуальных устройств. В данной статье мы будем рассказывать про то, что же из себя представляет драйвер Windows.

Больше информации о драйвере Windows

Диалоговое окно на ассемблере

Метки:  , ,

Окна, как элемент графического интерфейса Windows, могут быть простыми, информационными, уведомляющими пользователя о каком-либо событии (например, об ошибке), но чаще всего они представляют собой более сложные конструкции, содержащие в собственной клиентской области множество элементов управления. Вне зависимости от внешнего вида графического окна, основное предназначение его заключается в выстраивании взаимодействия с пользователем, поскольку само понятие окна подразумевает некую область, которую приложение отрисовывает с целью предоставить (вывести) информацию или запросить (ввести) её, другими словами обеспечить ввод/вывод данных. Вывод и вывод зачастую комбинируются в пределах одного окна и могут быть организованы нетривиально, например содержать выделенные рамкой области, группирующие однотипные данные, иметь чекбоксы/радиокнопки, обеспечивающие выбор опций, поля для текстового вывода, кнопки, различного рода списки и прочие объекты. Естественно, что создавать а затем и обслуживать в окне большое количество автономных объектов не так просто как хотелось бы: мало того, что для самого окна нужно определять класс, на основании класса уже создавать непосредственно окно, далее описывать оконную процедуру, а в довершение ко всему создавать в пределах окна каждый элемент, а ведь этими элементами придется еще и управлять. Вся эта рутина превращает процесс разработки многоэлеметного окна в очень трудоемкую задачу, в которой разработчик сфокусирован более на логике создания окон и элементов, нежели на алгоритме ядра приложения. Решением данной проблемы является рекомендованный Microsoft к использованию особый класс окон, называемый диалоговыми, которые обеспечивают относительную простоту обслуживания окон, содержащих произвольное количество различных (статических и динамических) элементов управления.

Давайте ближе познакомимся с диалоговыми окнами

Манифест приложения на ассемблере

Метки:  , ,

Когда я, в процессе своего обучения, подошел к написанию приложений, активно использующих различные графические элементы управления, раз за разом начал обращать внимание на одну интересную проблему. Дело в том, что при запуске двоичного исполняемого файла, все элементы, находящиеся в окне, выглядели "плоско", то есть имели упрощенный стиль, а-ля Windows 95/98. Долгое время я как-то не мог сообразить, почему у меня из раза в раз оформление окон получается каким-то упрощенным, без выпуклого объема кнопок, теней, объемных полос прокруток, элегантных тонких линий-рамок у групп элементов, а у подавляющего большинства сторонних оконных приложений, видимых мною в Сети, тема оформления окна как раз была "объемной"? Особенно это заметно в диалоговых окнах, где группируется большое количество разнообразных дочерних элементов управления, волей-неволей начинаешь к ним присматриваться, изучать детали.. и тут вот осознаешь, что в твоих то приложениях они получаются не такими элегантными. Оказалось, что если не предпринимать каких-либо дополнительных действий, то приложения, компилируемые FASM и использующие оконный графический интерфейс, все как на подбор получаются с упрощенной стилизацией интерфейса. Что я только не делал, уже и все стили элементов перебрал вдоль и поперек, ставя в параметры ресурсов всяческие мыслимые и немыслимые комбинации, эффект был разный, но неизменно далекий от желаемого. Как заставить приложение выглядеть в новом, современном стиле? В ходе практических изысканий, когда уже все варианты кончились, наконец-то начал думать :) Как оказалось, ответ кроется в изменившихся принципах работы с общими элементами управления, подключаемых посредством механизма под названием манифест приложения.

Что же такое манифест приложения на ассемблере

Сбой при загрузке aspi32.sys

Метки:  , , , , , , , , ,

Порой случается и такое, что обращаешь внимание на сущую мелочь, безделицу, к изначальному объекту твоего внимания никакого отношения не имеющую. Однако со временем, этот безобидный, на первый взгляд, предмет твоего невольного интереса может запросто превратиться в источник различного рода проблем. Так бывает в жизни и точно таков мир операционных систем, где постоянно изменяющийся код системных компонентов может в какой-то момент кардинально преобразовать ситуацию. Иногда, так сказать по долгу "службы", приходится анализировать системные журналы Windows, представляющие собой один из многочисленных источников информации о состоянии системы. Именно в нем иной раз можно найти записи об уже существующих и даже потенциальных, так сказать предстоящих неисправностях. Так вот, в одной далекой-далекой компании, имя которой не разглашается дабы не скомпрометировать доброе имя :) и не навредить коммерческим интересам, ну а более в целях создания статейной интриги :) специалистами было отмечено, что (иногда) при анализе системных журналов встречались любопытные события. Возникавшие с завидной регулярностью, события эти сводились к ошибкам функционирования одного и того же драйвера aspi32.sys, имели коды 7026, 1060, 7000 и содержали следующее описание:

больше информации об сбое при загрузке aspi32.sys