Blog. Just Blog

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

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

Парсинг метаданных DSF-файлов на Ассемблере

11.11.2023 | Категория: Образ мышления: Assembler | Автор: ManHunter

Парсинг метаданных DSF-файлов на Ассемблере

Во время очередного пиратского набега на торренты мне попался музыкальный альбом в формате DSF. Это контейнер для аудиопотока в супер-мега качестве, разработанный компаниями Sony и Philips. В результате и файлы получаются по 400-500 мегабайт на одну песню. Может быть для аудиофилов такое качество как-то можно обосновать, но для меня этот формат представляет исключительно спортивный интерес. А точнее, как из таких файлов извлечь метаданные.

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

Как защитить DLL от выгрузки через FreeLibrary

07.11.2023 | Категория: Образ мышления: Assembler | Автор: ManHunter
Небольшой трюк, позволяющий защитить вашу DLL от выгрузки из процесса при помощи функции FreeLibrary. Например, если процесс обнаружил инжект посторонней библиотеки в свое адресное пространство и пытается от нее избавиться.

Сперва немного теории. При вызове функции LoadLibrary увеличивается на единицу внутренний счетчик загрузок, но повторной загрузки библиотеки не выполняется. При вызове функции FreeLibrary, соответственно, этот счетчик уменьшается. При достижении счетчиком нулевого значения библиотека выгружается из памяти. На этом основан метод "защиты" от выгрузки, когда в самой DLL несколько раз дополнительно вызывается LoadLibrary, тем самым увеличивая счетчик загрузок. Но ведь никто не мешает вызвать FreeLibrary сто или сто тысяч раз подряд, пока счетчик не будет обнулен. Поэтому я взял слово "защита" в кавычки.

Правильным способом защититься от выгрузки DLL из целевого процесса будет использование функции GetModuleHandleEx с флагом GET_MODULE_HANDLE_EX_FLAG_PIN. Функция должна вызываться из DLL. В этом случае загруженный модуль будет оставаться в памяти вплоть до завершения основного процесса, независимо от того, сколько раз будет вызвана функция FreeLibrary.

Просмотров: 135 | Комментариев: 0

Как получить список поддерживаемых кодировок

05.11.2023 | Категория: Образ мышления: Assembler | Автор: ManHunter
Сегодняшний небольшой пример кода - получение списка всех поддерживаемых кодировок в системе. Примерно такой список можно увидеть в меню сохранения в текстовых редакторах или в браузерах, когда надо выбрать кодировку страницы. Если ваше приложение умеет работать с разными кодировками, то значит должно уметь и получать их список.

Начинаем с констант и структуры, которые отсутствуют в FASM.
  1. CP_SUPPORTED = 0x00000002
  2.  
  3. MAX_LEADBYTES   = 12
  4. MAX_DEFAULTCHAR = 2
  5.  
  6. struct CPINFOEX
  7.         MaxCharSize        dd ?
  8.         DefaultChar        rb MAX_DEFAULTCHAR
  9.         LeadByte           rb MAX_LEADBYTES
  10.         UnicodeDefaultChar dw ?
  11.         CodePage           dd ?
  12.         CodePageName       rb MAX_PATH
  13. ends
Для получения списка всех доступных кодировок надо вызвать функцию EnumSystemCodePages с параметром CP_SUPPORTED или с параметром CP_INSTALLED, если надо узнать только список установленных.
  1.         ; Получить список поддерживаемых кодировок
  2.         invoke  EnumSystemCodePages,CodePageEnumProc,CP_SUPPORTED
Другим параметром передается адрес функции обработчика, которой будут поочередно передаваться идентификаторы кодировок.

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

Устраняем косяки функций PathRemoveExtension и PathRenameExtension

24.10.2023 | Категория: Образ мышления: Assembler | Автор: ManHunter
В комментариях к статьям иногда проскакивают мысли, мол, зачем изобретать велосипед, если уже существуют готовые WinAPI. Ну так вот, в библиотеке shlwapi помимо кучи других полезных функций есть две функции для работы с расширениями файлов. PathRemoveExtension служит для удаления расширения из строки с путем файла, а PathRenameExtension для замены имеющегося расширения на другое. Это очень удобно в случае, когда, например, надо сгенерировать имя файла данных или файла с настройками по имени исполняемого файла. Но, к сожалению, у них есть фатальные косяки в реализации. Это проще показать на примерах. Вот удаление расширения:

