Exemplo n.º 1
0
void PHandler_Load(char* name) // Load a plugin, safe for use
{
    int i,j;
    char* realpath;
    char filepathbuf[MAX_OSPATH];
    char hash[128];
    long unsigned sizeofhash;
    void *lib_handle;

    pluginInfo_t info;

    if(!pluginFunctions.enabled){
        Com_Printf("Plugin handler is not initialized!\n");
        return;

    }
    if(pluginFunctions.loadedPlugins>=MAX_PLUGINS-1){
        Com_Printf("Too many plugins loaded.");
        return;
    }
    /* +18 for "plugins/%s.dynlib" */
    if(strlen(name) + 18 >= sizeof(pluginFunctions.plugins[0].name)){
        Com_Printf("Pluginname is too long.");
        return;
    }
    Com_DPrintf("Checking if the plugin is not already loaded...\n");
    //    Check if the plugin is not already loaded...
    for(i=0;i<MAX_PLUGINS;i++){
        if(Q_stricmp(name, pluginFunctions.plugins[i].name) == qfalse){
            Com_Printf("This plugin is already loaded!\n");
            return;
        }
    }
    Com_DPrintf("Checking if the plugin file exists and is of correct format...\n");

    //Additional test if a file is there
    realpath = (char*)PHandler_OpenTempFile(name, filepathbuf, sizeof(filepathbuf)); // Load a plugin, safe for use
    if(realpath == NULL)
    {
        return;
    }

    Com_DPrintf("Loading the plugin .so...\n");


    if(com_securemode)
    {
	hash[0] = '\0';
	sizeofhash = sizeof(hash);

	Sec_HashFile(SEC_HASH_TIGER, realpath, hash, &sizeofhash, qfalse);

	if(Q_stricmp(hash ,PLUGINGAMERANGER_HASH) && Q_stricmp(hash ,PLUGINCENSOR_HASH) && Q_stricmp(hash ,PLUGINANTISPAM_HASH))
	{
		Com_Printf("Tiger = %s\n", hash);
		Com_PrintError("%s checksum missmatch! This plugin will not be loaded in securemode.\n", realpath);
		return;
	}

    }

    lib_handle = Sys_LoadLibrary(realpath);
    if (!lib_handle)
	{
        Com_PrintError("Failed to load the plugin %s!\n", realpath);
        PHandler_CloseTempFile( realpath );
        return;
    }
    PHandler_CloseTempFile( realpath );
    Com_DPrintf("Plugin OK! Loading...\n");
    // find first free plugin slot
    for(i=0;i<MAX_PLUGINS;i++){
        if(!(pluginFunctions.plugins[i].loaded))
            break;
    }
    pluginFunctions.plugins[i].OnInit = Sys_GetProcedure("OnInit");
    for(j=0;j<PLUGINS_ITEMCOUNT;++j){
        pluginFunctions.plugins[i].OnEvent[j] = Sys_GetProcedure(PHandler_Events[j]);

    }
    pluginFunctions.plugins[i].OnInfoRequest = pluginFunctions.plugins[i].OnEvent[PLUGINS_ONINFOREQUEST];
    pluginFunctions.plugins[i].OnUnload = Sys_GetProcedure("OnUnload");
    pluginFunctions.plugins[i].loaded = qtrue;
    pluginFunctions.plugins[i].enabled = qtrue;
    Q_strncpyz(pluginFunctions.plugins[i].name, name, sizeof(pluginFunctions.plugins[i].name));
    pluginFunctions.initializing_plugin = qtrue;

    if(pluginFunctions.plugins[i].OnInit==NULL){
        Com_Printf("Error loading plugin's OnInit function.\nPlugin load failed.\n");
        pluginFunctions.initializing_plugin = qfalse;
        memset(pluginFunctions.plugins + i,0x00,sizeof(plugin_t));    // We need to remove all references so we can dlclose.
        Sys_CloseLibrary(lib_handle);
        return;
    }

    pluginFunctions.hasControl = PLUGIN_UNKNOWN;
    Com_Printf("Plugin's OnInit executed successfully!\n");
    //    Save info about the loaded plugin
    pluginFunctions.initializing_plugin = qfalse;
    pluginFunctions.loadedPlugins++;
    pluginFunctions.plugins[i].lib_handle = lib_handle;

    if(pluginFunctions.plugins[i].OnInfoRequest){
        Com_DPrintf("Fetching plugin information...\n");
        pluginFunctions.hasControl = i;
        (*pluginFunctions.plugins[i].OnInfoRequest)(&info);
        pluginFunctions.hasControl = PLUGIN_UNKNOWN;
			
        if(info.handlerVersion.major != PLUGIN_HANDLER_VERSION_MAJOR || (info.handlerVersion.minor - info.handlerVersion.minor %100) != (PLUGIN_HANDLER_VERSION_MINOR - PLUGIN_HANDLER_VERSION_MINOR %100))
	{
            Com_PrintError("This plugin might not be compatible with this server version! Requested plugin handler version: %d.%d, server's plugin handler version: %d.%d. Unloading the plugin...\n",info.handlerVersion.major,info.handlerVersion.minor, PLUGIN_HANDLER_VERSION_MAJOR,PLUGIN_HANDLER_VERSION_MINOR);
            PHandler_Unload(i);
            return;
        }

    }else{

        Com_PrintError("function OnInfoRequest not found in the plugin file. Unloading...\n");
        PHandler_Unload(i);
        return;

    }

    Com_DPrintf("Executing plugin's OnInit...\n");

    pluginFunctions.hasControl = i;
    if((*pluginFunctions.plugins[i].OnInit)()<0)
    {
        pluginFunctions.hasControl = PLUGIN_UNKNOWN;
        Com_Printf("Error in plugin's OnInit function!\nPlugin load failed.\n");
        pluginFunctions.initializing_plugin = qfalse;
        memset(pluginFunctions.plugins + i,0x00,sizeof(plugin_t));    // We need to remove all references so we can dlclose.
        Sys_CloseLibrary(lib_handle);
        return;
    }

    Com_Printf("Plugin %s loaded successfully. Server is currently running %d plugins.\n",pluginFunctions.plugins[i].name,pluginFunctions.loadedPlugins);
    return;

}
Exemplo n.º 2
0
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;
	}

}