Blog. Just Blog

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

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

Как получить путь из символической ссылки

24.10.2022 | Категория: Образ мышления: Assembler | Автор: ManHunter
Начиная с Windows Vista, в системе появились так называемые символические ссылки, специальные файлы, в которых вместо каких-либо данных содержится путь к другому файлу или каталогу, открываемому при обращении к этой ссылке. Это позволяет, например, иметь для одного и того же файла сразу несколько разных имен.

Чтобы получить целевой путь, на который указывает символическая ссылка, есть несколько методов. Обычно в этих ваших интернетах рекомендуют сложный путь через использование функции DeviceIoControl. Штука интересная, с нее и начнем. Но сперва пачка структур и констант, которые нам понадобятся для работы.
  1. struct SymbolicLinkReparseBuffer
  2.     SubstituteNameOffset dw ?
  3.     SubstituteNameLength dw ?
  4.     PrintNameOffset      dw ?
  5.     PrintNameLength      dw ?
  6.     Flags                dd ?
  7.     PathBuffer           rw MAX_PATH*2
  8. ends
  9.  
  10. struct MountPointReparseBuffer
  11.     SubstituteNameOffset dw ?
  12.     SubstituteNameLength dw ?
  13.     PrintNameOffset      dw ?
  14.     PrintNameLength      dw ?
  15.     PathBuffer           rw MAX_PATH*2
  16. ends
  17.  
  18. struct GenericReparseBuffer
  19.     DataBuffer           db ?
  20. ends
  21.  
  22. struct REPARSE_DATA_BUFFER
  23.     ReparseTag dd ?
  24.     ReparseDataLength dw ?
  25.     Reserved dw ?
  26.     union
  27.         SymbolicLink SymbolicLinkReparseBuffer
  28.         MountPoint   MountPointReparseBuffer
  29.         Generic      GenericReparseBuffer
  30.     ends
  31. ends
  32.  
  33. FSCTL_GET_REPARSE_POINT      = 0x000900A8
  34. FILE_FLAG_BACKUP_SEMANTICS   = 0x02000000
  35. FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000
  36. IO_REPARSE_TAG_MOUNT_POINT   = 0xA0000003
  37. IO_REPARSE_TAG_SYMLINK       = 0xA000000C
Первым делом для вашего процесса надо активировать привилегию SeBackupPrivilege. Это мы уже делали, тут ничего нового нет. В оригинале эта привилегия нужна для выполнения резервного копирования файлов, а по факту она предоставляет доступ на чтение для любого файла, независимо от списка контроля доступа. Именно это нам требуется для получения информации из символической ссылки.

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

Сортировка Шелла на Ассемблере

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

Сортировка Шелла на Ассемблере

Сегодня разберем еще один алгоритм сортировки - сортировку Шелла. Он назван в честь ученого Дональда Шелла, который в 1959 году опубликовал этот алгоритм. Сортировка Шелла представляет собой нечто среднее между классической пузырьковой сортировкой и сортировкой вставками, легко реализуется на разных языках программирования, при этом показывает хорошую скорость работы и не требует выделения дополнительной памяти.

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

Загрузка шрифтов WOFF на Ассемблере

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

Загрузка шрифтов WOFF на Ассемблере

WOFF или Web Open Font Format - формат шрифтов, чаще всего используемый для Web. Он основан на стандартных форматах шрифтов OpenType или TrueType, но данные в WOFF хранятся в сжатом виде, за счет чего повышается скорость загрузки. Штатными средствами система Windows с такими шрифтами работать не умеет, поэтому мне стало интересно разобраться с этим форматом.

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

Получение размера динамической памяти приложения (Heap)

