mirror of
https://gitlab.com/hashborgir/plugy.git
synced 2024-11-30 12:36:02 +00:00
468 lines
16 KiB
C++
468 lines
16 KiB
C++
/*=================================================================
|
|
File created by Yohann NICOLAS.
|
|
Add support 1.13d by L'Autour.
|
|
|
|
Patch D2gfx.dll to install PlugY.
|
|
|
|
=================================================================*/
|
|
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
|
|
|
|
#include "../Commons/VersionInfo.h"
|
|
#include <stdio.h>
|
|
|
|
DWORD loadCallerAddr;
|
|
DWORD loadCallerLen;
|
|
BYTE loadCallerNew[6] = { 0x90,0xE8,0x00,0x00,0x00,0x00 }; // Call load PlugY library
|
|
BYTE loadCallerOld[6] = { 0xFF,0x15,0x00,0x00,0x00,0x00 }; // CALL DWORD PTR DS:[<&KERNEL32.LoadLibrary>]
|
|
|
|
DWORD freeCallerAddr;
|
|
DWORD freeCallerLen;
|
|
BYTE freeCallerNew[6] = { 0x90,0xE8,0x00,0x00,0x00,0x00 }; // Call free PlugY library
|
|
BYTE freeCallerOld[6] = { 0xFF,0x15,0x00,0x00,0x00,0x00 }; // CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>]
|
|
|
|
DWORD loadDllAddr;
|
|
DWORD loadDllLen;
|
|
BYTE loadDll[] = {
|
|
0xFF,0x74,0x24,0x04, //PUSH DWORD PTR SS:[ESP+4]
|
|
0xFF,0x15,0x40,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.LoadLibraryA>] ; kernel32.LoadLibraryA
|
|
0x50, //PUSH EAX
|
|
0x68,0x80,0xBE,0xA7,0x6F, //PUSH d2gfx.6FA7BE80 ; ASCII "PlugY.dll"
|
|
0xFF,0x15,0x40,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.LoadLibraryA>] ; kernel32.LoadLibraryA
|
|
0xA3,0xFC,0xEF,0xA8,0x6F, //MOV DWORD PTR DS:[6FA8EFFC],EAX
|
|
0x85,0xC0, //TEST EAX,EAX
|
|
0x74,0x2B, //JE SHORT d2gfx.6FA7BE33
|
|
0x50, //PUSH EAX
|
|
0x68,0x90,0xBE,0xA7,0x6F, //PUSH d2gfx.6FA7BE10 ;Init String
|
|
0x50, //PUSH EAX
|
|
0xFF,0x15,0x3C,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.GetProcAddress>] ; kernel32.GetProcAddress
|
|
0x85,0xC0, //TEST EAX,EAX
|
|
0x74,0x04, //JE SHORT d2gfx.6FA7BDC1
|
|
0x6A,0x00, //PUSH 0
|
|
0xEB,0x13, //JMP SHORT d2gfx.6FA7BDC1
|
|
0x68,0x10,0x27,0x00,0x00, //PUSH 2710 ;Init Ordinal(10000)
|
|
0xFF,0x74,0x24,0x04, //PUSH DWORD PTR SS:[ESP+4]
|
|
0xFF,0x15,0x3C,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.GetProcAddress>] ; kernel32.GetProcAddress
|
|
0x85,0xC0, //TEST EAX,EAX
|
|
0x74,0x02, //JE SHORT d2gfx.6FA7BDC1
|
|
0xFF,0xD0, //CALL EAX
|
|
0x58, //POP EAX
|
|
0x58, //POP EAX
|
|
0xC2,0x04,0x00, //RETN 4
|
|
0x00,0x00,0x00,0x00 }; //HANDLE var;
|
|
|
|
DWORD freeDllAddr;
|
|
DWORD freeDllLen;
|
|
BYTE freeDll[] = {
|
|
0xFF,0x74,0x24,0x04, //PUSH DWORD PTR SS:[ESP+4]
|
|
0xFF,0x15,0x48,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>] ; kernel32.FreeLibrary
|
|
0x50, //PUSH EAX
|
|
0xA1,0xFC,0xEF,0xA8,0x6F, //MOV EAX,DWORD PTR DS:[6FA8EFFC]
|
|
0x85,0xC0, //TEST EAX,EAX
|
|
0x74,0x2D, //JE SHORT d2gfx.6FA7BE74
|
|
0x50, //PUSH EAX
|
|
0x68,0xA0,0xBE,0xA7,0x6F, //PUSH d2gfx.6FA7BE20 ;Release String
|
|
0x50, //PUSH EAX
|
|
//0x33,0xC0, //XOR EAX,EAX
|
|
//0xA3,0xFC,0xEF,0xA8,0x6F, //MOV DWORD PTR DS:[6FA8EFFC],EAX
|
|
0xFF,0x15,0x3C,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; kernel32.GetProcAddress
|
|
0x85,0xC0, //TEST EAX,EAX
|
|
0x75,0x13, //JNZ SHORT d2gfx.6FA7BDEF
|
|
0x68,0x11,0x27,0x00,0x00, //PUSH 2711 ;Release Ordinal(10001)
|
|
0xFF,0x74,0x24,0x04, //PUSH DWORD PTR SS:[ESP+4]
|
|
0xFF,0x15,0x3C,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; kernel32.GetProcAddress
|
|
0x85,0xC0, //TEST EAX,EAX
|
|
0x74,0x02, //JE SHORT d2gfx.6FA7BDEF
|
|
0xFF,0xD0, //CALL EAX
|
|
0xFF,0x15,0x48,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.FreeLibrar>; kernel32.FreeLibrary
|
|
0x58, //POP EAX
|
|
0xC2,0x04,0x00 }; //RETN 4
|
|
|
|
DWORD libraryNameAddr;
|
|
DWORD libraryNameLen;
|
|
LPCSTR libraryName = "PlugY.dll";
|
|
|
|
DWORD initNameAddr;
|
|
DWORD initNameLen;
|
|
LPCSTR initName = "_Init@4";
|
|
|
|
DWORD releaseNameAddr;
|
|
DWORD releaseNameLen;
|
|
LPCSTR releaseName = "_Release@0";
|
|
|
|
int msgBox(LPCSTR boxName, UINT uType, LPCSTR pFormat, ...)
|
|
{
|
|
char buffer[300];
|
|
va_list lArgs;
|
|
va_start( lArgs, pFormat );
|
|
vsprintf_s( buffer, sizeof(buffer), pFormat, lArgs );
|
|
va_end(lArgs);
|
|
|
|
return MessageBox(NULL, buffer, boxName, uType);
|
|
}
|
|
|
|
int Align(int v)
|
|
{
|
|
return v % 16 ? v + 16 - v % 16 : v;
|
|
}
|
|
|
|
////////////////////////////// EXPORTED FUNCTIONS //////////////////////////////
|
|
|
|
int Patch(FILE *targetFile)
|
|
{
|
|
bool error = false;
|
|
int ident = 0;
|
|
BYTE buffer[100];
|
|
BYTE zeros[100];
|
|
memset(zeros, 0, sizeof(zeros));
|
|
|
|
fseek(targetFile, loadCallerAddr, SEEK_SET);
|
|
fread(buffer, sizeof(loadCallerNew), 1, targetFile);
|
|
if (memcmp(buffer, loadCallerOld, sizeof(loadCallerNew)) != 0) error = true;
|
|
if (memcmp(buffer, loadCallerNew, sizeof(loadCallerNew)) == 0) ident++;
|
|
|
|
fseek(targetFile, freeCallerAddr, SEEK_SET);
|
|
fread(buffer, sizeof(freeCallerNew), 1, targetFile);
|
|
if (memcmp(buffer, freeCallerOld, sizeof(freeCallerNew)) != 0) error = true;
|
|
if (memcmp(buffer, freeCallerNew, sizeof(freeCallerNew)) == 0) ident++;
|
|
|
|
fseek(targetFile, loadDllAddr, SEEK_SET);
|
|
fread(buffer, sizeof(loadDll), 1, targetFile);
|
|
if (memcmp(buffer, zeros, sizeof(loadDll)) != 0) error = true;
|
|
if (memcmp(buffer, loadDll, sizeof(loadDll)) == 0) ident++;
|
|
|
|
fseek(targetFile, freeDllAddr, SEEK_SET);
|
|
fread(buffer, sizeof(freeDll), 1, targetFile);
|
|
if (memcmp(buffer, zeros, sizeof(freeDll)) != 0) error = true;
|
|
if (memcmp(buffer, freeDll, sizeof(freeDll)) == 0) ident++;
|
|
|
|
fseek(targetFile, initNameAddr, SEEK_SET);
|
|
fread(buffer, initNameLen, 1, targetFile);
|
|
if (memcmp(buffer, zeros, initNameLen) != 0) error = true;
|
|
if (memcmp(buffer, initName, initNameLen) == 0) ident++;
|
|
|
|
fseek(targetFile, releaseNameAddr, SEEK_SET);
|
|
fread(buffer, releaseNameLen, 1, targetFile);
|
|
if (memcmp(buffer, zeros, releaseNameLen) != 0) error = true;
|
|
if (memcmp(buffer, releaseName, releaseNameLen) == 0) ident++;
|
|
|
|
fseek(targetFile, libraryNameAddr, SEEK_SET);
|
|
fread(buffer, libraryNameLen, 1, targetFile);
|
|
if (memcmp(buffer, zeros, libraryNameLen) != 0) error = true;
|
|
if (memcmp(buffer, libraryName, libraryNameLen) == 0) ident++;
|
|
|
|
if (error)
|
|
return ident == 7 ? 1 : 2;
|
|
|
|
fseek(targetFile, loadCallerAddr, SEEK_SET);
|
|
fwrite(loadCallerNew, 6, 1, targetFile);
|
|
|
|
fseek(targetFile, freeCallerAddr, SEEK_SET);
|
|
fwrite(freeCallerNew, 6, 1, targetFile);
|
|
|
|
fseek(targetFile, loadDllAddr, SEEK_SET);
|
|
fwrite(loadDll, sizeof(loadDll), 1, targetFile);
|
|
|
|
fseek(targetFile, freeDllAddr, SEEK_SET);
|
|
fwrite(freeDll, sizeof(freeDll), 1, targetFile);
|
|
|
|
fseek(targetFile, initNameAddr, SEEK_SET);
|
|
fwrite(initName, initNameLen, 1, targetFile);
|
|
|
|
fseek(targetFile, releaseNameAddr, SEEK_SET);
|
|
fwrite(releaseName, releaseNameLen, 1, targetFile);
|
|
|
|
fseek(targetFile, libraryNameAddr, SEEK_SET);
|
|
fwrite(libraryName, libraryNameLen, 1, targetFile);
|
|
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
int Unpatch(FILE *targetFile)
|
|
{
|
|
bool error = false;
|
|
int ident = 0;
|
|
BYTE buffer[100];
|
|
BYTE zeros[100];
|
|
memset(zeros, 0, sizeof(zeros));
|
|
|
|
fseek(targetFile, loadCallerAddr, SEEK_SET);
|
|
fread(buffer, 6, 1, targetFile);
|
|
if (memcmp(buffer, loadCallerNew, 6) != 0) error = true;
|
|
if (memcmp(buffer, loadCallerOld, 6) == 0) ident++;
|
|
|
|
fseek(targetFile, freeCallerAddr, SEEK_SET);
|
|
fread(buffer, 6, 1, targetFile);
|
|
if (memcmp(buffer, freeCallerNew, 6) != 0) error = true;
|
|
if (memcmp(buffer, freeCallerOld, 6) == 0) ident++;
|
|
|
|
fseek(targetFile, loadDllAddr, SEEK_SET);
|
|
fread(buffer, sizeof(loadDll), 1, targetFile);
|
|
if (memcmp(buffer, loadDll, sizeof(loadDll)) != 0) error = true;
|
|
if (memcmp(buffer, zeros, sizeof(loadDll)) == 0) ident++;
|
|
|
|
fseek(targetFile, freeDllAddr, SEEK_SET);
|
|
fread(buffer, sizeof(freeDll), 1, targetFile);
|
|
if (memcmp(buffer, freeDll, sizeof(freeDll)) != 0) error = true;
|
|
if (memcmp(buffer, zeros, sizeof(freeDll)) == 0) ident++;
|
|
|
|
fseek(targetFile, initNameAddr, SEEK_SET);
|
|
fread(buffer, initNameLen, 1, targetFile);
|
|
if (memcmp(buffer, initName, initNameLen) != 0) error = true;
|
|
if (memcmp(buffer, zeros, initNameLen) == 0) ident++;
|
|
|
|
fseek(targetFile, releaseNameAddr, SEEK_SET);
|
|
fread(buffer, releaseNameLen, 1, targetFile);
|
|
if (memcmp(buffer, releaseName, releaseNameLen) != 0) error = true;
|
|
if (memcmp(buffer, zeros, releaseNameLen) == 0) ident++;
|
|
|
|
fseek(targetFile, libraryNameAddr, SEEK_SET);
|
|
fread(buffer, libraryNameLen, 1, targetFile);
|
|
if (memcmp(buffer, libraryName, libraryNameLen) != 0) error = true;
|
|
if (memcmp(buffer, zeros, libraryNameLen) == 0) ident++;
|
|
|
|
if (error)
|
|
return ident == 7 ? 1 : 2;
|
|
|
|
fseek(targetFile, loadCallerAddr, SEEK_SET);
|
|
fwrite(loadCallerOld, 6, 1, targetFile);
|
|
|
|
fseek(targetFile, freeCallerAddr, SEEK_SET);
|
|
fwrite(freeCallerOld, 6, 1, targetFile);
|
|
|
|
fseek(targetFile, loadDllAddr, SEEK_SET);
|
|
fwrite(zeros, sizeof(loadDll), 1, targetFile);
|
|
|
|
fseek(targetFile, freeDllAddr, SEEK_SET);
|
|
fwrite(zeros, sizeof(freeDll), 1, targetFile);
|
|
|
|
fseek(targetFile, initNameAddr, SEEK_SET);
|
|
fwrite(zeros, initNameLen, 1, targetFile);
|
|
|
|
fseek(targetFile, releaseNameAddr, SEEK_SET);
|
|
fwrite(zeros, releaseNameLen, 1, targetFile);
|
|
|
|
fseek(targetFile, libraryNameAddr, SEEK_SET);
|
|
fwrite(zeros, libraryNameLen, 1, targetFile);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char * argv[])
|
|
{
|
|
#ifdef RESTORE
|
|
bool unpatch = true;
|
|
#else
|
|
bool unpatch = argc > 1 && strcmp(argv[1], "-u") == 0;
|
|
#endif
|
|
|
|
int version = GetD2Version("Game.exe");
|
|
LPCSTR boxName = unpatch ? "Uninstall PlugY, The Survival Kit" : "Install PlugY, The Survival Kit";
|
|
LPCSTR targetFilename = version > V113d ? "Game.exe" : "D2gfx.dll";
|
|
|
|
if (version < V107 || version > V114d)
|
|
{
|
|
msgBox(boxName, MB_OK | MB_ICONEXCLAMATION,
|
|
"Current version of LoD (%s) isn't compatible with PlugY.\n\n"
|
|
"Please, install a patch between 1.09 and 1.13d or 1.14.",
|
|
GetVersionString(version));
|
|
exit(0);
|
|
}
|
|
|
|
if (msgBox(boxName, MB_YESNO | MB_ICONQUESTION,
|
|
"This programm will modify %s file in current directory.\n"
|
|
"Before continue, you should backup it.\n\n"
|
|
"Do you want to modify %s to %s PlugY ?",
|
|
targetFilename, targetFilename, unpatch ? "remove": "install") == IDNO)
|
|
{
|
|
msgBox(boxName, MB_OK | MB_ICONASTERISK, "No changes made.");
|
|
exit(0);
|
|
}
|
|
|
|
FILE *targetFile;
|
|
if (fopen_s(&targetFile, targetFilename, "rb+"))
|
|
{
|
|
msgBox(boxName, MB_OK | MB_ICONEXCLAMATION,
|
|
"Can't open %s in read/write mode.\n"
|
|
"If Diablo II is running, can you close it and try again ?",
|
|
targetFilename, unpatch ? "remove": "install");
|
|
exit(0);
|
|
}
|
|
|
|
// Get size
|
|
loadCallerLen = sizeof(loadCallerNew);
|
|
freeCallerLen = sizeof(freeCallerNew);
|
|
loadDllLen = sizeof(loadDll);
|
|
freeDllLen = sizeof(freeDll);
|
|
libraryNameLen = strlen(libraryName) + 1;
|
|
initNameLen = strlen(initName) + 1;
|
|
releaseNameLen = strlen(releaseName) + 1;
|
|
|
|
// Get Addr
|
|
DWORD offsetPESignature;
|
|
fseek(targetFile, 0x3C, SEEK_SET);
|
|
fread(&offsetPESignature, sizeof(offsetPESignature), 1, targetFile);
|
|
DWORD sizeOfCode;
|
|
fseek(targetFile, offsetPESignature + 0x1C, SEEK_SET);
|
|
fread(&sizeOfCode, sizeof(sizeOfCode), 1, targetFile);
|
|
DWORD baseOfCode;
|
|
fseek(targetFile, offsetPESignature + 0x2C, SEEK_SET);
|
|
fread(&baseOfCode, sizeof(baseOfCode), 1, targetFile);
|
|
DWORD imageBase;
|
|
fseek(targetFile, offsetPESignature + 0x34, SEEK_SET);
|
|
fread(&imageBase, sizeof(imageBase), 1, targetFile);
|
|
DWORD sizeOfData;
|
|
fseek(targetFile, offsetPESignature + 0x150, SEEK_SET);
|
|
fread(&sizeOfData, sizeof(sizeOfData), 1, targetFile);
|
|
DWORD baseOfData;
|
|
fseek(targetFile, offsetPESignature + 0x154, SEEK_SET);
|
|
fread(&baseOfData, sizeof(baseOfData), 1, targetFile);
|
|
|
|
// Set Addr
|
|
DWORD loadLibraryAddr = imageBase;
|
|
DWORD freeLibraryAddr = imageBase;
|
|
DWORD getProcAddressAddr = imageBase;
|
|
DWORD handleAddr = imageBase + baseOfData + sizeOfData;
|
|
|
|
loadCallerAddr = 0;
|
|
freeCallerAddr = 0;
|
|
loadDllAddr = Align(baseOfCode + sizeOfCode - 0x100);
|
|
freeDllAddr = Align(loadDllAddr + sizeof(loadDll));
|
|
libraryNameAddr = Align(freeDllAddr + sizeof(freeDll));
|
|
initNameAddr = Align(libraryNameAddr + libraryNameLen);
|
|
releaseNameAddr = Align(initNameAddr + initNameLen);
|
|
|
|
switch (version)
|
|
{
|
|
case V107:
|
|
loadCallerAddr += 0x3882;
|
|
freeCallerAddr += 0x3A6C;
|
|
loadLibraryAddr += 0xC038;
|
|
freeLibraryAddr += 0xC040;
|
|
getProcAddressAddr += 0xC034;
|
|
break;
|
|
case V108:
|
|
case V109:
|
|
case V109b:
|
|
case V109d:
|
|
loadCallerAddr += 0x389B;
|
|
freeCallerAddr += 0x3A8C;
|
|
loadLibraryAddr += 0xC03C;
|
|
freeLibraryAddr += 0xC044;
|
|
getProcAddressAddr += 0xC038;
|
|
break;
|
|
case V110:
|
|
loadCallerAddr += 0x3870;
|
|
freeCallerAddr += 0x3A6D;
|
|
loadLibraryAddr += 0xC040;
|
|
freeLibraryAddr += 0xC048;
|
|
getProcAddressAddr += 0xC03C;
|
|
break;
|
|
case V111:
|
|
loadCallerAddr += 0x8B23;
|
|
freeCallerAddr += 0x8ACA;
|
|
loadLibraryAddr += 0xD11C;
|
|
freeLibraryAddr += 0xD12C;
|
|
getProcAddressAddr += 0xD120;
|
|
break;
|
|
case V111b:
|
|
loadCallerAddr += 0xB423;
|
|
freeCallerAddr += 0xB3CA;
|
|
loadLibraryAddr += 0xD11C;
|
|
freeLibraryAddr += 0xD12C;
|
|
getProcAddressAddr += 0xD120;
|
|
break;
|
|
case V112:
|
|
loadCallerAddr += 0x8F63;
|
|
freeCallerAddr += 0x8F0A;
|
|
loadLibraryAddr += 0xD11C;
|
|
freeLibraryAddr += 0xD12C;
|
|
getProcAddressAddr += 0xD120;
|
|
break;
|
|
case V113c:
|
|
loadCallerAddr += 0xB423;
|
|
freeCallerAddr += 0xB3CA;
|
|
loadLibraryAddr += 0xD11C;
|
|
freeLibraryAddr += 0xD12C;
|
|
getProcAddressAddr += 0xD120;
|
|
break;
|
|
case V113d:
|
|
loadCallerAddr += 0xAA03;
|
|
freeCallerAddr += 0xA9AA;
|
|
loadLibraryAddr += 0xD11C;
|
|
freeLibraryAddr += 0xD124;
|
|
getProcAddressAddr += 0xD120;
|
|
break;
|
|
case V114a:
|
|
loadCallerAddr += 0x1BCB;// Load advapi.dll
|
|
freeCallerAddr += 0xF375;// Free dbghelp.dll
|
|
loadLibraryAddr += 0x2CD118;
|
|
freeLibraryAddr += 0x2CD120;
|
|
getProcAddressAddr += 0x2CD11C;
|
|
break;
|
|
case V114b:
|
|
case V114c:
|
|
loadCallerAddr += 0x1BCB;// Load advapi.dll
|
|
freeCallerAddr += 0x6F75;// Free dbghelp.dll
|
|
loadLibraryAddr += 0x2CD11C;
|
|
freeLibraryAddr += 0x2CD124;
|
|
getProcAddressAddr += 0x2CD120;
|
|
break;
|
|
case V114d:
|
|
loadCallerAddr += 0x621C;// Load advapi.dll
|
|
freeCallerAddr += 0xB514;// Free dbghelp.dll
|
|
loadLibraryAddr += 0x2CC144;
|
|
freeLibraryAddr += 0x2CC14C;
|
|
getProcAddressAddr += 0x2CC148;
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
*(DWORD*)&loadCallerNew[2] = loadDllAddr - (loadCallerAddr + sizeof(loadCallerNew));
|
|
*(DWORD*)&loadCallerOld[2] = loadLibraryAddr;
|
|
*(DWORD*)&freeCallerNew[2] = freeDllAddr - (freeCallerAddr + sizeof(freeCallerNew));
|
|
*(DWORD*)&freeCallerOld[2] = freeLibraryAddr;
|
|
*(DWORD*)&loadDll[6] = loadLibraryAddr;
|
|
*(DWORD*)&loadDll[12] = imageBase + libraryNameAddr;
|
|
*(DWORD*)&loadDll[18] = loadLibraryAddr;
|
|
*(DWORD*)&loadDll[23] = handleAddr;
|
|
*(DWORD*)&loadDll[33] = imageBase + initNameAddr;
|
|
*(DWORD*)&loadDll[40] = getProcAddressAddr;
|
|
*(DWORD*)&loadDll[63] = getProcAddressAddr;
|
|
*(DWORD*)&freeDll[6] = freeLibraryAddr;
|
|
*(DWORD*)&freeDll[12] = handleAddr;
|
|
*(DWORD*)&freeDll[22] = imageBase + releaseNameAddr;
|
|
*(DWORD*)&freeDll[29] = getProcAddressAddr;
|
|
*(DWORD*)&freeDll[48] = getProcAddressAddr;
|
|
*(DWORD*)&freeDll[60] = freeLibraryAddr;
|
|
|
|
// Patch / Unpatch
|
|
int res;
|
|
if (unpatch)
|
|
res = Unpatch(targetFile);
|
|
else
|
|
res = Patch(targetFile);
|
|
|
|
fclose(targetFile);
|
|
|
|
if (res == 0)
|
|
msgBox(boxName, MB_OK | MB_ICONASTERISK,
|
|
"%s was modified.\n"
|
|
"PlugY, The Survival Kit %s.",
|
|
targetFilename, unpatch ? "is removed" : "is installed");
|
|
else if (res == 1)
|
|
msgBox(boxName, MB_OK | MB_ICONASTERISK,
|
|
"PlugY, The Survival Kit already %s.",
|
|
unpatch ? "uninstalled" : "installed");
|
|
else if (res == 2)
|
|
msgBox(boxName, MB_OK | MB_ICONASTERISK,
|
|
"File contents in %s isn't correct.\n"
|
|
"Unable to %s PlugY, The Survival Kit.",
|
|
targetFilename, unpatch ? "uninstall" : "install");
|
|
|
|
return 1;
|
|
}
|
|
|
|
///////////////////////// END OF FILE ///////////////////////
|