c:\test\file1.txt -> PathRemoveExtension -> c:\test\file1
c:\test\file2 -> PathRemoveExtension -> c:\test\file2
c:\test\.htaccess -> PathRemoveExtension -> c:\test\
c:\test\.htaccess.bak -> PathRemoveExtension -> c:\test\.htaccess

И аналогично для замены расширения, например, на ".ini":

c:\test\file1.txt -> PathRenameExtension -> c:\test\file1.ini
c:\test\file2 -> PathRenameExtension -> c:\test\file2.ini
c:\test\.htaccess -> PathRenameExtension -> c:\test\.ini
c:\test\ -> PathRenameExtension -> c:\test\.ini
c:\test\.htaccess.bak -> PathRenameExtension -> c:\test\.htaccess.ini

Как видите, если имя файла начинается с точки и при этом файл не имеет расширения, то обе функции работают неправильно. Кроме этого, функция замены расширения дает неправильный с точки зрения логики результат, если имя файла в строке вообще отсутствует.

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

Как сделать перетаскиваемый курсор-прицел

21.10.2023 | Категория: Образ мышления: Assembler | Автор: ManHunter
У многих программ для работы с окнами приложений есть такая фича, как перетаскиваемый указатель-прицел, с помощью которого можно выбрать определенное окно. Когда-то у меня в комментариях спросили, как можно сделать что-то подобное. Что ж, лучше поздно, чем никогда.

Начнем с теории, как это все должно работать. На форме программы сперва рисуется значок прицела, это самая обычная статическая картинка. При клике на нее активируется процесс перетаскивания. Системный курсор меняется на этот же прицел, а значок на форме скрывается. Тем самым достигается визуальный эффект, что перетаскивается именно прицел с формы. Пока кнопка мыши нажата, обрабатываются координаты курсора и выполняются нужные действия с этой информацией. При отпускании кнопки мыши курсор меняется на дефолтный системный, а на форме снова отображается картинка. Таким образом нам надо отслеживать три сообщения окна: WM_LBUTTONDOWN для нажатия левой кнопки мыши, WM_LBUTTONUP для ее отпускания и WM_MOUSEMOVE для перемещения мыши.
  1.         cmp     [msg],WM_LBUTTONDOWN
  2.         je      .wmsetcursor
  3.         cmp     [msg],WM_LBUTTONUP
  4.         je      .wmreleasecursor
  5.         cmp     [msg],WM_MOUSEMOVE
  6.         je      .wmmousemove
Теперь разберем каждый обработчик более подробно. При нажатии левой кнопки мыши сперва проверяется координата, по которой было произведено нажатие. Если она находится внутри области, занимаемой картинкой прицела на форме, то загружается курсор, прячется картинка, как написано выше.
  1. .wmsetcursor:
  2.         ; Получить координаты события
  3.         invoke  GetMessagePos
  4.         ; Координата Y
  5.         mov     ebx,eax
  6.         shr     ebx,16
  7.         mov     [pt.y],ebx
  8.         ; Координата X
  9.         mov     ebx,eax
  10.         and     ebx,0FFFFh
  11.         mov     [pt.x],ebx
  12.  
  13.         ; Получить границы иконки
  14.         invoke  GetWindowRect,[hStatic],img
  15.  
  16.         ; Клик произошел в области иконки?
  17.         invoke  PtInRect,img,[pt.x],[pt.y]
  18.         or      eax,eax
  19.         jz      .processed
  20.  
  21.         ; Установить захват событий мыши
  22.         invoke  SetCapture,[hwnddlg]
  23.  
  24.         ; Загрузить наш курсор
  25.         invoke  SetCursor,[hCursor]
  26.  
  27.         ; Скрыть иконку на форме
  28.         invoke  SendMessage,[hStatic],STM_SETIMAGE,IMAGE_CURSOR,0
  29.  
  30.         mov     [state],1
Но главное, надо обязательно установить захват мыши для окна программы при помощи функции SetCapture. Иначе события перемещения перестанут передаваться, как только курсор покинет пределы окна. Также надо взвести флаг, что теперь выполняется перемещение прицела.

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

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