PDIBITMAP DibLoadImage(LPTSTR lpFilename) { PDIBITMAP lpBitmap; GpBitmap *bitmap; BitmapData lock; if (GdipCreateBitmapFromFile(lpFilename, &bitmap) != Ok) { return NULL; } lpBitmap = HeapAlloc(GetProcessHeap(), 0, sizeof(DIBITMAP)); if (lpBitmap == NULL) { GdipDisposeImage((GpImage*)bitmap); return NULL; } lpBitmap->info = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFO)); if (lpBitmap->info == NULL) { HeapFree(GetProcessHeap(), 0, lpBitmap); GdipDisposeImage((GpImage*)bitmap); return NULL; } if (GdipGetImageWidth((GpImage*)bitmap, &lpBitmap->width) != Ok || GdipGetImageHeight((GpImage*)bitmap, &lpBitmap->height) != Ok) { HeapFree(GetProcessHeap(), 0, lpBitmap->info); HeapFree(GetProcessHeap(), 0, lpBitmap); GdipDisposeImage((GpImage*)bitmap); return NULL; } lpBitmap->bits = HeapAlloc(GetProcessHeap(), 0, lpBitmap->width * lpBitmap->height * 4); if (!lpBitmap->bits) { HeapFree(GetProcessHeap(), 0, lpBitmap->info); HeapFree(GetProcessHeap(), 0, lpBitmap); GdipDisposeImage((GpImage*)bitmap); return NULL; } ZeroMemory(lpBitmap->info, sizeof(BITMAPINFO)); lpBitmap->info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpBitmap->info->bmiHeader.biWidth = lpBitmap->width; lpBitmap->info->bmiHeader.biHeight = -(INT)lpBitmap->height; lpBitmap->info->bmiHeader.biPlanes = 1; lpBitmap->info->bmiHeader.biBitCount = 32; lpBitmap->info->bmiHeader.biCompression = BI_RGB; lpBitmap->info->bmiHeader.biSizeImage = lpBitmap->width * lpBitmap->height * 4; lock.Width = lpBitmap->width; lock.Height = lpBitmap->height; lock.Stride = lpBitmap->width * 4; lock.PixelFormat = PixelFormat32bppPARGB; lock.Scan0 = lpBitmap->bits; lock.Reserved = 0; if (GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead | ImageLockModeUserInputBuf, PixelFormat32bppPARGB, &lock) != Ok) { HeapFree(GetProcessHeap(), 0, lpBitmap->bits); HeapFree(GetProcessHeap(), 0, lpBitmap->info); HeapFree(GetProcessHeap(), 0, lpBitmap); GdipDisposeImage((GpImage*)bitmap); return NULL; } GdipBitmapUnlockBits(bitmap, &lock); GdipDisposeImage((GpImage*)bitmap); return lpBitmap; }
int main (int argc, char **argv) { GpBitmap *bitmap; BitmapData d, q; Rect r; int i, j; unsigned long *lptr; unsigned char *cptr; BYTE *scan0 = (BYTE*) GdipAlloc(10 * 10 * 4); GpStatus status = GdipCreateBitmapFromScan0 (10, 10, 10 * 4, PixelFormat32bppARGB, scan0, &bitmap); CHECK_STATUS(1); printf ("Full rectangle, no format conversion, read only\n"); r.X = 0; r.Y = 0; r.Width = 10; r.Height = 10; status = GdipBitmapLockBits (bitmap, &r, ImageLockModeRead, PixelFormat32bppARGB, &d); CHECK_STATUS(1); printf ("Attempt to re-lock (should fail)\n"); status = GdipBitmapLockBits (bitmap, &r, ImageLockModeRead, PixelFormat32bppARGB, &q); CHECK_STATUS(0); printf ("Unlock\n"); status = GdipBitmapUnlockBits (bitmap, &d); CHECK_STATUS(1); /* lptr = (unsigned long *) bitmap->active_bitmap->scan0; for (j = 0; j < 10; j++) { for (i = 0; i < 10; i++) { *lptr++ = j | j << 8 | i << 16 | i << 24; } } */ memset (&d, 0x00, sizeof (BitmapData)); printf ("\nHalf rectangle, no format conversion, read only\n"); r.X = 5; r.Y = 5; r.Width = 5; r.Height = 5; status = GdipBitmapLockBits (bitmap, &r, ImageLockModeRead, PixelFormat32bppARGB, &d); CHECK_STATUS(1); for (j = 0; j < 5; j++) { lptr = (unsigned long *) d.Scan0 + j * d.Stride; printf ("%d: ", j); for (i = 0; i < 5; i++) { printf ("%08lx ", *lptr++); } printf ("\n"); } printf ("Modifying (setting to 0xff)\n"); memset (d.Scan0, 0xff, d.Stride * d.Height); printf ("Unlocking\n"); status = GdipBitmapUnlockBits (bitmap, &d); CHECK_STATUS(1); /* printf ("Original data after unlock (shouldn't be 0xffffffff): 0x%08x\n", ((unsigned long *)(bitmap->active_bitmap->scan0))[55]); if (((unsigned long *)(bitmap->active_bitmap->scan0))[55] == 0xffffffff) printf ("==> FAIL!\n"); */ memset (&d, 0x00, sizeof (BitmapData)); printf ("\nHalf rectangle, 32bpp ARGB -> 32bpp RGB, read only\n"); r.X = 5; r.Y = 5; r.Width = 5; r.Height = 5; status = GdipBitmapLockBits (bitmap, &r, ImageLockModeRead, PixelFormat32bppRGB, &d); CHECK_STATUS(1); lptr = (unsigned long *) d.Scan0; for (j = 0; j < 5; j++) { printf ("%d: ", j); for (i = 0; i < 5; i++) { printf ("%08lx ", *lptr++); } printf ("\n"); } status = GdipBitmapUnlockBits (bitmap, &d); CHECK_STATUS(1); memset (&d, 0x00, sizeof (BitmapData)); printf ("\nHalf rectangle, 32bpp ARGB -> 24bpp RGB, read/write only\n"); r.X = 5; r.Y = 5; r.Width = 5; r.Height = 5; status = GdipBitmapLockBits (bitmap, &r, ImageLockModeRead | ImageLockModeWrite, PixelFormat24bppRGB, &d); CHECK_STATUS(1); for (j = 0; j < 5; j++) { cptr = (unsigned char *) (d.Scan0 + (j * d.Stride)); printf ("%d: ", j); for (i = 0; i < 5; i++) { printf ("%02x%02x%02x ", cptr[0], cptr[1], cptr[2]); cptr += 3; } printf ("\n"); } printf ("Modifying (setting to 0xaabbcc)\n"); for (j = 0; j < 5; j++) { cptr = (unsigned char *) (d.Scan0 + (j * d.Stride)); for (i = 0; i < 5; i++) { *cptr++ = 0xcc; *cptr++ = 0xbb; *cptr++ = 0xaa; } } status = GdipBitmapUnlockBits (bitmap, &d); CHECK_STATUS(1); /* printf ("Original data after Unlock (should be all 0xffaabbcc):\n"); for (j = 5; j < 10; j++) { lptr = (unsigned long *) (bitmap->active_bitmap->Scan0 + j * bitmap->active_bitmap->Stride) + 5; printf ("%d: ", j); for (i = 5; i < 10; i++) { printf ("%08x ", *lptr++); } printf ("\n"); } */ GdipFree (scan0); return 0; }
/* * SfExtractDropper * * Purpose: * * Extract Sirefef/ZeroAccess from image resource. * * CNG variant * */ UINT SfExtractDropper( LPWSTR lpCommandLine ) { BOOL cond = FALSE, bSuccess = FALSE; ULONG c, uKey = 0, imagesz; WCHAR szInputFile[MAX_PATH + 1]; WCHAR szOutputFile[MAX_PATH + 1]; WCHAR szKey[MAX_PATH]; PVOID ImageBase = NULL, EncryptedData = NULL, DecryptedData = NULL; IStream *pImageStream = NULL; ULONG_PTR gdiplusToken = 0; GdiplusStartupInput input; GdiplusStartupOutput output; PVOID BitmapPtr = NULL; GdiPlusBitmapData BitmapData; GdiPlusRect rect; SIZE_T sz; PULONG ptr, i_ptr; //input file c = 0; RtlSecureZeroMemory(szInputFile, sizeof(szInputFile)); GetCommandLineParam(lpCommandLine, 1, (LPWSTR)&szInputFile, MAX_PATH, &c); if (c == 0) { SfcuiPrintText(g_ConOut, T_SFEXTRACTUSAGE, g_ConsoleOutput, FALSE); return (UINT)-1; } //output file c = 0; RtlSecureZeroMemory(&szOutputFile, sizeof(szOutputFile)); GetCommandLineParam(lpCommandLine, 2, (LPWSTR)&szOutputFile, MAX_PATH, &c); if (c == 0) { _strcpy(szOutputFile, TEXT("extracted.bin")); } //key c = 0; RtlSecureZeroMemory(&szKey, sizeof(szKey)); GetCommandLineParam(lpCommandLine, 3, (LPWSTR)&szKey, MAX_PATH, &c); if ((c == 0) || (c > 10)) { SfcuiPrintText(g_ConOut, T_SFEXTRACTUSAGE, g_ConsoleOutput, FALSE); return (UINT)-1; } c = 0; if (locase_w(szKey[1]) == 'x') { c = 2; } uKey = hextoul(&szKey[c]); do { ImageBase = SfuCreateFileMappingNoExec(szInputFile); if (ImageBase == NULL) break; c = 0; EncryptedData = SfLdrQueryResourceData(1, ImageBase, &c); if ((EncryptedData == NULL) || (c == 0)) break; pImageStream = SHCreateMemStream((BYTE *)EncryptedData, (UINT)c); if (pImageStream == NULL) break; RtlSecureZeroMemory(&input, sizeof(input)); RtlSecureZeroMemory(&output, sizeof(output)); input.GdiplusVersion = 1; if (GdiplusStartup(&gdiplusToken, &input, &output) != GdiplusOk) break; BitmapPtr = NULL; if (GdipCreateBitmapFromStream(pImageStream, &BitmapPtr) != GdiplusOk) break; RtlSecureZeroMemory(&rect, sizeof(rect)); if ( (GdipGetImageWidth(BitmapPtr, (UINT *)&rect.Width) == GdiplusOk) && (GdipGetImageHeight(BitmapPtr, (UINT *)&rect.Height) == GdiplusOk) ) { RtlSecureZeroMemory(&BitmapData, sizeof(BitmapData)); if (GdipBitmapLockBits(BitmapPtr, &rect, ImageLockModeRead, PixelFormat32bppARGB, &BitmapData) == GdiplusOk) { c = (rect.Width * rect.Height); imagesz = sizeof(ULONG) * c; sz = imagesz; DecryptedData = NULL; NtAllocateVirtualMemory(NtCurrentProcess(), &DecryptedData, 0, &sz, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (DecryptedData) { i_ptr = (PULONG)BitmapData.Scan0; ptr = DecryptedData; while (c > 0) { *ptr = *i_ptr ^ uKey; ptr++; i_ptr++; c--; } bSuccess = (SfuWriteBufferToFile(szOutputFile, DecryptedData, imagesz, FALSE, FALSE) == imagesz); sz = 0; NtFreeVirtualMemory(NtCurrentProcess(), &DecryptedData, &sz, MEM_RELEASE); } GdipBitmapUnlockBits(BitmapPtr, &BitmapData); } } } while (cond); if (bSuccess == FALSE) { SfcuiPrintText(g_ConOut, T_SFEXTRACTFAIL, g_ConsoleOutput, FALSE); } else { SfcuiPrintText(g_ConOut, szOutputFile, g_ConsoleOutput, TRUE); SfcuiPrintText(g_ConOut, T_SFEXTRACTED, g_ConsoleOutput, TRUE); } if (BitmapPtr != NULL) { GdipDisposeImage(&BitmapPtr); } if (gdiplusToken != 0) { GdiplusShutdown(gdiplusToken); } if (pImageStream != NULL) { pImageStream->lpVtbl->Release(pImageStream); } if (ImageBase != NULL) { NtUnmapViewOfSection(NtCurrentProcess(), ImageBase); } return 0; }
int ReadTextureFromFile( struct Texture * t, const char * filename ) { int i; HGLOBAL hMem; LPVOID pMemImage; IStream *pStm; struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GpBitmap *pImg; PixelFormat PixelFormat; //Read in data FILE * f = fopen( filename, "rb"); if( !f ) { fprintf( stderr, "Error: Could not open %s\n", filename ); return -1; } fseek(f,0,SEEK_END); int l = ftell( f ); unsigned char * buffer = malloc( l ); fseek(f,0,SEEK_SET); fread(buffer, l, 1, f ); fclose( f ); //Prepare GDI+ imaging hMem = GlobalAlloc( GMEM_MOVEABLE, l ); pMemImage = GlobalLock( hMem); memcpy( pMemImage, buffer, l ); GlobalUnlock( hMem ); //XXX: This requries OLE32, do we really want it? CreateStreamOnHGlobal( hMem, TRUE, &pStm ); gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL; gdiplusStartupInput.SuppressBackgroundThread = FALSE; gdiplusStartupInput.SuppressExternalCodecs = FALSE; GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, NULL ); if( GdipCreateBitmapFromStream( pStm, &pImg ) ) { fprintf( stderr, "Error: cannot decode: %s\n", filename ); return -2; } GdipGetImagePixelFormat( (GpImage *)pImg, &PixelFormat ); UINT width; UINT height; GdipGetImageHeight( (GpImage *)pImg, &height ); GdipGetImageWidth( (GpImage *)pImg, &width ); GpRect r; r.X = 0; r.Y = 0; r.Width = width; r.Height = height; BitmapData bd; enum TextureType format; GLenum type; //Almost always GL_TEXTURE_2D (Could be GL_TEXTURE_3D) GLuint texture; int slot; //which texture slot (For multi-texturing) uint8_t * rawdata; //May be other types, too! t->width = width; t->height = height; t->type = GL_TEXTURE_2D; //Detect if has alpha or not... int ps; if( PixelFormat & PixelFormatAlpha ) { GdipBitmapLockBits(pImg,&r,ImageLockModeRead,PixelFormat32bppARGB,&bd); ps = 4; t->format = TTRGBA; } else { GdipBitmapLockBits(pImg,&r,ImageLockModeRead,PixelFormat24bppRGB,&bd); ps = 3; t->format = TTRGB; } t->rawdata = malloc( ps * width * height ); int x, y; if( ps == 3 ) { for( y = 0; y < height; y++ ) for( x = 0; x < width; x++ ) { t->rawdata[(x+y*width)*3+0] = ((unsigned char*)bd.Scan0)[x*3+y*bd.Stride+2]; t->rawdata[(x+y*width)*3+1] = ((unsigned char*)bd.Scan0)[x*3+y*bd.Stride+1]; t->rawdata[(x+y*width)*3+2] = ((unsigned char*)bd.Scan0)[x*3+y*bd.Stride+0]; } } else //ps = 4 { for( y = 0; y < height; y++ ) for( x = 0; x < width; x++ ) { t->rawdata[(x+y*width)*4+0] = ((unsigned char*)bd.Scan0)[x*4+y*bd.Stride+2]; t->rawdata[(x+y*width)*4+1] = ((unsigned char*)bd.Scan0)[x*4+y*bd.Stride+1]; t->rawdata[(x+y*width)*4+2] = ((unsigned char*)bd.Scan0)[x*4+y*bd.Stride+0]; t->rawdata[(x+y*width)*4+3] = ((unsigned char*)bd.Scan0)[x*4+y*bd.Stride+3]; } } GdipBitmapUnlockBits(pImg, &bd ); GdipDisposeImage( (GpImage *)pImg ); GdiplusShutdown( gdiplusToken ); return 0; }