Skip to content

Статья, объясняющая принцип создания скриншотов экрана с использованием FASM на примере кода Томаша Грыштара

Notifications You must be signed in to change notification settings

xtenzQ/ScreenshotASM

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 

Repository files navigation

Создание снимков экрана при помощи FASM

Содержание

  1. Введение
  2. Секция импорта
  3. Структуры
  4. API-функции
  5. Ссылки

Введение

Эта статья основана на коде Томаша Грыштара (Tomasz Grysztar) [Ссылка на исходники] и написана исключительно в образовательных целях. Она объясняет работу ассемблерного кода, который создает снимки экрана в формате JPEG.

Описание структур и API-функции преимущественно является переводом описаний с MSDN.

Пост на FlatAssembler.net

Секция импорта

section '.rdata' data readable

; импортируемые функции и библиотеки
data import
  library                           \
    kernel32,       'KERNEL32.DLL', \
    user32,         'USER32.DLL',   \
    gdi32,          'GDI32.DLL',    \
    gdiplus,        'GDIPLUS.DLL'

  import  gdiplus,                                               \
    GdiplusStartup,               'GdiplusStartup',              \
    GdiplusShutdown,              'GdiplusShutdown',             \
    GdipGetImageEncodersSize,     'GdipGetImageEncodersSize',    \
    GdipGetImageEncoders,         'GdipGetImageEncoders',        \
    GdipSaveImageToFile,          'GdipSaveImageToFile',         \
    GdipDisposeImage,             'GdipDisposeImage',            \
    GdipCreateBitmapFromHBITMAP,  'GdipCreateBitmapFromHBITMAP'

  include 'api/kernel32.inc'
  include 'api/user32.inc'
  include 'api/gdi32.inc'
end data

Структуры

Программа представлена двумя структурами:

GdiplusStartupInput

[Описание на MSDN]

Структура, содержащая блок аргументов, требуемых для функции GdiplusStartup.

Синтаксис:

typedef struct GdiplusStartupInput {
  UINT32         GdiplusVersion;
  DebugEventProc DebugEventCallback;
  BOOL           SuppressBackgroundThread;
  BOOL           SuppressExternalCodecs;
};

Объявление структуры в FASM:

struct GdiplusStartupInput
  GdiplusVersion           dd ?
  DebugEventCallback       dd ?
  SuppressBackgroundThread dd ?
  SuppressExternalCodecs   dd ?
ends

Члены структуры представлены в таблице ниже:

Название Тип Описание
GdiplusVersion UINT32 Указывает версию GDI+. Должна быть 1.
DebugEventCallback DebugEventProc Указатель на функцию обратного вызова, которую GDI+ может вызывать. Значение по умолчанию - NULL.
SuppressBackgroundThread BOOL Логическое значение, указывающее, следует ли подавлять фоновый поток GDI+
SuppressExternalCodecs BOOL Логическое значение, указывающее, необходимо ли, чтобы GDI+ подавлял внешние кодеки изображений.

Структура GdiplusStartupInput предоставляет конструктор, который устаналивает член структуры GdiplusVersion в 1 и позволяет указать значения для остальных трех членов. Все параметры конструктора являются необязательными, поэтому можно объявить перменную типа GdiplusStartupInput без передачи каких-либо аргументов конструктору, и все члены будут инициализированы соответствующими значениями по умолчанию.

ImageCodecInfo

[Описание на MSDN]

Структура ImageCodecInfo предоставляет информацию об установленных кодеках изображения.

Синтаксис:

typedef struct ImageCodecInfo {
   CLSID ClassID;
   GUID FormatID;
   WCHAR * CodecName;
   WCHAR * DllName;
   WCHAR * FormatDescription;
   WCHAR * FilenameExtension;
   WCHAR * MimeType;
   DWORD Flags;
   DWORD Version;
   DWORD SigCount;
   DWORD SigSize;
   BYTE * SigPattern;
   BYTE * SigMask;
};

Объявление структуры в FASM:

struct ImageCodecInfo
  Clsid             db 16 dup ?
  FormatID          db 16 dup ?
  CodecName         dd ?
  DllName           dd ?
  FormatDescription dd ?
  FilenameExtension dd ?
  MimeType          dd ?
  Flags             dd ?
  Version           dd ?
  SigCount          dd ?
  SizeSize          dd ?
  SigPattern        dd ?
  SigMask           dd ?
ends

Члены структуры представлены в таблице ниже:

