Blog. Just Blog

Образ мышления: Assembler

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

Вывод изображения на Ассемблере с помощью OLE

21.09.2019 | Категория: Образ мышления: Assembler | Автор: ManHunter
Ранее я уже разбирал загрузку и вывод изображения с помощью GDI+, но это далеко не единственный способ загрузки изображения из файла. В дополнение к этой теме предлагаю рассмотреть еще один способ, как можно загрузить изображение из файла средствами OLE. Сперва пропишем GUID объекта IID_IPicture и создадим структуру для методов интерфейса IPicture. В MSDN методы перечислены в алфавитном порядке, а не так, как они фактически идут в интерфейсе, имейте это в виду.
  1. ; GUID {7BF80980-BF32-101A-8BBB-00AA00300CAB}
  2. IID_IPicture       dd 7BF80980h
  3.                    dw 0BF32h
  4.                    dw 0101Ah
  5.                    db 08Bh, 0BBh, 0h, 0AAh, 0h, 030h, 00Ch, 0ABh
  6.  
  7. ; IPicture Interface
  8. struct IPicture
  9.     ; IUnknown
  10.     QueryInterface dd ?
  11.     AddRef         dd ?
  12.     Release        dd ?
  13.  
  14.     ; IPicture
  15.     get_Handle     dd ?
  16.     get_hPal       dd ?
  17.     get_Type       dd ?
  18.     get_Width      dd ?
  19.     get_Height     dd ?
  20.     Render         dd ?
  21.     set_hPal       dd ?
  22.     get_CurDC      dd ?
  23.     SelectPicture  dd ?
  24.     get_KeepOriginalFormat dd ?
  25.     set_KeepOriginalFormat dd ?
  26.     PictureChanged dd ?
  27.     SaveAsFile     dd ?
  28.     get_Attributes dd ?
  29.     SetHdc         dd ?
  30. ends
Итак, у нас есть файл с изображением, который надо загрузить в память и затем выполнить с ним нужные действия, например, вывести на форму. Первым делом загружаем его целиком в память.
  1.         ; Прочитать файл в память
  2.         invoke  _lopen,fname,OF_READ
  3.         cmp     eax,-1
  4.         je      loc_free_1
  5.         mov     ebx,eax
  6.  
  7.         ; Получить размер файла
  8.         invoke  GetFileSize,ebx,NULL
  9.         mov     [file_size],eax
  10.  
  11.         ; Выделить память под файл
  12.         invoke  GetProcessHeap
  13.         mov     [hProcHeap],eax
  14.         invoke  HeapAlloc,[hProcHeap],0,[file_size]
  15.         mov     [hLock],eax
  16.  
  17.         ; Загрузить картинку в память
  18.         invoke  _lread,ebx,[hLock],[file_size]
  19.         invoke  _lclose,ebx
Тут ничего сложного, в куче выделяется блок памяти под размер файла картинки, затем в него считывается содержимое файла.

Читать статью целиком »
Просмотров: 421 | Комментариев: 0

Как программно свернуть все окна

04.09.2019 | Категория: Образ мышления: Assembler | Автор: ManHunter
Есть разные способы программно свернуть все открытые окна. Простой и топорный вариант решения - эмуляция нажатия клавиш Win+M, которые и выполняют команду "Свернуть все окна". Делается это через последовательность вызовов keybd_event.
  1.         ; Эмуляция нажатия клавиш Win+M
  2.         invoke  keybd_event,VK_LWIN,0,0,NULL
  3.         invoke  Sleep,1
  4.         invoke  keybd_event,'M',0,0,NULL
  5.         invoke  Sleep,1
  6.         invoke  keybd_event,VK_LWIN,0,KEYEVENTF_KEYUP,NULL
Для обратного действия надо сэмулировать нажатие комбинации Win+Shift+M:
  1.         ; Эмуляция нажатия клавиш Win+Shift+M
  2.         invoke  keybd_event,VK_LWIN,0,0,NULL
  3.         invoke  Sleep,1
  4.         invoke  keybd_event,VK_LSHIFT,0,0,NULL
  5.         invoke  Sleep,1
  6.         invoke  keybd_event,'M',0,0,NULL
  7.         invoke  Sleep,1
  8.         invoke  keybd_event,VK_LSHIFT,0,KEYEVENTF_KEYUP,NULL
  9.         invoke  Sleep,1
  10.         invoke  keybd_event,VK_LWIN,0,KEYEVENTF_KEYUP,NULL
Таким же образом эмулируется нажатие комбинации Win+D - "Показать рабочий стол". Решение, в принципе, рабочее, но целиком полагаться на программную эмуляцию клавиатуры нельзя. Нажатие клавиш может перехватить или переопределить другое приложение, может быть заполнена системная очередь ввода, да мало ли чего.

Читать статью целиком »
Просмотров: 505 | Комментариев: 3

Создание выпадающего списка (Combobox) с иконками

