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