Название Тип Описание
Clsid CLSID Идентификатор кодека
FormatID GUID Идентификатор формата файла
CodecName WCHAR Указатель строку, содержащую имя кодека.
DllName WCHAR Указатель на строку, содержащую имя пути к DLL, в котором находится кодек
FormatDescription WCHAR Указатель на строку, которая содержит имя формата файла, используемого кодеком
FilenameExtension WCHAR Указатель на строку, которая содержит все расширения имен файлов, связанные с кодеком
MimeType WCHAR Указатель на строку, которая содержит тип mime-кодека.
Flags DWORD Комбинация флагов из перечисления ImageCodecFlags
Version DWORD Целое число, указывающее версию кодека
SigCount DWORD Целое число, которое указывает количество подписей, используемых файловым форматом, связанным с кодеком
SizeSize DWORD Целое число, указывающее количество байтов в каждой подписи
SigPattern BYTE Указатель на массив байтов, содержащий шаблон для каждой подписи
SigMask BYTE Указатель на массив байтов, содержащий маску для каждой подписи

API-функции

API-функции, использованные в программе:

GdiPlusStartup

[Описание на MSDN]

Функция GdiplusStartup инициализирует Windows GDI+.

Status GdiplusStartup(
  __out  ULONG_PTR token *token,
  __in   const GdiplusStartupInput *input,
  __out  GdiplusStartupOutput *output
);

Аргументы функции GdiplusStartup:

Название Тип Описание
token [out] ULONG_PTR token* Указатель на ULONG_PTR, который получает токен
input [in] const GdiPlusStartupInput*
output [out] GdiplusStartupOutput* Указатель на структуру GdiplusStartupOutput

Использование в коде:

  invoke  GdiplusStartup, token, input, NULL
  test    eax, eax
  jnz     exit

GdipGetImageEncodersSize

[Описание на MSDN]

Функция GdipGetImageEncodersSize получает число доступных кодировщиков изображения и размер массива объектов типа ImageCodecInfo, который возвращает функция GetImageEncoders.

Синтаксис:

Status GetImageEncodersSize(
  __out  UINT *numEncoders,
  __out  UINT *size
);

Аргументы функции GdipGetImageEncodersSize:

Название Тип Описание
numEncoders [out] UINT* Указатель на UINT, который получает число доступных кодировщиков изображения
size [out] UINT* Указатель на UINT, который получает размер массива объектов ImageCodecInfo (в байтах), возвращаемых функцией GetImageEncoders

Использование в коде:

  invoke  GdipGetImageEncodersSize, encoders_count, encoders_size
  test    eax, eax
  jnz     gdiplus_shutdown

VirtualAlloc

[Описание на MSDN]

С помощью данной функции есть возможность выделить или зарезервировать страницы виртуальной памяти. Между выделением и резервированием есть разница. При выделении физически выделяется память и естественно увеличивается файл подкачки. При резервировании этого не происходит.

Синтаксис:

LPVOID WINAPI VirtualAlloc(
  _In_opt_ LPVOID lpAddress,
  _In_     SIZE_T dwSize,
  _In_     DWORD  flAllocationType,
  _In_     DWORD  flProtect
);

Аргументы функции VirtualAlloc:

Название Тип Описание
lpAddress [in, optional] LPVOID Базовый адрес
size [out] SIZE_T Размер области в байтах
flAllocationType [in] DWORD Способ получения
flProtect [in] DWORD Тип доступа

Способ получения:

Название Описание
MEM_COMMIT Выполняется выделение страниц памяти для непосредственной работы с ними. Выделенные страницы заполняются нулями.
MEM_RESERVE Резервирует страницы памяти

Тип доступа:

Название Описание
PAGE_READONLY Только чтение
PAGE_READWRITE Чтение и запись
PAGE_EXECUTE Только исполнение программного кода
PAGE_EXECUTE_READ Исполнение и чтение
PAGE_EXECUTE_READWRITE Исполнение, чтение и запись
PAGE_GUARD Сигнализация доступа к странице
PAGE_NOACCESS Запрещен любой вид доступа
PAGE_NOCACHE Отмена кэширования для страницы памяти

Использование в коде:

  invoke  VirtualAlloc, 0, [encoders_size], MEM_COMMIT, PAGE_READWRITE
  test    eax, eax
  jz      gdiplus_shutdown
  mov     ebx, eax

GetImageEncoders

[Описание на MSDN]

Функция GetImageEncoders получает массив объектов типа ImageCodecInfo, которые содержат информацию о доступных кодировщиках изображений.

Синтаксис:

Status GetImageEncoders(
  __in   UINT numEncoders,
  __in   UINT size,
  __out  ImageCodecInfo *encoders
);

Аргументы функции:

Название Тип Описание
numEncoders [in] UINT Целое число, определяющее количество доступных кодировщиков изображений
size [in] UINT Целое число, которое задает размер в байтах массив объектов типа ImageCodecInfo
encoders [out] ImageCodecInfo* Указатель на буфер, который получает массив объектов типа ImageCodecInfo

Использование в коде:

  invoke  GdipGetImageEncoders, [encoders_count], [encoders_size], ebx
  test    eax, eax
  jnz     gdiplus_shutdown

