FastStone Image Viewer (FSViewer.exe) v. <= 7.5
FastStone Image Viewer v.7.5 and prior are affected by a Stack-based Buffer Overflow at 0x005BDF49, affecting the CUR file parsing functionality ('BitCount' file format field), that will end up corrupting the Structure Exception Handler (SEH). Attackers could exploit this issue to achieve code execution when a user opens or views a malformed/specially crafted CUR file.
@@ -0,0 +1,157 @@
|
||||
//------------------------------------------------
|
||||
//--- 010 Editor v2.0 Binary Template
|
||||
//
|
||||
// File: CUR.bt
|
||||
// Authors: Paolo Stagno aka VoidSec (https://voidsec.com)
|
||||
// Version: 0.1
|
||||
// Purpose: Defines a template for parsing cursor image files.
|
||||
// Category: Image
|
||||
// File Mask: *.CUR
|
||||
// ID Bytes: 00 00 02 00
|
||||
// History:
|
||||
// 0.1 2021-03-09 Paolo Stagno: Initial Structures Release
|
||||
//
|
||||
// Based on ICO.bt from SweetScape Software
|
||||
// Does not support PNG cursor images
|
||||
// Ref: https://www.daubnet.com/en/file-format-cur
|
||||
//------------------------------------------------
|
||||
|
||||
typedef struct {
|
||||
WORD idReserved <fgcolor=cRed, bgcolor=cBlack, name="Reserved", comment="Reserved (must be 0)">;
|
||||
WORD idType <fgcolor=cRed, name="Type", comment="Resource Type (1 for icons, 2 for cursors)">;
|
||||
} SIGNATURE;
|
||||
|
||||
typedef struct { // List of cursors
|
||||
BYTE bWidth <name="Width", comment="Cursor Width (in pixels)">;
|
||||
BYTE bHeight <name="Height", comment="Cursor Height (in pixels)">;
|
||||
BYTE bColorCount <name="ColorCount", comment="Number of colors in image (0 if >=8bpp)">;
|
||||
BYTE bReserved <fgcolor=cBlack, name="Reserved", comment="must be 0">;
|
||||
WORD XHotspot <name="XHotspot", comment="Hotspot's X-Position">;
|
||||
WORD YHotspot <name="YHotspot", comment="Hotspot's Y-Position">;
|
||||
DWORD dwBytesInRes <name="SizeInBytes", comment="How many bytes in this resource?">; // Size of (InfoHeader + ANDBitmap + XORBitmap)
|
||||
DWORD dwImageOffset <name="FileOffset", comment="Where in the file is this image?">; // FilePos, where InfoHeader starts
|
||||
} CURDIRENTRY <read=ReadCURDIRENTRY>;
|
||||
|
||||
typedef struct { // RGBq
|
||||
UBYTE rgbBlue <bgcolor=cBlue, fgcolor=cLtBlue, name="rgbBlue">;
|
||||
UBYTE rgbGreen <bgcolor=cGreen, fgcolor=cLtGreen, name="rgbGreen">;
|
||||
UBYTE rgbRed <bgcolor=cRed, fgcolor=cLtRed, name="rgbRed">;
|
||||
UBYTE rgbReserved <fgcolor=cBlack, name="Reserved">;
|
||||
} RGBQUAD <read=ReadRGBQUAD, name="Colors", comment="RGBQUAD">;
|
||||
|
||||
typedef struct { // RGBt
|
||||
UBYTE rgbBlue <bgcolor=cBlue, fgcolor=cLtBlue, name="rgbtBlue">;
|
||||
UBYTE rgbGreen <bgcolor=cGreen, fgcolor=cLtGreen, name="rgbtGreen">;
|
||||
UBYTE rgbRed <bgcolor=cRed, fgcolor=cLtRed, name="rgbtRed">;
|
||||
} RGBTRIPLE <read=ReadRGBTRIPLE, name="Colors", comment="RGBTRIPLE">;
|
||||
|
||||
typedef struct { // BMIH
|
||||
DWORD biSize <name="Size", comment="Size of InfoHeader structure (commonly 40h)">;
|
||||
LONG biWidth <name="Width", comment="Cursor Width">;
|
||||
LONG biHeight <name="Height", comment="Cursor Height">; // added height of XORbitmap and ANDbitmap
|
||||
WORD biPlanes <name="Planes", comment="Number of planes">;
|
||||
WORD biBitCount <name="BitCount", comment="Bits per pixel">;
|
||||
DWORD biCompression <name="Compression", comment="Type of Compression">;
|
||||
DWORD biSizeImage <name="ImageSize", comment="Size of Image in Bytes">; // 0 = uncompressed
|
||||
LONG biXPelsPerMeter <name="XpixelsPerM", comment="unused">;
|
||||
LONG biYPelsPerMeter <name="YpixelsPerM ", comment="unused">;
|
||||
DWORD biClrUsed <name="ColorsUsed", comment="unused">;
|
||||
DWORD biClrImportant <name="ColorsImportant", comment="unused">;
|
||||
} BITMAPINFOHEADER;
|
||||
|
||||
typedef struct {
|
||||
// Define the color table
|
||||
if( (bmiHeader.biBitCount != 24) && (bmiHeader.biBitCount != 32) ) {
|
||||
if( bmiHeader.biClrUsed > 0 ) {
|
||||
RGBQUAD aColors[ bmiHeader.biClrUsed ];
|
||||
}else{
|
||||
RGBQUAD aColors[ 1 << bmiHeader.biBitCount ];
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate bytes per line and padding required
|
||||
local int bytesPerLine = (int)Ceil( bmiHeader.biWidth * bmiHeader.biBitCount / 8.0 );
|
||||
local int padding = 4 - (bytesPerLine % 4);
|
||||
if( padding == 4 ) {
|
||||
padding = 0;
|
||||
}
|
||||
|
||||
// Define each line of the image
|
||||
struct BITMAPLINE {
|
||||
|
||||
// Define color data
|
||||
if( bmiHeader.biBitCount < 8 ) {
|
||||
UBYTE imageData[ bytesPerLine ];
|
||||
}else if( bmiHeader.biBitCount == 8 ) {
|
||||
UBYTE colorIndex[ bmiHeader.biWidth ];
|
||||
}else if( bmiHeader.biBitCount == 24 ) {
|
||||
RGBTRIPLE colors[ bmiHeader.biWidth ];
|
||||
}else if( bmiHeader.biBitCount == 32 ) {
|
||||
RGBQUAD colors[ bmiHeader.biWidth ];
|
||||
}
|
||||
// Pad if necessary
|
||||
if( padding != 0 ) {
|
||||
UBYTE padBytes[ padding ];
|
||||
}
|
||||
} lines[ bmiHeader.biHeight/2 ]<optimize=false>;
|
||||
|
||||
// Define each line of the mask
|
||||
struct MASKLINE {
|
||||
UBYTE line[((bmiHeader.biWidth + 31)/32)*4]<format=hex>;
|
||||
}mask[bmiHeader.biHeight/2]<optimize=false>;
|
||||
|
||||
}IMAGEDATA;
|
||||
|
||||
typedef struct {
|
||||
SetBackColor( cAqua );
|
||||
BITMAPINFOHEADER bmiHeader <name="InfoHeader", comment="Variant of BMP InfoHeader ">;
|
||||
SetBackColor( cDkGray );
|
||||
IMAGEDATA data <name="Image Data">;
|
||||
}CURIMAGE <read=ReadDIBHeader>;
|
||||
|
||||
//---------------------------------------------
|
||||
// Custom read functions - this allows the data to be displayed without having to open up the structure.
|
||||
|
||||
string ReadCURDIRENTRY( CURDIRENTRY &dirEntry ) {
|
||||
string s;
|
||||
SPrintf( s, "%dx%d %d colors", dirEntry.bWidth, dirEntry.bHeight, dirEntry.bColorCount );
|
||||
return s;
|
||||
}
|
||||
|
||||
string ReadDIBHeader( CURIMAGE &image ) {
|
||||
string s;
|
||||
SPrintf( s, "%dx%d %dbit", image.bmiHeader.biWidth, image.bmiHeader.biHeight, image.bmiHeader.biBitCount );
|
||||
return s;
|
||||
}
|
||||
|
||||
string ReadRGBQUAD( RGBQUAD &a ) {
|
||||
string s;
|
||||
SPrintf( s, "#%02X%02X%02X%02X", a.rgbReserved, a.rgbRed, a.rgbGreen, a.rgbBlue );
|
||||
return s;
|
||||
}
|
||||
|
||||
string ReadRGBTRIPLE( RGBTRIPLE &a ) {
|
||||
string s;
|
||||
SPrintf( s, "#%02X%02X%02X", a.rgbRed, a.rgbGreen, a.rgbBlue );
|
||||
return s;
|
||||
}
|
||||
//---------------------------------------------
|
||||
|
||||
// Define the headers
|
||||
LittleEndian();
|
||||
|
||||
local short res = ReadShort( FTell() );
|
||||
local short type = ReadShort(FTell() +2 );
|
||||
|
||||
//Check cursor
|
||||
if( res != 0 || type != 2) {
|
||||
Warning( "File is not an Cursor. Template stopped." );
|
||||
return -1;
|
||||
}
|
||||
|
||||
SetBackColor( cNone );
|
||||
SIGNATURE signature <name="Signature", comment="CUR Magic Bytes">;
|
||||
WORD idCount <fgcolor=cYellow, name="Image Count", comment="How many embedded images?">;
|
||||
CURDIRENTRY idEntries[idCount] <bgcolor=cBlue, name="Entries", comment="List of Cursors in the file">;
|
||||
// https://www.sweetscape.com/010editor/manual/ArraysDuplicates.htm#Optimizing%20Arrays%20of%20Structs
|
||||
CURIMAGE images[idCount] <optimize=false, name="Image">;
|
||||
|
After Width: | Height: | Size: 133 KiB |
|
After Width: | Height: | Size: 766 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 338 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 816 B |
|
After Width: | Height: | Size: 183 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 170 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 867 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 283 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 919 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 133 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 196 B |
|
After Width: | Height: | Size: 177 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 161 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 500 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 690 B |
|
After Width: | Height: | Size: 1.6 KiB |