
Образ мышления: Assembler
То, что не удается запрограммировать на Ассемблере, приходится паять
Образ мышления: Assembler - RSS-канал
Образ мышления: Assembler - Карта сайта

Эффект плавного открытия окна
08.12.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Разберем еще один красивый эффект для ваших приложений - плавное сворачивание и разворачивание окна. Для этого используются те же функции, что и для создания окон нестандартной формы, так как по сути это такая же работа с прямоугольными регионами, но только в цикле с заданными параметрами. Алгоритм простой: прямоугольный регион окна увеличивается от центра до полного размера или уменьшается со всех сторон до центра. Для этого надо сперва надо вычислить шаг, на который будет увеличиваться или уменьшаться горизонтальная и вертикальная координата.Code (Assembler) : Убрать нумерацию
- ; Обработчик инициализации окна
- ...
- ; Получить размер окна
- invoke GetClientRect,[hwnddlg],coord
- ; Вычислить размеры окна для создания основного региона
- mov eax,[coord.bottom]
- sub eax,[coord.top]
- mov [height],eax
- mov eax,[coord.right]
- sub eax,[coord.left]
- mov [width],eax
- SPEED = 4 ; Скорость анимации
- ; Вычислить коэффициент соотношения сторон в зависимости от
- ; размеров ширины и высоты окна
- cmp eax,[height]
- ja @f
- ; Высота/ширина
- xor edx,edx
- mov eax,[height]
- mov ecx,[width]
- div ecx
- shl eax,SPEED
- mov [delta_x],(1 shl SPEED) ; Шаг изменения ширины
- mov [delta_y],eax ; Шаг изменения высоты
- jmp @1
- @@:
- ; Ширина/высота
- xor edx,edx
- mov eax,[width]
- mov ecx,[height]
- div ecx
- shl eax,SPEED
- mov [delta_x],eax ; Шаг изменения ширины
- mov [delta_y],(1 shl SPEED) ; Шаг изменения высоты
- @1:
Читать статью целиком »
Просмотров: 6193 | Комментариев: 6

Расчет CRC16 на Ассемблере
30.11.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
CRC (Cyclic Redundancy Code - циклический избыточный код) - алгоритм расчета контрольной суммы для передаваемого сообщения, основанный на полиномиальной арифметике. Основная идея алгоритма CRC состоит в представлении сообщения в виде огромного двоичного числа, делении его на другое фиксированное двоичное число и использовании остатка от этого деления в качестве контрольной суммы. Получив сообщение, приемник должен выполнить аналогичное действие и сравнить полученный результат с принятой контрольной суммой. Сообщение считается достоверным, выполняется это равенство. Классический алгоритм CRC16 часто используется в архиваторах для контроля целостности данных служебных заголовков архивов, также его удобно использовать для сравнения строки с каким-либо значением, когда по соображениям безопасности сравниваемое значение не хранится в открытом виде. Для контроля целостности файлов функцию CRC16 лучше не использовать, так как из-за небольшой длины ее научились подделывать. Чтобы выполнить расчет CRC16 требуется сперва подготовить так называемую таблицу инициализации. В сегменте данных таблица резервируется как 256 слов, по одному word на каждый возможный байт:Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- ; Таблица инициализации для расчета CRC16
- crc16table rw 256
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------------------
- ; Функция создания таблицы инициализации для расчета CRC16
- ;-----------------------------------------------------------------------
- proc init_CRC16
- push eax ebx ecx edi
- ; Указатель на выделенную под таблицу память
- mov edi,crc16table
- ; Расчитать значения для всех 256 слов
- xor edx,edx
- CRC16_Polynom:
- mov eax,edx
- mov ecx,8
- CRC16_NL:
- shr ax,1
- jae CRC16_NoXOR
- ; Magic Number!
- xor ax,0a001h
- CRC16_NoXOR:
- loop CRC16_NL
- ; Записать значение в таблицу полиномов
- stosw
- inc edx ; Счетчик +1
- cmp edx,256 ; Всю таблицу сгенерировали?
- jne CRC16_Polynom ; Нет, работаем дальше
- ; Восстановить измененные регистры
- pop edi ecx ebx eax
- ret
- endp
Читать статью целиком »
Просмотров: 10727 | Комментариев: 2