VirtualFree

[Описание на MSDN]

Функция VirtualFree освобождает выделенную память.

Синтаксис:

BOOL VirtualFree
(  
  LPVOID lpAddress,
  SIZE_T dwSize,	
  DWORD dwFreeType	
);

Аргументы функции:

Название Тип Описание
lpAddress LPVOID Базовый адрес
dwSize SIZE_T Размер, если мы будем использовать тип освобождения, как MEM_RELEASE, то размер должен быть установлен в 0.
encoders [out] DWORD Определяет, какая операция произойдет с памятью

Типы операций с памятью:

Название Описание
lpAddress LPVOID
MEM_RELEASE Высвобождение используемой памяти
MEM_DECOMMIT Высвобождение зарезервированной памяти

Использование в коде:

invoke  VirtualFree, ebx, 0, MEM_RELEASE

GetDC

[Описание на MSDN]

Функция GetDC идентифицирует контекст устройства для CWnd клиентской области если успешно иначе, возвращаемое значение NULL.

Синтаксис:

HDC GetDC(
  _In_ HWND hWnd
);

Аргументы функции:

Название Тип Описание
hWnd HWND Дескриптор окна, чей контекст устройства должен быть извлечен

Использование в коде:

invoke  GetDC, HWND_DESKTOP
test    eax, eax
jz      gdiplus_shutdown
mov     esi, eax

GetSystemMetrics

[Описание на MSDN]

Функция GetSystemMetrics идентифицирует заданный системный показатель или настройку конфигурации системы.

Синтаксис:

int WINAPI GetSystemMetrics(
  _In_ int nIndex
);

Аргументы функции:

Название Тип Описание
nIndex int Идентификатор настройки

Использование в коде:

invoke  GetSystemMetrics, SM_CYSCREEN
mov     [screen_height], eax
invoke  GetSystemMetrics,SM_CXSCREEN
mov     [screen_width], eax

CreateCompatibleBitmap

[Описание на MSDN]

Функция CreateCompatibleBitmap создает точечный рисунок, совместимый с контекстом устройства.

Синтаксис:

HBITMAP CreateCompatibleBitmap(
  _In_ HDC hdc,
  _In_ int nWidth,
  _In_ int nHeight
);

Аргументы функции:

Название Тип Описание
hdc [in] HDC Дескриптор контекста устройства
nWidth [in] int Ширина рисунка в пикселях
nHeight [in] int Высота рисунка в пикселях

Использование в коде:

invoke  CreateCompatibleBitmap, esi, [screen_width], [screen_height]
test    eax, eax
jz      release_desktop_dc
mov     ebx, eax

CreateCompatibleDC

[Описание на MSDN]

Функция CreateCompatibleDC создает контекст устройства памяти, который является совместимым с устройством, определенным pDC.

Синтаксис:

HDC CreateCompatibleDC(
  _In_ HDC hdc
);

Аргументы функции:

Название Тип Описание
hdc [in] HDC Указатель на контекст устройства

Использование в коде:

invoke  CreateCompatibleDC, esi
test    eax, eax
jz      delete_bitmap
mov     edi, eax

SelectObject

[Описание на MSDN]

Функция SelectObject выбирает объект в указанном контексте устройства. Новый объект заменяет предыдущий объект того же типа.

Синтаксис:

HGDIOBJ SelectObject(
  _In_ HDC     hdc,
  _In_ HGDIOBJ hgdiobj
);

Аргументы функции:

Название Тип Описание
hdc [in] HDC Указатель на контекст устройства
hgdiobj [in] HGDIOBJ Указатель на объект, который должен быть выбран

Использование в коде:

invoke  SelectObject, edi, ebx
test    eax, eax
jz      delete_dc

BitBlt

[Описание на MSDN]

Функция BitBlt копирует точечный рисунок от исходного контекста устройства до этого текущего контекста устройства.

Синтаксис:

BOOL BitBlt(
  _In_ HDC   hdcDest,
  _In_ int   nXDest,
  _In_ int   nYDest,
  _In_ int   nWidth,
  _In_ int   nHeight,
  _In_ HDC   hdcSrc,
  _In_ int   nXSrc,
  _In_ int   nYSrc,
  _In_ DWORD dwRop
);

Аргументы функции:

Название Тип Описание
hdcDest [in] HDC Указатель на контекст конечного устройства
nXDest [in] int Определяет логическую x-координату левого верхнего угла прямоугольника адресата.
nYDest [in] int Определяет логическую y-координату левого верхнего угла прямоугольника адресата.
nWidth [in] int Определяет ширину (в логических модулях) прямоугольника адресата и исходного точечного рисунка.
nHeight [in] int Определяет высоту (в логических модулях) прямоугольника адресата и исходного точечного рисунка.
hdcSrc [in] HDC Указатель на объект HDC, который идентифицирует контекст устройства из которого точечный рисунок будет скопирован
nXSrc [in] int Определяет логическую x-координату левого верхнего угла исходного точечного рисунка
nYSrc [in] int Определяет логическую y-координату левого верхнего угла исходного точечного рисунка
dwRop [in] DWORD Определяет растровую операцию, которую нужно выполнить

