void update_environment(char* base_path)
{
    /*
     Set the following environment variables:
     1) PIN_VM_LD_LIBRARY_PATH (put pin_libs in front of existing LD_LIBRARY_PATH)
     2) PIN_LD_RESTORE_REQUIRED (set it to "t")
     3) PIN_APP_LD_LIBRARY_PATH (copy of LD_LIBRARY_PATH (if set))
     4) PIN_APP_LD_ASSUME_KERNEL (copy of LD_ASSUME_KERNEL (if set))
     4a) PIN_APP_LD_BIND_NOW
     4b) PIN_APP_LD_PRELOAD
     5) unset LD_ASSUME_KERNEL
     6) LD_LIBRARY_PATH          (injector_libs before users's LD_LIBRARY_PATH)

     On Unix systems, we run pinbin instead of pin.
     */

    int r;
    int gcc_major = 0, gcc_minor = 0;
    const int overwrite = 1;
    char* pin_ld_library_path = 0;
    char* new_ld_library_path = 0;
    const char* pin_runtime_dir = "runtime";
    const char* glibc_lib_dir = "glibc";
    const char* cpp_lib_dir = "cpplibs";
    char* ld_library_path = 0;
    char* ld_assume_kernel = 0;
    char* base_path32 = 0;
    char* base_path64 = 0;
    char* pin_runtime_libs32 = 0;
    char* pin_runtime_libs64 = 0;
    char* pin_glibc_libs32 = 0;
    char* pin_glibc_libs64 = 0;
    char* pin_cpp_libs32 = 0;
    char* pin_cpp_libs64 = 0;
    char* incoming_ld_preload = 0;
    char* incoming_ld_bind_now = 0;
    int getGccPassed = 0;

    base_path32 = append3(base_path, "/", "ia32");
    base_path64 = append3(base_path, "/", "intel64");

    /* make pin_libs - required for pin/vm */
    pin_runtime_libs32 = append3(base_path32, "/", pin_runtime_dir);
    pin_runtime_libs64 = append3(base_path64, "/", pin_runtime_dir);

    pin_glibc_libs32 = append3(pin_runtime_libs32, "/", glibc_lib_dir);
    pin_glibc_libs64 = append3(pin_runtime_libs64, "/", glibc_lib_dir);

    pin_cpp_libs32 = append3(pin_runtime_libs32, "/", cpp_lib_dir);;
    pin_cpp_libs64 = append3(pin_runtime_libs64, "/", cpp_lib_dir);;

    /* make pin_ld_library_path pre-pending pin_libs -- for the VM ultimately */
    ld_library_path = getenv("LD_LIBRARY_PATH");
    pin_ld_library_path = ld_library_path;

    /* must be first (so added last) */
    pin_ld_library_path = append3(pin_glibc_libs32, ":", pin_ld_library_path);
    pin_ld_library_path = append3(pin_glibc_libs64, ":", pin_ld_library_path);

    getGccPassed = get_gcc_version_string(&gcc_major, &gcc_minor);

    if (!getGccPassed || gcc_major < 4 || (gcc_major == 4 && gcc_minor < 5)) {
        pin_ld_library_path = append3(pin_cpp_libs32, ":", pin_ld_library_path);
        pin_ld_library_path = append3(pin_cpp_libs64, ":", pin_ld_library_path);
    }

    pin_ld_library_path = append3(pin_runtime_libs32, ":", pin_ld_library_path);
    pin_ld_library_path = append3(pin_runtime_libs64, ":", pin_ld_library_path);

    /* make new_ld_library_path pre-pending injector_libs */
    new_ld_library_path = ld_library_path;

    if (!getGccPassed || gcc_major < 4 || (gcc_major == 4 && gcc_minor < 5)) {
        new_ld_library_path = append3(pin_cpp_libs32, ":", new_ld_library_path);
        new_ld_library_path = append3(pin_cpp_libs64, ":", new_ld_library_path);
    }

    /* must be first (so added last) */
    new_ld_library_path = append3(pin_runtime_libs32, ":", new_ld_library_path);
    new_ld_library_path = append3(pin_runtime_libs64, ":", new_ld_library_path);

    /* This variable tells the injector to restore environment variables after pin is injected. */
    r = setenv("PIN_LD_RESTORE_REQUIRED", "t", overwrite);
    check_retval(r, "setenv PIN_LD_RESTORE_REQUIRED");

    /* Set the pin vm library path. */
    r = setenv("PIN_VM_LD_LIBRARY_PATH", pin_ld_library_path, overwrite);
    check_retval(r, "setenv PIN_VM_LD_LIBRARY_PATH");

    /*
     * Backup the LD_LIBRARY_PATH, since pin uses a different one while launching. It will be restored
     * when the app is loaded to memory.
     */
    if (ld_library_path)
    {
        r = setenv("PIN_APP_LD_LIBRARY_PATH", ld_library_path, overwrite);
        check_retval(r, "setenv PIN_APP_LD_LIBRARY_PATH");
    }

    /* Overwrite LD_LIBRARY_PATH with the libraries required for pin to run. */
    r = setenv("LD_LIBRARY_PATH", new_ld_library_path, overwrite);
    check_retval(r, "setenv LD_LIBRARY_PATH");

    /*
     * If the LD_BIND_NOW, LD_ASSUME_KERNEL and LD_PRELOAD variables were defined they should pass as
     * is to the app. Since pin's injector doesn't need it, we save them now and restore it after
     * pin is injected into the process.
     */
    ld_assume_kernel = getenv("LD_ASSUME_KERNEL");
    if (ld_assume_kernel)
    {
        r = setenv("PIN_APP_LD_ASSUME_KERNEL", ld_assume_kernel, overwrite);
        check_retval(r, "setenv PIN_APP_LD_ASSUME_KERNEL");
        unsetenv("LD_ASSUME_KERNEL");
    }

    incoming_ld_bind_now = getenv("LD_BIND_NOW");
    if (incoming_ld_bind_now)
    {
        r = setenv("PIN_APP_LD_BIND_NOW", incoming_ld_bind_now, overwrite);
        check_retval(r, "setenv PIN_APP_LD_BIND_NOW");
        unsetenv("LD_BIND_NOW");
    }

    incoming_ld_preload = getenv("LD_PRELOAD");
    if (incoming_ld_preload)
    {
        r = setenv("PIN_APP_LD_PRELOAD", incoming_ld_preload, overwrite);
        check_retval(r, "setenv PIN_APP_LD_PRELOAD");
        unsetenv("LD_PRELOAD");
    }

}
Example #2
0
int dbg_help_client_t::init(char* path) {
    DWORD64 dwBaseAddr=0;

    int chars;
    char exe_path[MAX_PATH];
    chars = GetModuleFileName(NULL, exe_path, MAX_PATH);
    if (chars == 0) { 
        fprintf(stderr,"Could not find base path for XED executable\n");
        fflush(stderr);
        exit(1);
    }
    //fprintf(stderr,"EXE PATH %s\n", exe_path);
    char* dir = find_base_path(exe_path);
    //fprintf(stderr,"DIR      %s\n", dir);

    char* dbghelp = append3(dir,"\\","dbghelp.dll");
    //fprintf(stderr,"DBGHLP   %s\n", dbghelp);

    if (_access_s(dbghelp,4) != 0) {
        //fprintf(stderr,
        //    "WARNING: Could not find dbghelp.dll in xed.exe directory\n");
        //fflush(stderr);
        return 0;
    }    
    //fprintf(stderr,"FOUND DBGHELP\n");

    if (validate_version(dbghelp)) {
        fprintf(stderr,
            "WARNING: dbghelp.dll version is too old\n");
        fflush(stderr);
        return 0;
    }


    //FIXME: Add a version check for the dll ( ImagehlpApiVersion is NOT
    //the right thing)
        
    SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
    hProcess = GetCurrentProcess();
    
    if (SymInitialize(hProcess, NULL, FALSE))     {
        // nothing
    }
    else    {
        error = GetLastError();
        fprintf(stderr,"SymInitialize returned error : %d 0x%x\n",
                error, error);
        fflush(stderr);
        return 0;
    }


    actual_base = SymLoadModuleEx(hProcess, NULL, path, NULL, 
                                  dwBaseAddr, 0, NULL, 0);
    if (actual_base) {
        // nothing
    }
    else    {
        error = GetLastError();
        fprintf(stderr,"SymLoadModuleEx returned error : %d 0x%x\n", 
                error, error);
        fflush(stderr);
        return 0;
    }


    if (SymEnumerateModules64(hProcess, 
                        (PSYM_ENUMMODULES_CALLBACK64)enum_modules, this)) {
        // nothing
    }
    else    {
        error = GetLastError();
        fprintf(stderr,"SymEnumerateModules64 returned error : %d 0x%x\n",
               error, error);
        fflush(stderr);
        return 0;
    }

    if (SymEnumSymbols(hProcess, actual_base, 0, enum_sym, this))    {
        // nothing
    }
    else    {
        error = GetLastError();
        fprintf(stderr,"SymEnumSymbols failed: %d 0x%x\n", error, error);
        fflush(stderr);
        return 0;
    }

    make_symbol_vector(&sym_tab);
    initialized = true;
    return 1;
}