20.08.2019 | Категория: Образ мышления: Assembler | Автор: ManHunter
Ранее я рассказывал, как сделать простой комбобокс. Сейчас давайте усовершенствуем его, а точнее дополним строки списка иконками. Я уже делал подобное с меню, тут принцип точно такой же. К стилям комбобокса в ресурсах добавляется CBS_OWNERDRAWFIXED, что в дальнейшем позволит нам самостоятельно обрабатывать процесс отрисовки каждой строки выпадающего списка. Теорию и принцип работы вы можете почитать по приведенной ссылке, повторяться я не буду. В обработчик окна, в котором находится комбобокс, добавляется реакция на два события - это WM_MEASUREITEM, которое приходит перед отрисовкой строки, и WM_DRAWITEM, при котором мы будем рисовать эту строку.
  1.         cmp     [msg],WM_MEASUREITEM
  2.         je      wm_measure
  3.         cmp     [msg],WM_DRAWITEM
  4.         je      wm_drawitem
Начнем с первого обработчика. Тут система в параметре lParam сообщения передает нам структуру MEASUREITEMSTRUCT, в которой сообщает нашей программе тип объекта, который она планирует нарисовать, а также его идентификаторы и размеры прямоугольника, который он будет занимать.
  1. wm_measure:
  2.         ; Отрисовываем строку комбобокса?
  3.         mov     ebx,[lparam]
  4.         cmp     [ebx+MEASUREITEMSTRUCT.CtlType],ODT_COMBOBOX
  5.         jne     processed
  6.  
  7.         ; Высота строки комбобокса с учетом размера иконки
  8.         mov     [ebx+MEASUREITEMSTRUCT.itemHeight],26
  9.  
  10.         jmp     processed
Проверяем, если это комбобокс, то меняем его высоту на фиксированные 26 пикселов. Ширина остается без изменений. Обратите внимание, что тут не проверяется идентификатор комбобокса CtlID, так как в нашем примере он один единственный. В реальных проектах, когда на форме может быть более одного выпадающего списка, такие проверки надо выполнять в обязательном порядке.

Читать статью целиком »
Просмотров: 441 | Комментариев: 2

Конвертирование юникодных числовых символов в цифры

05.08.2019 | Категория: Образ мышления: Assembler | Автор: ManHunter
Предположим, ваше приложение работает с числами, полученными от пользователя через текстовые поля ввода. Почти со стопроцентной вероятностью это будут привычные нам цифры 0..9, но теоретически в строке ввода могут оказаться юникодные символы из национальных алфавитов, обозначающие цифры. Например, на деванагари (꣑꣒꣓), арабском (٤٥٦) или саураштра (꣗꣘꣙).

Преобразование таких национальных символов в привычные нам цифры легко выполняется одной единственной функцией FoldString. FASM не в курсе о существовании нужного нам флага MAP_FOLDDIGITS, так что придется обозначить его самостоятельно. В остальном никаких сложностей.
  1. buff    rw 100h
  2. num     rw 100h
  3. MAP_FOLDDIGITS = 128
  4.         ...
  5.         ...
  6.         ...
  7.         ; Получить строку из поля ввода
  8.         invoke  GetDlgItemText,[hwnddlg],ID_TXT,buff,100h
  9.  
  10.         ; Сконвертировать юникодные числовые символы в цифры
  11.         invoke  FoldString,MAP_FOLDDIGITS,buff,-1,num,100h
Преобразуются только символы, соответствующие цифрам, все прочие остаются без изменений. После преобразования строки ваше приложение может продолжить работу с нормализованными пользовательскими данными. Вряд ли это вам когда-нибудь понадобится на практике, но все-таки будет полезно узнать.

Читать статью целиком »
Просмотров: 381 | Комментариев: 0

Работа с Image File Execution Options на Ассемблере

17.07.2019 | Категория: Образ мышления: Assembler | Автор: ManHunter
Не так давно я выкладывал статью про использование Image File Execution Options, где обещал провести эксперименты на Ассемблере. Всю теорию про IFEO вы можете прочитать по приведенной ссылке, дублировать я ее тут не буду.

Начнем с установки перехватчика. Тут все просто, создаем ключ в реестре, затем в нем создаем параметр "Debugger" с указанием пути к нашему файлу.
  1. ; Ключ реестра
  2. victim_key db 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\'
  3.            db 'Image File Execution Options\victim.exe',0
  4. ; Путь к нашему отладчику
  5. debug_key  db 'Debugger',0
  6. ...
  7. ...
  8.         invoke  RegCreateKeyEx,HKEY_LOCAL_MACHINE,victim_key,0,0,\
  9.                 REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,0,phkResult,lpdwDisp
  10.         ; Путь к отладчику
  11.         invoke  lstrlen,evil
  12.         invoke  RegSetValueEx,[phkResult],debug_key,0,REG_SZ,evil,eax
  13.         invoke  RegCloseKey,[phkResult]
Удаление перехватчика тоже не должно вызывать сложностей. Можно просто грохнуть параметр "Debugger", это будет правильно в случае с системными приложениями типа браузеров. Для пользовательских приложений лучше удалять соответствующую ветку реестра целиком, чтобы не засорять систему своим мусором:
  1.         invoke  SHDeleteKey,HKEY_LOCAL_MACHINE,victim_key
Для всех этих операций может потребоваться запуск с правами Администратора, а также при должной настройке может сработать UAC.

Читать статью целиком »
Просмотров: 418 | Комментариев: 0

Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2020
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.06 сек. / MySQL: 2 (0.0021 сек.) / Память: 4.75 Mb
Наверх