Использование в коде:

invoke  BitBlt, edi, 0, 0, [screen_width], [screen_height], esi, 0, 0, SRCCOPY
test    eax, eax
jz      delete_dc

GdipCreateBitmapFromHBITMAP

[Описание на MSDN]

Функция GdipCreateBitmapFromHBITMAP создает точечное изображение на основе дескриптора GDI и дескриптора палитры GDI.

Синтаксис:

GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(
    HBITMAP hbm,
    HPALETTE hpal,
    GpBitmap** bitmap
);

Аргументы функции:

Название Тип Описание
hbm [in] HBITMAP Дескриптор точечного изображения
hgdiobj [in] HPALETTE Дескриптор палитры GDI
bitmap [out] GpBitmap Указатель на переменную DWORD, которая получает указатель на объект bitmap

Использование в коде:

invoke  GdipCreateBitmapFromHBITMAP, ebx, NULL, gdip_bitmap
test    eax, eax
jnz     delete_dc

GdipSaveImageToFile

[Описание на MSDN]

Функция GdipSaveImageToFile сохраняет изображение в файл.

Синтаксис:

GpStatus WINGDIPAPI GdipSaveImageToFile(
    GpImage *image,
    GDIPCONST WCHAR* filename,
    GDIPCONST CLSID* clsidEncoder,
    GDIPCONST EncoderParameters* encoderParams
);

Аргументы функции:

Название Тип Описание
image [in] GpImage Указатель на изображение
filename [in] GDIPCONST Указатель на строку unicode, которая указывает имя пути для сохраненного изображения
clsidEncoder [in] GDIPCONST Указатель на CLSID, который указывает кодировщик, который будет использоваться для сохранения изображения
encoderParams [in] GDIPCONST Указатель на структуру EncoderParameters, которая содержит параметры, используемые кодировщиком

Использование в коде:

invoke  GdipSaveImageToFile, [gdip_bitmap], file_name, encoder_clsid, NULL

GdipDisposeImage

[Описание на MSDN]

Функция GdipDisposeImage удаляет указанное изображение.

Синтаксис:

GpStatus WINGDIPAPI GdipDisposeImage(
    GpImage *image
);

Аргументы функции:

Название Тип Описание
image [in] GpImage Указатель на изображение

Использование в коде:

invoke  GdipDisposeImage, [gdip_bitmap]

DeleteObject

[Описание на MSDN]

Функция DeleteObject удаляет перо, кисть, шрифт, растровое изображение, область или палитру, освобождая все системные ресурсы, связанные с объектом. После удаления объекта указанный дескриптор более недействителен.

Синтаксис:

BOOL DeleteObject(
  _In_ HGDIOBJ hObject
);

Аргументы функции:

Название Тип Описание
hObject [in] HGDIOBJ Дескриптор объекта

Использование в коде:

invoke  DeleteObject, edi

ReleaseDC

[Описание на MSDN]

Функция ReleaseDC освобождает контекст устройства (DC) для его использования другими приложениями.

Синтаксис:

int ReleaseDC(
  _In_ HWND hWnd,
  _In_ HDC  hDC
);

Аргументы функции:

Название Тип Описание
hWnd [in] HWND Дескриптор окна, чей контекст должен быть высвобожден
hDC [in] HDC Дескриптор контекста устройства, который надо высвободить

Использование в коде:

invoke  ReleaseDC, HWND_DESKTOP, esi

GdiplusShutdown

[Описание на MSDN]

Функция GdiplusShutdown очищает ресурсы, используемые Windows GDI+.

Синтаксис:

void GdiplusShutdown(
  __in  ULONG_PTR token
);

Аргументы функции:

Название Тип Описание
token [in] ULONG_PTR Токен, возвращенный предыдущим вызовом GdiplusStartup

Использование в коде:

invoke  GdiplusShutdown, [token]

ExitProcess

[Описание на MSDN]

Функция ExitProcess заканчивает работу процесса и всех его потоков.

Синтаксис:

VOID ExitProcess(
  UINT uExitCode	
);

Аргументы функции:

Название Тип Описание
uExitCode [in] UINT Определяет код выхода для процесса, и для всех потоков, которые завершают работу в результате вызова этой функци

Использование в коде:

invoke  ExitProcess, 0

About

Статья, объясняющая принцип создания скриншотов экрана с использованием FASM на примере кода Томаша Грыштара

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published