Question

I'm creating a WinForm Application in C# that I can use to "sniff out" some 24 bit bitmaps in a file. I already gathered information such as its offset, some analysis on how it is written in the file, and its length.

So more information about the file are:

  • The BMP data is written reversely. (Example : (255 0 0) is written (0 0 255)
  • It has no BMP header. Only chunks of BMP's image data.
  • PixelFormat is 24 bit.
  • Its BMP is pure magenta. (255 0 255 in RGB)

I'm using the following code :

            using (FileStream fs = new FileStream(@"E:\MyFile.exe", FileMode.Open))
            {
                    int width = 190;
                    int height = 219;
                    int StartOffset = 333333;   // Just a sample offset

                    Bitmap tmp_bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                    Rectangle rect = new Rectangle(0, 0, tmp_bitmap.Width, tmp_bitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData =
                        tmp_bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
                        tmp_bitmap.PixelFormat);

                    unsafe
                    {
                        // Get address of first pixel on bitmap.
                        byte* ptr = (byte*)bmpData.Scan0;

                        int bytes = width * height * 3; //124830 [Total Length from 190x219 24 Bit Bitmap]

                        int b;  // Individual Byte

                        for (int i = 0; i < bytes; i++)
                        {
                            fs.Position = StartOffset - i;  // Change the fs' Position [Subtract since I'm reading in reverse]
                            b = fs.ReadByte();              // Reads one byte from its position

                            *ptr = Convert.ToByte(b);   // Record byte
                            ptr ++;
                        }
                        // Unlock the bits.
                        tmp_bitmap.UnlockBits(bmpData);
                    }
                    pictureBox1.Image =  tmp_bitmap;
                }

I get this output. I think the reason is that the bytes are getting messed up whenever it hit the next line. (255 0 255 becomes 0 255 255 and it goes on until it becomes 255 255 0)

Output

I hope you can help me fix this. Thank you very much in advance.

SOLUTION Now it is fixed by adding this code (with some help from my friend and information given by James Holderness)

if (width % 4 != 0)
    if ((i + 1) % (width * 3) == 0 && (i + 1) * 3 % width < width - 1)
         ptr += 2;

Thank you very much!

Was it helpful?

Solution

For a standard BMP, each individual scan line needs to be a multiple of 4 bytes, so when you have a 24 bit image (3 bytes per pixel), you often need to allow for padding at the end of every scan line to bring it up to a multiple of 4.

For example, if your width if 150 pixels, that's 450 bytes, which needs to be rounded up to 452 to make it a multiple of 4.

I suspect that might be the problem you're having here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top