Exemplo n.º 1
0
//--------------------------------------------------------------------------
/// Before launching a new process, this function will initialize the environment for the
/// new process.
/// \return true if the the environment for the new process was initialized fully.
//--------------------------------------------------------------------------
bool ProcessTracker::PrelaunchEnvironmentInitialization()
{
    // Start by assuming that this will work without a problem.
    bool bEnvironmentInitialized = true;

#ifndef _WIN32
    // Get the server path. The GLServer plugin will be in the same place.
    // LD_PRELOAD has to be set up before the app is run so the plugin can be attached
    const char* strServerPath;
    strServerPath = SG_GET_PATH(ServerPath);
    char ext[PS_MAX_PATH];
    sprintf_s(ext, PS_MAX_PATH, "%s.so", GDT_PROJECT_SUFFIX);
    char strLdPreload[PS_MAX_PATH];
    sprintf_s(strLdPreload, PS_MAX_PATH, "%sPlugins/%sServer%s", strServerPath, m_injectedAppPluginName.c_str(), ext);
    //   LogConsole(logMESSAGE, "LD_PRELOAD is >>>%s<<<\n", strLdPreload);

    // Set the LD_PRELOAD environment variable
    setenv("LD_PRELOAD", strLdPreload, 1);
#endif

#if ENABLE_VULKAN
    SetupVulkanEnvVariables();
#endif

    return bEnvironmentInitialized;
}
Exemplo n.º 2
0
// Returns reference to file that is currently being used.
//
const char* GetLogFilename()
{
    if (SG_GET_BOOL(OptionNoLogfile))
    {
        return (NULL);
    }
    else
    {
        return (SG_GET_PATH(LogfilePath));
    }
}
Exemplo n.º 3
0
//--------------------------------------------------------------------------
/// Initialize GPA.
/// \param inAPI The API being initialized.
/// \returns True if GPA initialization was successful.
//--------------------------------------------------------------------------
bool ModernAPIFrameProfilerLayer::InitializeGPA(GPA_API_Type inAPI)
{
    const char* errorMessage = NULL;
    bool bLoadSuccessful = mGPALoader.Load(SG_GET_PATH(GPUPerfAPIPath), inAPI, &errorMessage);

    if (!bLoadSuccessful)
    {
        Log(logERROR, "Failed to load GPA. Load error: %s\n", errorMessage);
    }
    else
    {
        if (mGPALoader.GPA_RegisterLoggingCallback(GPA_LOGGING_ERROR_AND_MESSAGE, (GPA_LoggingCallbackPtrType)&ModernAPIFrameProfilerLayer::GPALoggingCallback) != GPA_STATUS_OK)
        {
            Log(logERROR, "Failed to register profiler logging callback.\n");
        }
    }

    return bLoadSuccessful;
}
Exemplo n.º 4
0
//--------------------------------------------------------------
/// Is micro dll allowed to be injected into this process?
/// check the current executable with the filelist specified. If
/// it is in the list, or the list contains 'all', then injection
/// is allowed.
/// \param modulename name of the executable being started
/// \returns true if injection is allowed, false otherwise
static bool InjectionAllowed(const char* modulename)
{
    // if not using AppInit_DLLs registry key, always allow injection
    if (SG_GET_BOOL(OptionAppInitDll) == false)
    {
        return true;
    }

    // get the filename from the path. If there's an error here, don't inject
    char path[PS_MAX_PATH];
    char* filename;
    DWORD res = GetFullPathName(modulename, PS_MAX_PATH, path, &filename);

    if (res == 0)
    {
        return false;
    }

    gtASCIIString fileString = SG_GET_PATH(AppInitDllFileList);

    // if 'all' specified, always inject
    if (fileString.compareNoCase("all") == 0)
    {
        return true;
    }

    // split the list up and see if the current exe is in the list
    std::list<gtASCIIString> fileList;
    fileString.Split(",", false, fileList);

    for (std::list<gtASCIIString>::const_iterator it = fileList.begin(); it != fileList.end(); ++it)
    {
        if ((*it).compareNoCase(filename) == 0)
        {
            // file is in list, inject
            return true;
        }
    }

    return false;
}
Exemplo n.º 5
0
//--------------------------------------------------------------
//  LaunchAppInNewProcess
//--------------------------------------------------------------
PROCESS_INFORMATION ProcessTracker::LaunchAppInNewProcess(gtASCIIString strApp, gtASCIIString strDir, gtASCIIString strArgs, osModuleArchitecture binaryType)
{
#ifdef _LINUX
    PS_UNREFERENCED_PARAMETER(binaryType);
#endif
    LogConsole(logMESSAGE, "About to launch: %s\n", strApp.asCharArray());
    LogConsole(logMESSAGE, "Params: %s\n", strArgs.asCharArray());
    LogConsole(logMESSAGE, "Working Directory: %s\n", strDir.asCharArray());

    // Get app directory and make it default
    if (strDir.isEmpty())
    {
        size_t pos = strApp.find_last_of("\\");

        if (pos != std::string::npos)
        {
            strDir = strApp.substr(0, (int)pos);

            if (strApp[0] == '\"')
            {
                strDir += "\"";
            }
        }
    }

    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(pi));

