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++;
}
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;
}
Ejemplo n.º 3
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;
	}

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