Dump2Picture v1.1 source code

Since the first release of Dump2Picture I was under pressure to publish its source code and today I released it under GPL. I have to apologize that it doesn’t always use secure string manipulation functions, error handling is copy/pasted several times and there are no comments. I promise better code in the next version. :-)

If you plan to make changes and improvements please let me know so I could enjoy your versions of memory visuals too. I used ancient Visual C++ 6.0 to compile and build the project.

// Dump2Picture version 1.1 (c) Dmitry Vostokov
// GNU GENERAL PUBLIC LICENSE
// http://www.gnu.org/licenses/gpl-3.0.txt

#include <math.h>
#include <iostream>
#include <process.h>
#include <windows.h>

BITMAPFILEHEADER bmfh = { 'MB', 0, 0, 0,
   sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) };
BITMAPINFOHEADER bmih = { sizeof(BITMAPINFOHEADER), 0, 0, 1, 32,
   0, 0, 0, 0, 0, 0 };
RGBQUAD rgb[256];

void DisplayError (LPCSTR szPrefix)
{
 LPSTR errMsg;
 CHAR  szMsg[256];
 strncpy(szMsg, szPrefix, 128);
 DWORD gle = GetLastError();
 if (gle && FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
    NULL, gle, 0, (LPSTR)&errMsg, 0, NULL))
 {
  strcat(szMsg, ": ");
  strncat(szMsg, errMsg, 120);
 }  
 std::cout << szMsg << std::endl;
 LocalFree(errMsg);
}

int main(int argc, char* argv[])
{
 std::cout << std::endl << "Dump2Picture version 1.1"
    << std::endl << "Written by Dmitry Vostokov, 2007"
    << std::endl << std::endl;
 if (argc < 3)
 {
  std::cout << "Usage: Dump2Picture dumpfile bmpfile [8|16|24|32]" << std::endl;
  return -1;
 }

 HANDLE hFile = CreateFile(argv[1], GENERIC_READ,
    FILE_SHARE_READ, NULL, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, NULL);
 if (hFile == INVALID_HANDLE_VALUE)
 {
  DisplayError("Cannot read dump file"); 
  return -1;
 }

 DWORD dwDumpSizeHigh = 0;
 DWORD dwDumpSizeLow = GetFileSize(hFile, &dwDumpSizeHigh);
 CloseHandle(hFile);

 if (dwDumpSizeHigh)
 {
  std::cout << "The dump file must be less than 4Gb"
     << std::endl;
  return -1;
 }

 if (argc == 4)
 {
  if (!strcmp(argv[argc-1],"8"))
  {
   bmih.biBitCount = 8;
   for (int i = 0; i < 256; ++i)
   {
    rgb[i].rgbBlue = rgb[i].rgbGreen = rgb[i].rgbRed = i;
    rgb[i].rgbReserved = 0;
   }
  }
  else if (!strcmp(argv[argc-1],"16"))
  {
   bmih.biBitCount = 16;
  }
  else if (!strcmp(argv[argc-1],"24"))
  {
   bmih.biBitCount = 24;
  }
  else
  {
   bmih.biBitCount = 32;
  }
 }

 bmih.biWidth = bmih.biHeight = sqrt((double)(dwDumpSizeLow/
    (bmih.biBitCount/8)));
 bmih.biWidth -= bmih.biWidth%2;
 if (bmih.biBitCount == 8 )
 {
  bmih.biWidth -= bmih.biWidth%8;
 }
 bmih.biHeight -= bmih.biHeight%2;
 bmih.biSizeImage = bmih.biWidth*bmih.biHeight*
    (bmih.biBitCount/8);
 if (bmih.biBitCount == 8 )
 {
  bmfh.bfOffBits += sizeof(rgb);
 }
 bmfh.bfSize = bmfh.bfOffBits + bmih.biSizeImage;

 hFile = CreateFile(argv[2], GENERIC_WRITE, 0, NULL,
    CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
 if (hFile == INVALID_HANDLE_VALUE)
 {
  DisplayError("Cannot create bitmap header file"); 
  return -1;
 }

 DWORD dwWritten;
 if (!WriteFile(hFile, &bmfh, sizeof(bmfh), &dwWritten, NULL))
 {
  DisplayError("Cannot write bitmap header file"); 
  CloseHandle(hFile);
  return -1;
 }

 if (!WriteFile(hFile, &bmih, sizeof(bmih), &dwWritten, NULL))
 {
  DisplayError("Cannot write bitmap header file"); 
  CloseHandle(hFile);
  return -1;
 }

 if (bmih.biBitCount == 8 )
 {
  if (!WriteFile(hFile, &rgb, sizeof(rgb), &dwWritten, NULL))
  {
   DisplayError("Cannot write bitmap header file"); 
   CloseHandle(hFile);
   return -1;
  }
 }
 
 CloseHandle(hFile);

 std::string str = "copy \"";
 str += argv[2];
 str += "\" /B + \"";
 str += argv[1];
 str += "\" /B \"";
 str += argv[2];
 str += "\" /B";

 system(str.c_str());
 
 return 0;
}

- Dmitry Vostokov @ DumpAnalysis.org -

Leave a Reply

You must be logged in to post a comment.