#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0501
#include "windows.h"
#include <stdio.h>
void PreserveOriginal(LPCTSTR szPath)
{
char szOrg[MAX_PATH];
char szNew[MAX_PATH];
strcpy(szOrg, szPath);
strcpy(szNew, szPath);
strcat(szOrg, "uxtheme.dll");
strcat(szNew, "uxtheme_original.dll");
BOOL bCancel = FALSE;
// if it exists, leave it alone. its already backed up.
CopyFile(szOrg, szNew, TRUE);
}
void PatchFile(LPCTSTR pszDir, LPCTSTR pszFile, BOOL bNoMsg = FALSE)
{
char szFilename[MAX_PATH];
strcpy(szFilename, pszDir);
strcat(szFilename, pszFile);
HANDLE hFile = CreateFile(szFilename, FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile && hFile != INVALID_HANDLE_VALUE)
{
// search sequence for XP
BYTE bSearchSeq[8] = {0x81, 0xEC, 0x80, 0x00, 0x00, 0x00, 0x56, 0x57};
// search sequence for Server 2003
BYTE bSearchSeq2[8] = {0x81, 0xEC, 0x84, 0x00, 0x00, 0x00, 0xA1, 0x2C};
BYTE bRead[8] = {0, 0, 0, 0, 0, 0, 0, 0};
BYTE bPatch[8] = {0x33, 0xF6, 0x8B, 0xC6, 0xC9, 0xC2, 0x08, 0x00};
DWORD dwRead = 0;
DWORD dwWrite = 0;
while (ReadFile(hFile, (void*)&bRead[7], 1, &dwRead, NULL))
{
if (dwRead == 0)
break;
if ((memcmp(bRead, bSearchSeq, 8) == 0) || (memcmp(bRead, bSearchSeq2, 8) == 0))
{
SetFilePointer(hFile, -8, NULL, FILE_CURRENT);
WriteFile(hFile, &bPatch, 8, &dwWrite, NULL);
CloseHandle(hFile);
return;
}
else
{
bRead[0] = bRead[1];
bRead[1] = bRead[2];
bRead[2] = bRead[3];
bRead[3] = bRead[4];
bRead[4] = bRead[5];
bRead[5] = bRead[6];
bRead[6] = bRead[7];
bRead[7] = 0;
}
}
CloseHandle(hFile);
if (!bNoMsg)
MessageBox(NULL, "Unable to find search bytes in UXTHEME.DLL!\nIt may already be patched.", "UxThemePatch Error!", MB_ICONERROR);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
char szWinDir[MAX_PATH];
char szDir1[MAX_PATH]; // sp files
char szDir2[MAX_PATH]; // dllcache
char szDir3[MAX_PATH]; // system32
char szDir4[MAX_PATH];
GetWindowsDirectory(szWinDir, MAX_PATH);
strcpy(szDir1, szWinDir);
strcat(szDir1, "\\ServicePackFiles\\i386\\");
strcpy(szDir2, szWinDir);
strcat(szDir2, "\\system32\\dllcache\\");
strcpy(szDir3, szWinDir);
strcat(szDir3, "\\system32\\");
// move to the system32 dir to make the copy easier
SetCurrentDirectory(szDir3);
if (stricmp(lpCmdLine, "-uninstall") == 0)
{
DeleteFile("uxtheme_patched.dll");
DeleteFile("uxtheme_locked.dll");
DeleteFile(".\\dllcache\\uxtheme.dll");
CopyFile("uxtheme_original.dll", ".\\dllcache\\uxtheme.dll", FALSE);
MoveFile("uxtheme.dll", "uxtheme_locked.dll");
CopyFile(".\\dllcache\\uxtheme.dll", "uxtheme.dll", FALSE);
return 0;
}
// many pre-built pc mfg's put this dir there, so we'll patch it too.
strcpy(szDir4, "c:\\i386\\");
PatchFile(szDir4, "uxtheme.dll", TRUE);
PatchFile(szDir1, "uxtheme.dll", TRUE);
PreserveOriginal(szDir3);
// patch system32\uxtheme_patched.dll first.
CopyFile("uxtheme.dll", "uxtheme_patched.dll", FALSE);
PatchFile(szDir3, "uxtheme_patched.dll");
// then copy it into \dllcache
CopyFile("uxtheme_patched.dll", ".\\dllcache\\uxtheme.dll", FALSE);
// \system32's uxtheme is probably locked, so we need to rename it.
if (!MoveFile("uxtheme.dll", "uxtheme_locked.dll"))
{
MessageBox(NULL, "Please remove \\SYSTEM32\\UXTHEME_LOCKED.DLL and restart this application.", "UxThemePatch Error!", MB_ICONERROR);
return 0;
}
// then copy the patched version back in. WFP is a pain to work around isn't it?
CopyFile(".\\dllcache\\uxtheme.dll", "uxtheme.dll", FALSE);
return 0;
}