05.09.2022 | Категория: Образ мышления: Assembler | Автор: ManHunter
Heap или куча - особая структура данных, с помощью которой приложению выделяется динамически распределяемая память. Крайне удобная штука, когда надо быстренько выделить немного памяти под сиюминутные нужды. Но при активной работе с кучей может возникнуть ситуация, когда надо узнать размер оставшейся памяти, общий размер кучи или максимальный размер непрерывных данных, которые туда можно записать. Что-то из этого можно узнать при помощи штатных функций, а что-то придется получать копанием в недрах системы. Но сперва несколько структур и констант для работы. Их нет даже в MSDN, не говоря уже о FASM.
  1. struct DEBUG_BUFFER
  2.         SectionHandle        dd ?
  3.         SectionBase          dd ?
  4.         RemoteSectionBase    dd ?
  5.         SectionBaseDelta     dd ?
  6.         EventPairHandle      dd ?
  7.         Unknown              rd 2
  8.         RemoteThreadHandle   dd ?
  9.         InfoClassMask        dd ?
  10.         SizeOfInfo           dd ?
  11.         AllocatedSize        dd ?
  12.         SectionSize          dd ?
  13.         ModuleInformation    dd ?
  14.         BackTraceInformation dd ?
  15.         HeapInformation      dd ?
  16.         LockInformation      dd ?
  17.         Reserved             rd 8
  18. ends
  19.  
  20. struct DEBUG_HEAP_INFORMATION
  21.         Base        dd ?
  22.         Flags       dd ?
  23.         Granularity dw ?
  24.         Unknown     dw ?
  25.         Allocated   dd ?
  26.         Committed   dd ?
  27.         TagCount    dd ?
  28.         BlockCount  dd ?
  29.         Reserved    rd 7
  30.         Tags        dd ?
  31.         Blocks      dd ?
  32. ends
  33.  
  34. PDI_HEAPS = 0x04
  35. PDI_HEAP_BLOCKS = 0x10
Каждый процесс может иметь больше одного объекта кучи, для получения данных об этих объектах воспользуемся недокументированной функцией RtlQueryProcessDebugInformation, предварительно подготовив буфер для приема данных еще одной недокументированной функцией RtlCreateQueryDebugBuffer. Указатель на интересующие нас данные содержится в поле HeapInformation структуры DEBUG_BUFFER. Это массив из нескольких структур типа DEBUG_HEAP_INFORMATION, каждая из которых соответствует одному из объектов кучи процесса. Перебирая их по очереди и сравнивая поле Base с искомым хэндлом, находим нужный объект. В следующем код предполагается, что в переменной hHeap содержится хэндл созданной кучи, по которой мы хотим получить информацию.
  1.         ; Зарезервировать буфер для отладочной информации
  2.         invoke  RtlCreateQueryDebugBuffer,0,FALSE
  3.         mov     [debug_buf],eax
  4.  
  5.         ; Получить информацию о кучах текущего процесса
  6.         invoke  GetCurrentProcessId
  7.         invoke  RtlQueryProcessDebugInformation,eax,\
  8.                 PDI_HEAPS+PDI_HEAP_BLOCKS,[debug_buf]
  9.         mov     eax,[debug_buf]
  10.         ; Указатель на информацию о кучах
  11.         mov     eax,[eax+DEBUG_BUFFER.HeapInformation]
  12.         ; Количество записей
  13.         mov     ecx,[eax]
  14.         ; Пропустить заголовок
  15.         add     eax,4
  16. .loc_heap_scan:
  17.         or      ecx,ecx
  18.         jz      .loc_heap_done
  19.  
  20.         ; Это наша куча?
  21.         mov     edx,[eax+DEBUG_HEAP_INFORMATION.Base]
  22.         cmp     edx,[hHeap]
  23.         jne     .loc_heap_next
  24.  
  25.         ...
  26.         ; В структуре DEBUG_HEAP_INFORMATION информация о куче
  27.         ...
  28.  
  29.         jmp     .loc_heap_done
  30.  
  31. .loc_heap_next:
  32.         add     eax,sizeof.DEBUG_HEAP_INFORMATION
  33.         dec     ecx
  34.         jmp     .loc_heap_scan
  35.  
  36. .loc_heap_done:
  37.         ; Прибраться за собой
  38.         invoke  RtlDestroyQueryDebugBuffer,[debug_buf]
Нужный объект кучи найден. Теперь давайте повнимательнее посмотрим на содержимое других полей структуры DEBUG_HEAP_INFORMATION. Запрошенный размер памяти Allocated - суммарный объем всех блоков, выделенных с помощью функции HeapAlloc. Committed - фактически выделенный размер памяти. Максимальный размер кучи Blocks - параметр dwMaximumSize, указанный при вызове функции HeapCreate и выровненный до размера страницы памяти. Размер страницы можно получить при помощи функции GetSystemInfo. BlockCount - количество выделенных блоков памяти в куче, оно может отличаться от количества вызовов функции HeapAlloc, так как содержит еще и служебные блоки. Также важно понимать, что из-за сегментации кучи размер блока, который можно разово выделить в ней, не обязательно равен разнице между значениями Blocks и Allocated. Для получения максимального размера непрерывного блока памяти надо воспользоваться функцией HeapCompact. В случае фрагментированной кучи эта функция вернет размер наибольшего свободного участка.

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

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

