/* * 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; }