#ifdef _WIN32
    DWORD dwFlags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED;

    SetLastError(0);

    STARTUPINFO si;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
#endif

    // Cmd line has to include the exe name since many apps expect the executable name to be in argv[0]!
    // Note argv[0] on the command line needs to be surrounded with quotes if it contains spaces.
    // The arguments in strArgs have already been "quoted" as they are parsed.

    gtASCIIString strCmdLine = AddQuotesIfStringHasSpaces(strApp.asCharArray());
    strCmdLine += " ";
    strCmdLine += strArgs;

    LogConsole(logMESSAGE, "strApp: %s\n", strApp.asCharArray());
    LogConsole(logMESSAGE, "strCmdLine: %s\n", strCmdLine.asCharArray());

    // Attempt to initialize the environment that the new process will run in. The child process should inherit "this" environment.
    if (!PrelaunchEnvironmentInitialization())
    {
        // Log a warning if this failed- initializing the environment for the new process can fail if Mantle support isn't installed.
        // In these cases, if the user is attempting to debug a Mantle application, they will have bigger problems to deal with.
        // In cases where a DX/GL app is being debugged, this warning can be ignored without any side effects.
        Log(logWARNING, "Environment initialization failed. If using DX/GL, it is safe to ignore this warning.\n");
    }

    BOOL succeeded = FALSE;

#ifdef _WIN32

    char microDLLPath[PS_MAX_PATH];
    const char* strServerPath;
    strServerPath = SG_GET_PATH(ServerPath);

    if (SG_GET_BOOL(OptionDllReplacement) == true)
    {
        DllReplacement::SetDllDirectory(binaryType == OS_X86_64_ARCHITECTURE);
    }

    // if using manual dll replacement or the AppInit_DLLs registry setting, don't use any kind of dll injection
    if (SG_GET_BOOL(OptionManualDllReplacement) == true || SG_GET_BOOL(OptionAppInitDll))
    {
        succeeded = CreateProcess(strApp.asCharArray(), (LPSTR)strCmdLine.asCharArray(), NULL, NULL, TRUE, dwFlags, NULL, strDir.asCharArray(), &si, &pi);
    }
    else
    {
#ifdef X64

        // can only launch 64 bit applications
        if (binaryType != OS_X86_64_ARCHITECTURE)
        {
            sprintf_s(microDLLPath, PS_MAX_PATH, "%s" MICRODLLNAME "%s%s.dll", SG_GET_PATH(ServerPath), GDT_DEBUG_SUFFIX, GDT_BUILD_SUFFIX);
            succeeded = AMDT::CreateProcessAndInjectDll(strApp.asCharArray(), (LPSTR)strCmdLine.asCharArray(),
                                                        NULL, NULL, TRUE, dwFlags, NULL,
                                                        strDir.asCharArray(),
                                                        &si, &pi,
                                                        microDLLPath);
        }

#else

        if (binaryType != OS_I386_ARCHITECTURE)
        {
            sprintf_s(microDLLPath, PS_MAX_PATH, "%s" MICRODLLNAME "-x64%s%s.dll", SG_GET_PATH(ServerPath), GDT_DEBUG_SUFFIX, GDT_BUILD_SUFFIX);
            succeeded = AMDT::CreateProcessAndInjectDll(strApp.asCharArray(), (LPSTR)strCmdLine.asCharArray(),
                                                        NULL, NULL, TRUE, dwFlags, NULL,
                                                        strDir.asCharArray(),
                                                        &si, &pi,
                                                        microDLLPath);
        }

#endif // X64
        else
        {
            succeeded = AMDT::CreateProcessAndInjectDll(strApp.asCharArray(), (LPSTR)strCmdLine.asCharArray(),
                                                        NULL, NULL, TRUE, dwFlags, NULL,
                                                        strDir.asCharArray(),
                                                        &si, &pi,
                                                        SG_GET_PATH(MicroDLLPath));
        }
    }

#else

    // Create the app process
    succeeded = CreateProcess(strApp.asCharArray(), strCmdLine.asCharArray(), strDir.asCharArray(), &pi);
#endif // _WIN32

    if (!succeeded)
    {
        osSystemErrorCode systemLastError = osGetLastSystemError();

        gtString systemErrorString;
        osGetLastSystemErrorAsString(systemErrorString);

        Log(logERROR, "CreateProcessAndInjectDll failed; Error %d: %s\n", systemLastError, systemErrorString.asASCIICharArray());
        pi.dwProcessId = 0;
    }