Как запретить Windows переходить в спящий режим
26.10.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
В некоторых случаях требуется, чтобы на время работы вашего приложения компьютер постоянно оставался в активном состоянии, то есть не включался скринсейвер, не отключался монитор, система не переходила в спящий режим. Для этого надо "убедить" Windows, что за клавиатурой сидит реальный пользователь и проявляет какую-то активность, в этом случае все счетчики времени бездействия будут сбрасываться. Для программной имитации действий пользователя используются две функции: mouse_event для симуляции работы с мышкой мышки и, соответственно, keybd_event для клавиатуры. Также можно использовать более универсальную функцию SendInput, она позволяет симулировать не только мышку и клавиатуру, но и хардварные события. Есть еще более суровые варианты, связанные с ковырянием в реестре, изменением профилей электропитания, но их я рассматривать не буду.В прикладном приложении для имитации действий пользователя надо установить таймер, например, на секундный интервал, и в его функции-обработчике симулировать движение мыши. Нажатия кнопок мыши и клавиш на клавиатуре симулировать не надо, так как эти действия могут наложиться с действиями реального пользователя, а вот перемещение мышки на какое-нибудь незаметное расстояние будет в самый раз. Почитаем повнимательнее документацию к функции mouse_event. Координаты перемещения задаются в условных единицах - микки, которые высчитываются по формуле: 1 микки = (ширина или высота разрешения монитора) / 65535. Если не указан флаг MOUSEEVENTF_ABSOLUTE, то координаты считаются относительные, то есть от текущего положения курсора. Первоначальный вариант решения был в перемещении курсора на 1 микки от текущего положения курсора, а затем в возвращении его обратно. Но, к сожалению, на Windows XP этот способ все-таки двигал курсор (спасибо ezfalc0n за подсказку). Следующий вариант, вообще без движения, также сбрасывает счетчик времени бездействия системы, так что будем использовать именно его:
Code (Assembler) : Убрать нумерацию
- ; Симулировать событие от мышки, оставляя ее на месте
- invoke mouse_event,MOUSEEVENTF_MOVE,0,0,0,0
Читать статью целиком »
Просмотров: 12708 | Комментариев: 25

Экранная лупа на Ассемблере
15.10.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Алгоритм реализации экранной лупы достаточно простой. Надо получить часть изображения рабочего стола и скопировать его с масштабированием в нужную область вашего приложения. Сделать это можно при помощи функции StretchBlt. Если посмотрите описание, то увидите, что для работы этой функции требуются следующие параметры: размеры результирующей области, размеры исходной области и контексты устройств (окон), в которых находятся области. А поскольку мы сейчас разрабатываем лупу, значит она должна увеличивать, то есть размеры исходного окна должны быть пропорционально меньше результирующего. Коэффициент пропорциональности и есть коэффициент увеличения лупы. При инициализации окна выполним предварительные расчеты:Code (Assembler) : Убрать нумерацию
- ...
- ; Получить контекст окна лупы
- invoke GetDlgItem,[hwnddlg],ID_ZOOM
- mov ebx,eax
- invoke GetDC,eax
- mov [wDC],eax
- ; Получить размеры окна лупы
- invoke GetClientRect,ebx,coord
- mov eax,[coord.right]
- sub eax,[coord.left]
- mov [dWidth],eax
- mov eax,[coord.bottom]
- sub eax,[coord.top]
- mov [dHeight],eax
- ; Получить контекст десктопа
- invoke GetDesktopWindow
- mov [hDesktop],eax
- invoke GetDC,eax
- mov [dDC],eax
- ...
Читать статью целиком »
Просмотров: 6034 | Комментариев: 6

Защищенное поле для ввода пароля
23.08.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Как-то задумался о том, можно ли защититься от программ, которые показывают пароли за "звездочками"? Ведь это могут быть не только безобидные программы для восстановления забытых паролей, но и "троянские кони", похищающие вашу приватную информацию. Немного поэкспериментировал, оказалось, что защититься можно. Сперва немного теоретической информации о том, каким образом открываются пароли. Первый способ: сначала нужному полю EDIT посылается сообщение EM_SETPASSWORDCHAR с нулевыми параметрами, в результате чего с него снимается атрибут ES_PASSWORD. После этого текст пароля можно прочитать как визуально, так и через GetWindowText, WM_GETTEXT и т.п. Второй способ, более "пробивной", это внедрение в исследуемый процесс своей DLL, после чего с ее помощью текст пароля читается через сообщение WM_GETTEXT. Это делается потому, что в целях безопасности информацию из поля, закрытого "звездочками", через GetWindowText или WM_GETTEXT можно получить только из контекста процесса, который владеет окном.Чтобы защититься от программ первого типа, надо самостоятельно обрабатывать сообщение EM_SETPASSWORDCHAR и в обработчике подавлять его. Защититься от второго варианта сложнее, ведь если мы будем подавлять сообщение WM_GETTEXT, то мы и сами не сможем прочитать текст пароля. Значит надо каким-то образом различать "свои" сообщения WM_GETTEXT и "чужие". Признак "свой" можно сделать, например, указав в качестве длины буфера какое-нибудь заранее определенное уникальное значение, а затем в обработчике пропускать сообщения только с этим параметром. Установить собственный обработчик можно через субклассирование окна ввода, это мы уже разбирали в предыдущих статьях. Теперь от теории перейдем к практике.
Читать статью целиком »
Просмотров: 5934 | Комментариев: 10