13.08.2022 | Категория: Образ мышления: Assembler | Автор: ManHunter
На сайте уже есть две статьи про загрузку и вывод изображения с помощью GDI+ и OLE, сегодня расскажу про еще очередной способ загрузки изображений, на этот раз с помощью WIC (Windows Imaging Component). Эта технология позволяет не привязываться к конкретным форматам изображений, а делегировать большую часть рутинной работы системе. Если установлен соответствующий графический кодек и система в принципе может открыть изображение во встроенном Просмотрщике фотографий, значит его можно будет прочитать и при помощи Windows Imaging Component. Например, популярный формат WebP в чистой Windows 7 не открывается, но если поставить кодеки, то все сразу заработает.

Переходим к программированию. Поскольку это COM-технология, то нам понадобится описание множества GUID, констант и интерфейсов. Надо ли говорить, что FASM про них ничего не знает? А множество действительно внушительное.
  1. ; GUID {CACAF262-9370-4615-A13B-9F5539DA4C0A}
  2. CLSID_WICImagingFactory dd 0CACAF262h
  3.                         dw 09370h
  4.                         dw 04615h
  5.                         db 0A1h, 03Bh, 09Fh, 055h, 039h, 0DAh, 04Ch, 00Ah
  6.  
  7. ; GUID {EC5EC8A9-C395-4314-9C77-54D7A935FF70}
  8. IID_IWICImagingFactory dd 0EC5EC8A9h
  9.                        dw 0C395h
  10.                        dw 04314h
  11.                        db 09Ch, 077h, 054h, 0D7h, 0A9h, 035h, 0FFh, 070h
  12.  
  13. ; IID_IWICImagingFactory Interface
  14. struct IWICImagingFactory
  15.     ; IUnknown
  16.     QueryInterface                           dd ?   ; 000h
  17.     AddRef                                   dd ?   ; 004h
  18.     Release                                  dd ?   ; 008h
  19.     ; IWICImagingFactory
  20.     CreateDecoderFromFilename                dd ?   ; 00Ch
  21.     CreateDecoderFromStream                  dd ?   ; 010h
  22.     CreateDecoderFromFileHandle              dd ?   ; 014h
  23.     CreateComponentInfo                      dd ?   ; 018h
  24.     CreateDecoder                            dd ?   ; 01Ch
  25.     CreateEncoder                            dd ?   ; 020h
  26.     CreatePalette                            dd ?   ; 024h
  27.     CreateFormatConverter                    dd ?   ; 028h
  28.     CreateBitmapScaler                       dd ?   ; 02Ch
  29.     CreateBitmapClipper                      dd ?   ; 030h
  30.     CreateBitmapFlipRotator                  dd ?   ; 034h
  31.     CreateStream                             dd ?   ; 038h
  32.     CreateColorContext                       dd ?   ; 03Ch
  33.     CreateColorTransformer                   dd ?   ; 040h
  34.     CreateBitmap                             dd ?   ; 044h
  35.     CreateBitmapFromSource                   dd ?   ; 048h
  36.     CreateBitmapFromSourceRect               dd ?   ; 04Ch
  37.     CreateBitmapFromMemory                   dd ?   ; 050h
  38.     CreateBitmapFromHBITMAP                  dd ?   ; 054h
  39.     CreateBitmapFromHICON                    dd ?   ; 058h
  40.     CreateComponentEnumerator                dd ?   ; 05Ch
  41.     CreateFastMetadataEncoderFromDecoder     dd ?   ; 060h
  42.     CreateFastMetadataEncoderFromFrameDecode dd ?   ; 064h
  43.     CreateQueryWriter                        dd ?   ; 068h
  44.     CreateQueryWriterFromReader              dd ?   ; 06Ch
  45. ends
  46.  
  47. ; IID_IWICBitmapDecoder Interface
  48. struct IWICBitmapDecoder
  49.     ; IUnknown
  50.     QueryInterface         dd ?   ; 000h
  51.     AddRef                 dd ?   ; 004h
  52.     Release                dd ?   ; 008h
  53.     ; IWICBitmapDecoder
  54.     QueryCapability        dd ?   ; 00Ch
  55.     Initialize             dd ?   ; 010h
  56.     GetContainerFormat     dd ?   ; 014h
  57.     GetDecoderInfo         dd ?   ; 018h
  58.     CopyPalette            dd ?   ; 01Ch
  59.     GetMetadataQueryReader dd ?   ; 020h
  60.     GetPreview             dd ?   ; 024h
  61.     GetColorContexts       dd ?   ; 028h
  62.     GetThumbnail           dd ?   ; 02Ch
  63.     GetFrameCount          dd ?   ; 030h
  64.     GetFrame               dd ?   ; 034h
  65. ends
  66.  
  67. ; IWICBitmapFrameDecode Interface
  68. struct IWICBitmapFrameDecode
  69.     ; IUnknown
  70.     QueryInterface         dd ?   ; 000h
  71.     AddRef                 dd ?   ; 004h
  72.     Release                dd ?   ; 008h
  73.     ; IWICBitmapFrameDecode
  74.     GetSize                dd ?   ; 00Ch
  75.     GetPixelFormat         dd ?   ; 010h
  76.     GetResolution          dd ?   ; 014h
  77.     CopyPalette            dd ?   ; 018h
  78.     CopyPixels             dd ?   ; 01Ch
  79.     GetMetadataQueryReader dd ?   ; 020h
  80.     GetColorContexts       dd ?   ; 024h
  81.     GetThumbnail           dd ?   ; 028h
  82. ends
  83.  
  84. ; IID_IWICFormatConverter Interface
  85. struct IWICFormatConverter
  86.     ; IUnknown
  87.     QueryInterface dd ?   ; 000h
  88.     AddRef         dd ?   ; 004h
  89.     Release        dd ?   ; 008h
  90.     ; IWICFormatConverter
  91.     GetSize        dd ?   ; 00Ch
  92.     GetPixelFormat dd ?   ; 010h
  93.     GetResolution  dd ?   ; 014h
  94.     CopyPalette    dd ?   ; 018h
  95.     CopyPixels     dd ?   ; 01Ch
  96.     Initialize     dd ?   ; 020h
  97.     CanConvert     dd ?   ; 024h
  98. ends
  99.  
  100. ; IID_IWICBitmap Interface
  101. struct IWICBitmap
  102.     ; IUnknown
  103.     QueryInterface dd ?   ; 000h
  104.     AddRef         dd ?   ; 004h
  105.     Release        dd ?   ; 008h
  106.     ; IWICBitmap
  107.     GetSize        dd ?   ; 00Ch
  108.     GetPixelFormat dd ?   ; 010h
  109.     GetResolution  dd ?   ; 014h
  110.     CopyPalette    dd ?   ; 018h
  111.     CopyPixels     dd ?   ; 01Ch
  112.     Lock           dd ?   ; 020h
  113.     SetPalette     dd ?   ; 024h
  114.     SetResolution  dd ?   ; 028h
  115. ends
  116.  
  117. ; IID_IWICBitmapLock Interface
  118. struct IWICBitmapLock
  119.     ; IUnknown
  120.     QueryInterface dd ?   ; 000h
  121.     AddRef         dd ?   ; 004h
  122.     Release        dd ?   ; 008h
  123.     ; IWICBitmapLock
  124.     GetSize        dd ?   ; 00Ch
  125.     GetStride      dd ?   ; 010h
  126.     GetDataPointer dd ?   ; 014h
  127.     GetPixelFormat dd ?   ; 018h
  128. ends
  129.  
  130. ; GUID {6FDDC324-4E03-4BFE-B185-3D77768DC910}
  131. GUID_WICPixelFormat32bppPBGRA dd 06FDDC324h
  132.                               dw 04E03h
  133.                               dw 04BFEh
  134.                               db 0B1h, 085h, 03Dh, 077h, 076h, 08Dh, 0C9h, 010h
  135.  
  136. CLSCTX_INPROC_SERVER = 0x01
  137.  
  138. WICBitmapDitherTypeNone        = 0x00000000
  139. WICBitmapPaletteTypeCustom     = 0x00000000
  140. WICBitmapCacheOnDemand         = 0x00000001
  141. WICBitmapLockWrite             = 0x00000002
  142. WICDecodeMetadataCacheOnDemand = 0x00000000
Процесс загрузки изображения начинается с создания фабрики объектов типа IWICImagingFactory, с помощью которой мы в дальнейшем будем создавать декодеры, модификаторы и все прочие инструменты для работы. Тут ничего сложного, обычная работа с COM.

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

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