6

foreword

"How to chat without emoji?"

As an artifact to break the dilemma of human communication, there is no scene that a meme cannot express. Imagine, when you are opening N VSCodes at the same time and frantically coding, there is a crisp sound of DING~, and the product manager sends a message: Have the bugs mentioned yesterday been fixed?​

Based on the principle of "you can send pictures without typing", it's time to bring out the big killer in your favorites↓

DOING.gif

Simple GIFs create a space for communication that moves forward and backward, and these GIFs are what we usually use as GIFs.

business background

However, in the risk control scenario, Heishai uses the multi-frame feature of GIF pictures to inject illegal pictures into them, and then disguise them as ordinary pictures by manually modifying the file extension, which undoubtedly increases the difficulty of risk prevention and control. The illegal main image that flashed by makes it hard for the operator to guard against it; the picture is finally fixed on the tail frame that seems to be no problem, making it difficult for the operator to capture the effective key information.

原图.jpg

Although GIF pictures have a "moving" nature, they are treated as pictures in the Web without discrimination, and no special treatment API is provided, so it is impossible to control events such as playback, pause, and end monitoring of GIF pictures . So is there any way to "move" the GIF that flashes and freezes at the end frame? Next, let’s delve deeper and analyze that there are magic horses in GIF pictures.

Introduction to GIF format

Graphics Interchange Format (GIF) is a bit graphic file format that reproduces true-color images in 8-bit colors (ie, 256 colors). The GIF file is internally divided into many storage blocks to store multiple images. An image or a control block that determines the behavior of an image to implement animations and interactive applications. GIF has two versions, GIF87a and GIF89a.

GIF is a bitmap. The general principle of a bitmap is that a picture is composed of many pixels, each pixel is assigned a color, and these pixels are combined to form a picture. The 8-bit "bit" is the color depth. The color depth is determined by the bit depth of an image. In simple terms, it is the maximum number of colors supported (for example, a pixel with a bit depth of 1 has two values: black and white. Bit The greater the depth, the more colors the image can contain, and the more accurate the color representation, 8-bit GIF image contains up to 256 colors)​

The GIF87a version was launched in 1987. One file stores one image and strictly does not support transparent pixels; GIF87a uses the LZW compression algorithm, which can compress the image size by 20 to 25 percent while maintaining the image quality.​

The GIF89a version is a very distinctive version launched in 1989. This version allows one file to store multiple images, can achieve animation function , and allows some pixels to be transparent. In this version, four blocks of graphic control block, remarks, description, and application programming interface are expanded for GIF documents, and support for transparent color and multi-frame animation is provided. If these images are played continuously, you can Make up the simplest animation possible. Therefore, it is often used to store "dynamic pictures", which are usually short in time, small in size, simple in content, and relatively clear in imaging. The first version of the GIF we are talking about now is in the 89a format.

GIF file structure disassembly

To understand how an image "moves", first understand how it is stored. Let's refer to a picture on the Internet to see the image file structure in GIF format:

image.png

Image credit: What's In A GIF

Files in GIF format are stored in blocks, which are generally divided into three parts:

  • File header (Header)
  • GIF Data Stream
  • End of file (Trailer)

Among them, we skip the text extension block, application extension block and comment extension block in the data stream, and the secret to "moving" the picture exists in the Graphic Control Extension (Graphic Control Extension) . Let's use a chestnut to find out.

Sample preparation

Sample image

Opening the visible picture will have a momentary flickering effect.

hex converter

Portal

file header

Identifying whether a picture is a GIF does not only depend on the extension format of the picture or whether the picture will move. The first 6 bytes of the GIF file are the signature and version number of the GIF. By printing on the console, we can get:

image.png contrast ASCII encoding we can get 47 49 46 38 39 61 corresponding to GIF 89a

Simple! Continue to look down↓

GIF data stream

Graphics Control Extensions

It is not difficult to find through observation that the picture will have the effect of flashing instantly. Compared with the emoji picture at the beginning of the article, why some GIF pictures can be played in a loop all the time, while some flashes instantly and then freezes in the second frame?​

In version 89a, GIF adds a graphic control extension block, which is placed in front of the image identifier (Image Descriptor) to control the display of the first image immediately following it. The structure of the graphic control extension block is shown in the figure below. Show:

image.png

As can be seen from the above figure, the entire extension block structure is as follows:

describelength
Extended block identifier1 byte, fixed value 0x21
Extended block ID1 byte, fixed value 0xF9
Extended block subblock length1 byte
reserved bit3 digits
Disposal method3 digits
user input flag1 person
transparent color sign1 person
delay2 bytes
Transparent Color Index1 byte
extended block trailer1 byte, fixed value 0x00

Found it! The culprit is the delay time! delay time marks the need to pause this delay time before continuing to process the data stream, which can be understood as the dwell time of each frame in the animation, and its unit is 1/100 second.​

At this point of analysis, there is a feeling of stunned. Back in the code, we can see through the console that the data parsed from the original image is like this:

image.png

Delay time: 00 00, hexadecimal conversion to decimal: 0​

By manually setting the delay time, we can make the flashed pictures "move":

image.png

Delay time after manual modification: 32 00, converted from hexadecimal to decimal: 800

The core code is as follows:

let p = 0; // 当前 Buffer 处理对应的下标

while (notEndOfFile && p < contentBuffer.length) {
  ...
  
    switch (contentBuffer[p++]) {
    case 0xf9:  // Graphics Control Extension
      if (contentBuffer[p++] !== 0x4 || contentBuffer[p+4] !== 0)
        throw new Error("Invalid graphics extension block.");
      p++; // graphicPackedFiled
      if (delay) {
        const delayArr = numberToByteArr(delay);
        contentBuffer[p] = delayArr[delayArr.length - 1];
        contentBuffer[p+1] = delayArr[delayArr.length - 2] || 0;
      }
      p = p + 4; // 略过 delay 2 字节, transparentIndex 1 字节,结束符号 1字节
      break;
  }
}

end of file

image.png

When all the sub-image data is parsed, the end of the file is encountered. This part has only one byte with a value of 0, which marks the end of a GIF file. End of file is fixed at 0x3B

write at the end

In the last article on solving image cross-domain, the author introduced that with the help of the team's serverless capabilities to build a cross-domain image forwarding server, this GIF file parsing solution is built on the basis of the original BFF layer capabilities.​

Octopus Image Forwarding Service

请求地址:https://xxx.fc.alibaba-inc.com/gifTransformer
请求方法:GET
参数:
url: 必传,需要解析的图片地址
loop: 非必传,GIF 图循环次数
delay: 非必传,GIF 图每一帧播放时间(ms)

返回结果:解析后的 GIF 图

GIF image analysis finally implements the risk investigation business, which solves the difficult problem of determining the illegal main image produced by black and gray, which has been a headache for the business. Interested students may wish to try it out.

Reference link

Author: ES2049 | Black Eyed Peas

The article can be reproduced at will, but please keep the original link.
Passionate you are very welcome to join ES2049 Studio , please send your resume to caijun.hcj@alibaba-inc.com .


ES2049
3.7k 声望3.2k 粉丝