Esempio n. 1
0
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;
}