鼠标指针文件格式解析——Windows(一)
ico文件格式分析
○ 文件头struct ICONDIR icondir
○ struct ICONDIRENTRY idEntries
○ 图像数据头段struct BITMAPINFOHEADER bmiHeader
○ 图像数据段struct IMAGEDATA data
○ 声明
在介绍鼠标指针文件之前,我们先来介绍一下图标文件。
一般大一点的软件里,都会有一个ico文件,这个图标的分辨率一般来说都较小。且无颜色的部分都为透明状,也就是阿尔法通道值为0。
ico文件格式分析:
文件后缀名一般位icon或者ico。
本篇文章主要是以在ico文件头后续加入了bitmap这种图片,而在ico文件头后续加入png等不在讨论的范围内。
ico文件头后续加入了bitmap情况:
ico文件头后续加入png情况:
ico的文件格式主要包括文件头、图像数据两部分。
文件头struct ICONDIR icondir
NO.1
这个部分文件头固定6字节,剩下的16字节代表了图像信息,每增加一张图片,这部分增加16字节。
如图仅有1张图像部分:
如图,图标文件含有多张图像部分,这张图标含有5张图像:
具体结构解释如下:
type
ICONDIR = packed record
idReserved: SmallInt; // Reserved 保留位,必须为0
idType: SmallInt; // Resource type 光标资源类型,作为ico时值为1
idCount: SmallInt; // Image Count 标记了文件中包含的图像数量,与后面的images数量相一致
end; // 6 bytes
struct ICONDIRENTRY idEntries
NO.2
剩下的16字节代表了图像的具体数据。
typedef struct
BYTE bWidth; // Width, in pixels, of the image 图片宽度
BYTE bHeight; // Height, in pixels, of the image 图片高度
BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
BYTE bReserved; // Reserved ( must be 0) 必须为0
WORD wPlanes; // Color Planes 位图位面数
WORD wBitCount; // Bits per pixel 描述图像的颜色深度
DWORD dwBytesInRes; // How many bytes in this resource? 数据字节数
DWORD dwImageOffset; // Where in the file is this image? 描述图像的偏移量,实际位置
ICONDIRENTRY, *LPICONDIRENTRY;
bColorCount; 它被假定的认为等于图像的颜色数量。
也就是说:bColorCount = 1 << (wBitCount * wPlanes)
如果 wBitCount * wPlanes大于等于8,则bColorCount为0。
读取完这部分数据后,就可以知道文件中每个图标的大小,颜色位数了,同时直接根据数据段的偏移,读取图像数据段。图像数据的偏移是从文件最开始算起的。
图像数据头段
struct BITMAPINFOHEADER bmiHeader
NO.3
紧接着文件头的就是图像数据头段了,它存放着文件中每个图像宽度、高度、颜色数量、数据段的偏移等信息,大小为40字节。
它是一个数组,每项数据16字节,定义如下:
type def struct tag
BITMAPINFOHEADER{
DWORD biSize; 数据块大小40
LONG biWidth; 图像宽度
LONG biHeight; 2*图像高度,XOR掩码区和AND掩码区高度之和
WORD biPlanes; 指定目标设备的平面数。此值必须设置为 1。
WORD biBitCount; 位深度
DWORD biCompression; 这个值没有用到,为0
DWORD biSizeImage; 掩码数据区的大小(XOR和AND)
LONG biXPelsPerMeter; 定位图的目标设备的水平分辨率(以像素/米为单位)X坐标热点,与Y同为0代表左上角
LONG biYPelsPerMeter; 定位图的目标设备的垂直分辨率(以像素/米为单位)Y坐标热点
DWORD biClrUsed; 实际使用颜色索引,在ico中值为0
DWORD biClrImportant; 重要的颜色索引,在ico中为0
BITMAPINFOHEADER, *PBITMAPINFOHEADER;
图像数据段struct IMAGEDATA data
NO.4
接下来的这部分的结构如下,这个部分代表了颜色。
type def struct tag RGBQUAD {
BYTE rgbBlue; 蓝
BYTE rgbGreen; 绿
BYTE rgbRed; 红
BYTE rgbReserved; 保留位,一般为0
RGBQUAD;
下面的maskline是掩码区。
提问:为什么这里是8个,跟上面的64个不相同的个数呢?
掩码区使用01代表该颜色存不存在,也就是使用00和FF黑白二色表示,可以将其理解为位深度为1的图片,使用1个bit就能代表一个黑或白的颜色,假设FE转成二进制就是11111110,每一个就是8个可以与上面对应,这个也可以解释为什么下面的mask区域还有非00,非FF的。
也就是说掩码区的作用是代表着这个地方的颜色透不透明。
详细参考下图中的第二行,Q代表这个颜色是Q。
最后的mask的部分,可以继续查看这篇文章:
The evolution of the ICO file format, part 2: Now in color! - The Old New Thing (microsoft.com)
至于为什么在介绍鼠标指针文件格式解析时要先介绍ico图标,我会在后续文章中进行揭秘。
最最后的无奖提问环节:计算机是怎么实现图片的透明显示的呢?
答案我会在下一篇中揭晓。
to be continued....
声明
NO.5
本文作者:be7a
本文编辑:Yusa
感谢be7a师傅 (๑•̀ㅂ•́)و✧
往期回顾
扫码关注我们
天虞实验室为赛宁网安旗下专业技术团队,重点攻关公司业务相关信息安全前沿技术。
原文始发于微信公众号(天虞实验室):鼠标指针文件格式解析——Windows(一)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论