#ifdef _WIN32
    else
    {
        // Check to see if the Steam.exe has been hooked and if so, set the value in shared memory
        // If Steam.exe was used to launch the target application, then the checks for cmd.exe and fcx.exe
        // need to be ignored.
        if (strApp.length() > 0)
        {
            if (strstr(strApp.toLowerCase().asCharArray(), "steam.exe") != NULL)
            {
                SG_SET_BOOL(SteamInjected, true);
            }

            ShowLauncherReminder(strApp.toLowerCase().asCharArray());
        }
        else
        {
            if (strstr(strCmdLine.toLowerCase().asCharArray(), "steam.exe") != NULL)
            {
                SG_SET_BOOL(SteamInjected, true);
            }

            ShowLauncherReminder(strCmdLine.toLowerCase().asCharArray());
        }
    }

#endif // _WIN32

    return pi;
}
Exemplo n.º 6
0
//--------------------------------------------------------------
///   DllMain
/// \param hModule Module
/// \param ul_reason_for_call Reason for call
/// \param lpReserved Reserved
/// \return True or false
//--------------------------------------------------------------
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    PS_UNREFERENCED_PARAMETER(hModule);
    PS_UNREFERENCED_PARAMETER(lpReserved);

    if (AMDT::InitHookDLL(ul_reason_for_call) == false)
    {
        return TRUE;
    }

    BOOL retVal = TRUE;
    char modulename[MAX_PATH];
    GetModuleFileNameA(NULL, modulename, MAX_PATH);

    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
        {
            if (OSWrappers::IsProcessRunning(sWebServerName, true) && InjectionAllowed(modulename))
            {
                Log(logMESSAGE, "Attaching to %s\n", modulename);
                Log(logMESSAGE, "DllMain DLL_PROCESS_ATTACH module %s\n", modulename);

                if (SG_GET_BOOL(OptionDllReplacement) == true)
                {
                    UpdateHooksOnLoadLibrary();
                }

#ifdef _WIN32
                {
                    // Initialize and register the unhandled exception handler:
                    bool rc1 = UnhandledExceptionHandler::init();

                    if (rc1)
                    {
                        Log(logMESSAGE, "Registered unhandled exception handler\n");
                    }
                    else
                    {
                        Log(logERROR, "Failed to register unhandled exception handler\n");
                    }
                }
#endif

                // @Note: Do we need to do this? Overwriting it doesn't seem to break anything?
                // get current directory so we can specify as a location for DLLs to be loaded from
                char curDir[PS_MAX_PATH];
                GetCurrentDirectory(PS_MAX_PATH, curDir);

                // SetDllDirectory requires XP SP1 or later.
                SetDllDirectory(curDir);

                sprintf_s(g_MicroDLLPath, PS_MAX_PATH, "%s", SG_GET_PATH(MicroDLLPath));

                CollectWrapperInfo();

                if (SG_GET_BOOL(OptionNoProcessTrack) == false)
                {
                    HookCreateProcess();
                    Log(logMESSAGE, "Process Tracking is ON\n");
                }
                else
                {
                    Log(logMESSAGE, "Process Tracking is OFF\n");
                }

                // At the moment, dxgi.dll is implicitly loaded from HookLoadLibrary
                // Force the Dll folder to point to our replaced dll's so the replace version
                // of dxgi.dll is loaded
                if (SG_GET_BOOL(OptionDllReplacement) == true)
                {
                    // Get architecture of parent application (32 or 64 bit)
                    osModuleArchitecture binaryType;
                    OSWrappers::GetBinaryType(modulename, &binaryType);
                    DllReplacement::SetDllDirectory(binaryType == OS_X86_64_ARCHITECTURE);
                }

                if (SG_GET_BOOL(OptionManualDllReplacement) == false)
                {
                    HookLoadLibrary();
                }
            }
            else
            {
                // set return value to FALSE. This will indicate a load error so the loader will
                // next unload this dll
                retVal = FALSE;
            }

            break;
        }

        case DLL_THREAD_ATTACH:
        {
            Log(logMESSAGE, "DllMain DLL_THREAD_ATTACH to %i %s\n", GetCurrentProcessId(), modulename);
        }
        break;

        case DLL_THREAD_DETACH:
        {
            Log(logMESSAGE, "DllMain DLL_THREAD_DETACH to %i %s\n", GetCurrentProcessId(), modulename);
        }
        break;

        case DLL_PROCESS_DETACH:
        {
            if (OSWrappers::IsProcessRunning(sWebServerName, true))
            {
                Log(logMESSAGE, "DllMain DLL_PROCESS_DETACH from module %s\n", modulename);

                if (SG_GET_BOOL(OptionNoProcessTrack) == false)
                {
                    UnhookCreateProcess();
                }

                UnhookLoadLibrary();
            }
        }
        break;

        default:
        {
            Log(logMESSAGE, "DllMain Unhandled switch case module %s\n", modulename);
        }
        break;
    }

    return retVal;
}