[原创]文件Fuzz教程之三:Peach实战之gif文件格式
发表于:
2013-7-31 16:46
6919
[原创]文件Fuzz教程之三:Peach实战之gif文件格式
RT
文件Fuzz教程第三篇文件 Fuzz 教程之三:Peach 实战之 gif 文件格式
Author:dragonltxgif 文件格式简介
GIF 文件结构的典型结构如图所示:
图 1 GIF 文件结构
数据块可分成 3 类:控制块(Control Block),图形描绘块(Graphic-Rendering
Block)和专用块(Special Purpose Block)。
(1) 控制块:控制块包含有用来控制数据流(Data Stream)或者设置硬件参数的信
息,其成员包括:
GIF 文件头(Header)
逻辑屏幕描述块(Logical Screen Descriptor)
图形控制扩展块(Graphic Control Extension)
文件结束块(Trailer)
(2) 图形描绘块:包含有用来描绘在显示设备上显示图形的信息和数据,其成员
包括:
图像描述块(Image Descriptor)
无格式文本扩展块(Plain Text Extension)
全局调色板、局部调色板、图像压缩数据和图像说明扩充块。
(3) 特殊用途数据块:包含有与图像处理无关的信息,其成员包括:
注释扩展块(Comment Extension)
应用扩展块(Application Extension)
除了在控制块中的逻辑屏幕描述块(Logical Screen Descriptor)和全局彩色表
(Global Color Table)的作用范围是整个数据流(Data Stream)之外, 所有其他控制
块仅跟在它们后面的图形描绘块。
注:建议跟 gif 010 Editor 模版进行对照阅读。Gif 文件头
文件头描述块(Header)定义 GIF 数据流(GIF Data Stream),它的结构如图 6-02 所
示。文件头描述块(Header)由 GIF 标记域(Signature)和版本号(Version)域组成,是
一个由 6 个固定字节组成的数据块,它们用来说明使用的文件格式是 GIF 格式
及当前所用的版本号。GIF 标记域(Signature)存放的是“GIF”,版本号域存放的是
1987 年 5 月发布的“87a”或者 1989 年 7 月发布的“89a”,或者更加新的版本号。
图 2 标记/版本数据块的结构
typedef struct gifheader
{
BYTE bySignature[3];
BYTE byVersion[3];
} GIFHEADER;
对应的 Peach 模型如下:
<DataModel name = "GifHeader" minOccurs="1" maxOccurs="1">
<Blob name="strSignature" length="3" valueType="hex" value="474946" token="true" mutable="false"/>
<Blob name="strVersion" length="3"/>
</DataModel>
typedef struct gifscrdesc
{
WORD wWidth;
WORD wDepth;
struct globalflag
{
BYTE PalBits : 3;
BYTE SortFlag : 1;
BYTE ColorRes : 3;
BYTE GlobalPal : 1;
} GlobalFlag;
BYTE byBackground;
BYTE byAspect;
} GIFSCRDESC;
if (LogicalScreenDescriptor.PackedFields.GlobalColorTableFlag == 1) {
SetBackColor( 0xC0C0C0 );
struct GLOBALCOLORTABLE {
local int i;
local int size = 1;
for (i = 0; i <= LogicalScreenDescriptor.PackedFields.SizeOfGlobalColorTable; i++) {
size *= 2;
}
RGB rgb[size];
} GlobalColorTable <optimize=false>;;
}
<DataModel name = "LogicalScreenDescriptor">
<Number name="Width" size="16" endian="little" signed="false"/>
<Number name="Height" size="16" endian="little" signed="false"/>
<Flags name="PackedFields" size="8">
<Flag name="GlobalColorTableFlag" position="7" size="1"/>
<Flag name="ColorResolution" position="4" size="3"/>
<Flag name="SortFlag" position="3" size="1"/>
<Flag name="SizeOfGlobalColorTable" position="0" size="3"/>
</Flags>
<Number name="BackgroundColorIndex" size="8" endian="little" signed="false"/>
<Number name="PixelAspectRatio" size="8" endian="little" signed="false"/>
<Block name = "GlobalColorTable" minOccurs="0" maxOccurs="1">
<Relation type="when" when="self.find('PackedFields.GlobalColorTableFlag').getInternalValue() == 1"/>
<!--Block name = "RGB">
<Blob name="Red" length="1"/>
<Blob name="Green" length="1"/>
<Blob name="Blue" length="1"/>
</Block-->
<Blob lengthType="calc" length="3*(2**(int(self.find('PackedFields.SizeOfGlobalColorTable').getInternalValue())+1))" />
</Block>
</DataModel>
struct IMAGEDESCRIPTOR {
UBYTE ImageSeperator;
ushort ImageLeftPosition;
ushort ImageTopPosition;
ushort ImageWidth;
ushort ImageHeight;
struct IMAGEDESCRIPTOR_PACKEDFIELDS {
UBYTE LocalColorTableFlag : 1;
UBYTE InterlaceFlag : 1;
UBYTE SortFlag : 1;
UBYTE Reserved : 2;
UBYTE SizeOfLocalColorTable : 3;
} PackedFields;
} ImageDescriptor;
<DataModel name = "ImageDescriptor">
<Blob name="ImageSeperator" length="1" valueType="hex" value="2c" token="true" mutable="false"/>
<Number name="ImageLeftPosition" size="16" endian="little" signed="false"/>
<Number name="ImageTopPosition" size="16" endian="little" signed="false"/>
<Number name="ImageWidth" size="16" endian="little" signed="false"/>
<Number name="ImageHeight" size="16" endian="little" signed="false"/>
<Flags name="PackedFields" size="8">
<Flag name="LocalColorTableFlag" position="7" size="1"/>
<Flag name="InterlaceFlag" position="6" size="1"/>
<Flag name="SortFlag" position="5" size="1"/>
<Flag name="Reserved" position="3" size="2"/>
<Flag name="SizeOfLocalColorTable" position="0" size="3"/>
</Flags>
<Block name = "LocalColorTable" minOccurs="0" maxOccurs="1">
<Relation type="when" when="self.find('PackedFields.LocalColorTableFlag').getInternalValue() == 1"/>
<!--Block name = "RGB">
<Blob name="Red" length="1"/>
<Blob name="Green" length="1"/>
<Blob name="Blue" length="1"/>
</Block-->
<Blob lengthType="calc" length="3*(2**(int(self.find('PackedFields.SizeOfLocalColorTable').getInternalValue())+1))
" />
</Block>
</DataModel>
<DataModel name = "DataSubBlocks">
<Choice maxOccurs="3000">
<Block name = "DataSubBlock">
<Relation type="when" when="self.find('Size').getInternalValue != 0"/>
<Number name="Size" size="8" endian="little" signed="false">
<Relation type="size" of="Data"/>
</Number>
<Blob name="Data"/>
</Block>
</Choice>
<Blob name="BlockTerminator" length="1" valueType="hex" value="00" mutable="false"/>
</DataModel>
<DataModel name = "ImageData">
<Number name="LZWMinimumCodeSize" size="8" endian="little" signed="false"/>
<Block ref="DataSubBlocks"/>
</DataModel>
<DataModel name = "GraphicControlExtension">
<Blob name="ExtensionIntroducer" length="1" valueType="hex" value="21" token="true" mutable="false"/>
<Blob name="GraphicControlLabel" length="1" valueType="hex" value="f9" token="true" mutable="false"/>
<Block name = "GraphicControlSubBlock">
<Number name="BlockSize" size="8" endian="little" signed="false"/>
<Flags name="PackedFields" size="8">
<Flag name="Reserved" position="5" size="3"/>
<Flag name="DisposalMethod" position="2" size="3"/>
<Flag name="UserInputFlag" position="1" size="1"/>
<Flag name="TransparentColorFlag" position="0" size="1"/>
</Flags>
<Number name="DelayTime" size="16" endian="little" signed="false"/>
<Number name="TransparentColorIndex" size="8" endian="little" signed="false"/>
</Block>
<Blob name="BlockTerminator" length="1" valueType="hex" value="00" mutable="false"/>
</DataModel>
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
上传的附件: