void XAssets_PatchLimits(){ void* ptr; int size = NUM_ASSETTYPES * sizeof(void*); void* *DB_XAssetPool = (void*)DB_XAssetPool_ADDR; ptr = &DB_XAssetPool[0]; if(!Sys_MemoryProtectWrite(ptr, size)) { Com_Error(ERR_FATAL,"XAssets_PatchLimits: Failed to change memory to writeable\n"); } DB_XAssetPool[XModel] = Z_Malloc(MAX_XMODELS*DB_GetXAssetTypeSize(XModel) +4); DB_XAssetPool[WeaponDef] = Z_Malloc(MAX_WEAPON*DB_GetXAssetTypeSize(WeaponDef) +4); DB_XAssetPool[FxEffectDef] = Z_Malloc(MAX_FX*DB_GetXAssetTypeSize(FxEffectDef) +4); DB_XAssetPool[GfxImage] = Z_Malloc(MAX_GFXIMAGE*DB_GetXAssetTypeSize(GfxImage) +4); if(DB_XAssetPool[XModel] == NULL || DB_XAssetPool[WeaponDef] == NULL || DB_XAssetPool[FxEffectDef] == NULL || DB_XAssetPool[GfxImage] == NULL) { Com_Error(ERR_FATAL, "Failed to get enough memory for Assets. Can not continue\n"); return; } if(!Sys_MemoryProtectReadonly(ptr, size)) { Com_Error(ERR_FATAL,"XAssets_PatchLimits: Failed to change memory to read only\n"); } //Patch XAssets poolsize int *DB_XAssetPoolSize = (int*)g_poolsize_ADDR; ptr = &DB_XAssetPoolSize[0]; if(!Sys_MemoryProtectWrite(ptr, size)) { Com_Error(ERR_FATAL,"XAssets_PatchLimits: Failed to change memory to writeable\n"); } DB_XAssetPoolSize[XModel] = MAX_XMODELS; DB_XAssetPoolSize[WeaponDef] = MAX_WEAPON; DB_XAssetPoolSize[FxEffectDef] = MAX_FX; DB_XAssetPoolSize[GfxImage] = MAX_GFXIMAGE; if(!Sys_MemoryProtectReadonly(ptr, size)) { Com_Error(ERR_FATAL,"XAssets_PatchLimits: Failed to change memory to read only\n"); } }
static qboolean Sys_PatchImage() { if(!Sys_MemoryProtectWrite((void*)(IMAGE_BASE + TEXT_SECTION_OFFSET), TEXT_SECTION_LENGTH)) return qfalse; if(!Sys_MemoryProtectWrite((void*)(IMAGE_BASE + RODATA_SECTION_OFFSET), RODATA_SECTION_LENGTH)) return qfalse; Sys_PatchImageData( ); if(!Sys_MemoryProtectExec((void*)(IMAGE_BASE + TEXT_SECTION_OFFSET), TEXT_SECTION_LENGTH)) return qfalse; if(!Sys_MemoryProtectReadonly((void*)(IMAGE_BASE + RODATA_SECTION_OFFSET), RODATA_SECTION_LENGTH)) return qfalse; return qtrue; }
void PHandler_ScrAddMethod(char *name, xfunction_t function, qboolean replace, int pID) { int i; if(pID>=MAX_PLUGINS){ Com_Printf("Error: tried adding a script command for a plugin with non existent pID. pID supplied: %d.\n",pID); return; }else if(pID<0){ Com_Printf("Plugin Handler error: Plugin_ScrAddMethod or Plugin_ScrReplaceMethod called from not within a plugin or from a disabled plugin!\n"); return; } if(!pluginFunctions.plugins[pID].loaded){ Com_Printf("Error: Tried adding a command for not loaded plugin! PID: %d.\n",pID); } Com_Printf("Adding a plugin script method for plugin %d, command name: %s.\n",pID, name); for(i = 0; i < MAX_SCRIPTFUNCTIONS; i++ ) { if(pluginScriptCallStubs.s[pID * MAX_SCRIPTFUNCTIONS + i].name[0] == 0) { break; } } if(i == MAX_SCRIPTFUNCTIONS) { Com_PrintError("Exceeded maximum number of scrip-functions (%d) for plugin\n", MAX_SCRIPTFUNCTIONS); return; } if(strlen(name) >= sizeof(pluginScriptCallStubs.s[pID * MAX_SCRIPTFUNCTIONS + i].name)) { Com_PrintError("Exceeded maximum length of name for scrip-method: %s (%d) for plugin.\n", name, sizeof(pluginScriptCallStubs.s[pID * MAX_SCRIPTFUNCTIONS + i].name) ); return; } if(replace == qtrue) { Scr_RemoveMethod(name); } if(Scr_AddMethod(name, (xfunction_t)&pluginScriptCallStubs.s[pID * MAX_SCRIPTFUNCTIONS + i].dyncallstub, qfalse) == qfalse) { Com_PrintError("Failed to add this script method: %s for plugin\n", name); return; } Sys_MemoryProtectWrite(pluginScriptCallStubs.s, sizeof(pluginScriptCallStubs.s)); Q_strncpyz(pluginScriptCallStubs.s[pID * MAX_SCRIPTFUNCTIONS + i].name, name, sizeof(pluginScriptCallStubs.s[pID * MAX_SCRIPTFUNCTIONS + i].name)); pluginScriptCallStubs.s[pID * MAX_SCRIPTFUNCTIONS + i].isMethod = qtrue; PHandler_InitDynCallStub(&pluginScriptCallStubs.s[pID * MAX_SCRIPTFUNCTIONS + i].dyncallstub, function, pID); Sys_MemoryProtectExec(pluginScriptCallStubs.s, sizeof(pluginScriptCallStubs.s)); pluginFunctions.plugins[pID].scriptmethods++; }
int PbSVLoadModule() { char hash[128]; long unsigned sizeofhash; char modname[256]; char modname_dest[256]; const char* dlname; const char* dlname2; byte* imagebase; if ( pbsv.hLibModule ) { return 0; } PbSvUnload(); if ( FS_FileExistsOSPath( PbSv6makefn(modname, "pbsvnew" DLL_EXT) ) == qtrue ) { Sys_Chmod( PbSv6makefn(modname, "pbsvold" DLL_EXT), 0777); FS_RemoveOSPath( PbSv6makefn(modname, "pbsvold" DLL_EXT) ); rename( PbSv6makefn(modname, "pbsv" DLL_EXT), PbSv6makefn(modname_dest, "pbsvold" DLL_EXT) ); Sys_Chmod( PbSv6makefn(modname, "pbsv" DLL_EXT), 0777); FS_RemoveOSPath( PbSv6makefn(modname, "pbsv" DLL_EXT) ); rename( PbSv6makefn(modname, "pbsvnew" DLL_EXT), PbSv6makefn(modname_dest, "pbsv" DLL_EXT) ); } if(com_securemode) { dlname = PbSv6makefn(modname, "pbag" DLL_EXT); dlname2 = PbSv6makefn(modname_dest, "pbags" DLL_EXT); if ( FS_FileExistsOSPath( dlname ) == qtrue ) { FS_RemoveOSPath( dlname2 ); rename( dlname ,dlname2 ); FS_RemoveOSPath( dlname ); } hash[0] = '\0'; sizeofhash = sizeof(hash); Sec_HashFile(SEC_HASH_TIGER, dlname2, hash, &sizeofhash, qfalse); if(Q_stricmp(hash ,PBAG_HASH)) { Com_Printf("Tiger = %s\n", hash); Com_PrintError("%s checksum missmatch! PunkBuster will not startup in securemode when the checksum is invalid.\n", dlname2); return 1; } dlname = PbSv6makefn(modname, "pbcl" DLL_EXT); dlname2 = PbSv6makefn(modname_dest, "pbcls" DLL_EXT); if ( FS_FileExistsOSPath( dlname ) == qtrue ) { FS_RemoveOSPath( dlname2 ); rename( dlname ,dlname2 ); FS_RemoveOSPath( dlname ); } hash[0] = '\0'; sizeofhash = sizeof(hash); Sec_HashFile(SEC_HASH_TIGER, dlname2, hash, &sizeofhash, qfalse); if(Q_stricmp(hash ,PBCL_HASH)) { Com_Printf("Tiger = %s\n", hash); Com_PrintError("%s checksum missmatch! PunkBuster will not startup in securemode when the checksum is invalid.\n", dlname2); return 1; } dlname2 = PbSv6makefn(modname, "pbsv" DLL_EXT); hash[0] = '\0'; sizeofhash = sizeof(hash); Sec_HashFile(SEC_HASH_TIGER, dlname2, hash, &sizeofhash, qfalse); if(Q_stricmp(hash ,PBSV_HASH)) { Com_Printf("Tiger = %s\n", hash); Com_PrintError("%s checksum missmatch! PunkBuster will not startup in securemode when the checksum is invalid.\n", dlname2); return 1; } } dlname = PbSv6makefn(modname, "pbsv" DLL_EXT); pbsv.hLibModule = Sys_LoadLibrary( dlname ); if ( pbsv.hLibModule == NULL ) { return 1; } if(com_securemode) { /* Remove system() */ imagebase = LIBRARY_ADDRESS_BY_HANDLE( pbsv.hLibModule ); if(Sys_MemoryProtectWrite( (void*)(imagebase + 0x4c6e0), 0xdfdf7 ) == qfalse) { return 1; } SetCall((DWORD)(imagebase + 0x114346), PB_SystemDummy); SetCall((DWORD)(imagebase + 0xc23cb), PB_SystemDummy); if(Sys_MemoryProtectExec( (void*)(imagebase + 0x4c6e0), 0xdfdf7 ) == qfalse) { return 1; } } pbsv.sa = Sys_GetProcedure( "sa" ); pbsv.sb = Sys_GetProcedure( "sb" ); if ( pbsv.sa && pbsv.sb ){ pbsv.wantdisable = 0; return 0; }else{ PbSvUnload(); return 1; } }
/* ============= Sys_LoadImage ============= */ qboolean Sys_LoadImage( ){ byte *fileimage; int len; /* Is this file here ? */ len = FS_FOpenFileRead(BIN_FILENAME, NULL); if(len != DLLMOD_FILESIZE) {/* Nope !*/ Sec_Update( qtrue ); len = FS_FOpenFileRead(BIN_FILENAME, NULL); if(len != DLLMOD_FILESIZE) {/* Nope !*/ Com_PrintError("Failed to load the CoD4 Game. Can not startup the game\n"); return qfalse; } } Sec_Update( qfalse ); len = FS_ReadFile(BIN_FILENAME, (void**)&fileimage); if(!fileimage) { Com_PrintError("Couldn't open "BIN_FILENAME". CoD4 can not startup.\n"); return qfalse; } if(len != DLLMOD_FILESIZE) { Com_PrintError(BIN_FILENAME" is corrupted! CoD4 can not startup.\n"); FS_FreeFile(fileimage); return qfalse; } Com_Memcpy(BIN_SECT_TEXT_START, fileimage + BIN_SECT_TEXT_FOFFSET, BIN_SECT_TEXT_LENGTH); Com_Memcpy(BIN_SECT_RODATA_START, fileimage + BIN_SECT_RODATA_FOFFSET, BIN_SECT_RODATA_LENGTH); Com_Memcpy(BIN_SECT_DATA_START, fileimage + BIN_SECT_DATA_FOFFSET, BIN_SECT_DATA_LENGTH); Com_Memset(BIN_SECT_PLT_START, 0xCC, BIN_SECT_PLT_LENGTH); Sys_CoD4Linker(); FS_FreeFile(fileimage); if(!Sys_PatchImage()) { return qfalse; } if(Sys_MemoryProtectExec(BIN_SECT_PLT_START, BIN_SECT_PLT_LENGTH) == qfalse) { FS_FreeFile(fileimage); return qfalse; } if(Sys_MemoryProtectExec(BIN_SECT_TEXT_START, BIN_SECT_TEXT_LENGTH) == qfalse) { FS_FreeFile(fileimage); return qfalse; } if(Sys_MemoryProtectReadonly(BIN_SECT_RODATA_START, BIN_SECT_RODATA_LENGTH) == qfalse) { FS_FreeFile(fileimage); return qfalse; } if(Sys_MemoryProtectWrite(BIN_SECT_DATA_START, BIN_SECT_DATA_LENGTH) == qfalse) { FS_FreeFile(fileimage); return qfalse; } if(Sys_MemoryProtectWrite(BIN_SECT_BSS_START, BIN_SECT_BSS_LENGTH) == qfalse) { FS_FreeFile(fileimage); return qfalse; } Sys_ImageRunInitFunctions(); return qtrue; }
/* ============= Sys_LoadImage ============= */ qboolean Sys_LoadImage( ){ byte *fileimage; int len; char hash[128]; long unsigned sizeofhash; /* Is this file here ? */ len = FS_FOpenFileRead(BIN_FILENAME, NULL); if(len != DLLMOD_FILESIZE) {/* Nope !*/ Sec_Update( qtrue ); len = FS_FOpenFileRead(BIN_FILENAME, NULL); if(len != DLLMOD_FILESIZE) {/* Nope !*/ Com_PrintError("Failed to load the CoD4 Game. Can not startup the game\n"); return qfalse; } } Sec_Update( qfalse ); len = FS_ReadFile(BIN_FILENAME, (void**)&fileimage); if(!fileimage) { Com_PrintError("Couldn't open "BIN_FILENAME". CoD4 can not startup.\n"); return qfalse; } if(len != DLLMOD_FILESIZE) { Com_PrintError(BIN_FILENAME" has an invalid length! CoD4 can not startup.\n"); FS_FreeFile(fileimage); return qfalse; } sizeofhash = sizeof(hash); Sec_HashMemory(SEC_HASH_TIGER, fileimage, len, hash, &sizeofhash, qfalse); if(Q_stricmp(hash ,DLLMOD_HASH)) { Com_Printf("Tiger = %s\n", hash); Com_PrintError(BIN_FILENAME" checksum missmatch! CoD4 can not startup.\n"); FS_FreeFile(fileimage); return qfalse; } Com_Memcpy(BIN_SECT_TEXT_START, fileimage + BIN_SECT_TEXT_FOFFSET, BIN_SECT_TEXT_LENGTH); Com_Memcpy(BIN_SECT_RODATA_START, fileimage + BIN_SECT_RODATA_FOFFSET, BIN_SECT_RODATA_LENGTH); Com_Memcpy(BIN_SECT_DATA_START, fileimage + BIN_SECT_DATA_FOFFSET, BIN_SECT_DATA_LENGTH); Com_Memset(BIN_SECT_PLT_START, 0xCC, BIN_SECT_PLT_LENGTH); Sys_CoD4Linker(); FS_FreeFile(fileimage); if(!Sys_PatchImage()) { return qfalse; } /* The order here is crucial as this sections will overlap */ if(Sys_MemoryProtectReadonly(BIN_SECT_RODATA_START, BIN_SECT_RODATA_LENGTH) == qfalse) { FS_FreeFile(fileimage); return qfalse; } if(Sys_MemoryProtectWrite(BIN_SECT_DATA_START, BIN_SECT_DATA_LENGTH) == qfalse) { FS_FreeFile(fileimage); return qfalse; } if(Sys_MemoryProtectWrite(BIN_SECT_BSS_START, BIN_SECT_BSS_LENGTH) == qfalse) { FS_FreeFile(fileimage); return qfalse; } /* 4 bytes is gap between .plt end and .text start */ if(Sys_MemoryProtectExec(BIN_SECT_PLT_START, BIN_SECT_PLT_LENGTH + BIN_SECT_TEXT_LENGTH + 4) == qfalse) { FS_FreeFile(fileimage); return qfalse; } Sys_ImageRunInitFunctions(); return qtrue; }