Beispiel #1
0
/* Implements a normal path search for fname on the paths in env_var.
 * Resolves symlinks, which is needed to get the right config filename (i#1062).
 */
drfront_status_t
drfront_searchenv(const char *fname, const char *env_var, OUT char *full_path,
                  const size_t full_path_size, OUT bool *ret)
{
    const char *paths = getenv(env_var);
    const char *cur;
    const char *next;
    const char *end;
    char tmp[full_path_size];
    char realpath_buf[PATH_MAX]; /* realpath hardcodes its buffer length */
    drfront_status_t status_check = DRFRONT_ERROR;
    bool access_ret = false;

    if (ret == NULL)
        return DRFRONT_ERROR_INVALID_PARAMETER;

    /* Windows searches the current directory first. */
    /* XXX: realpath resolves symlinks, which we may not want. */
    if (realpath(fname, realpath_buf) != NULL) {
        status_check = drfront_access(realpath_buf, DRFRONT_EXIST, &access_ret);
        if (status_check != DRFRONT_SUCCESS) {
            *ret = false;
            return status_check;
        } else if (access_ret == true) {
            *ret = true;
            snprintf(full_path, full_path_size, "%s", realpath_buf);
            full_path[full_path_size - 1] = '\0';
            return DRFRONT_SUCCESS;
        }
    }

    cur = paths;
    end = strchr(paths, '\0');
    while (cur < end) {
        next = strchr(cur, ':');
        next = (next == NULL ? end : next);
        snprintf(tmp, BUFFER_SIZE_ELEMENTS(tmp),
                 "%.*s/%s", (int)(next - cur), cur, fname);
        NULL_TERMINATE_BUFFER(tmp);
        /* realpath checks for existence too. */
        if (realpath(tmp, realpath_buf) != NULL) {
            status_check = drfront_access(realpath_buf, DRFRONT_EXIST, &access_ret);
            if (status_check != DRFRONT_SUCCESS) {
                *ret = false;
                return status_check;
            } else if (access_ret == true) {
                *ret = true;
                snprintf(full_path, full_path_size, "%s", realpath_buf);
                full_path[full_path_size - 1] = '\0';
                return DRFRONT_SUCCESS;
            }
        }
        cur = next + 1;
    }
    full_path[0] = '\0';
    *ret = false;
    return DRFRONT_ERROR;
}
Beispiel #2
0
drfront_status_t
drfront_set_client_symbol_search_path(const char *symdir, bool ignore_env,
                                      OUT char *symsrv_path, size_t symsrv_path_sz)
{
    char app_symsrv_path[MAX_SYMSRV_PATH];
    TCHAR wapp_symsrv_path[MAX_SYMSRV_PATH];
    char tmp_srv_path[MAX_SYMSRV_PATH];
    char tmp_symsrv_path[MAX_SYMSRV_PATH];
    char *cur;
    char *end;
    size_t sofar;
    ssize_t len;
    bool has_srv;
    bool dir_exists;
    bool has_ms_symsrv;
    drfront_status_t sc;
    static const char ms_symsrv[] = "http://msdl.microsoft.com/download/symbols";

    if (sym_set_path_func == NULL)
        return DRFRONT_ERROR_LIB_UNSUPPORTED;
    /* If the user set a non-empty _NT_SYMBOL_PATH, then we use that.
     * If not, we use symdir/symbols path and make sure it exists.
     */
    if (ignore_env ||
        drfront_get_env_var("_NT_SYMBOL_PATH", tmp_symsrv_path,
                            BUFFER_SIZE_ELEMENTS(tmp_symsrv_path)) != DRFRONT_SUCCESS ||
        strlen(tmp_symsrv_path) == 0) {
        char pdb_dir[MAXIMUM_PATH];
        _snprintf(pdb_dir, BUFFER_SIZE_ELEMENTS(pdb_dir), "%s/symbols", symdir);
        NULL_TERMINATE_BUFFER(pdb_dir);
        drfront_string_replace_character(pdb_dir, '/', '\\'); /* canonicalize */
        sc = drfront_create_dir(pdb_dir);
        if ((sc != DRFRONT_SUCCESS && sc != DRFRONT_ERROR_FILE_EXISTS) ||
            drfront_access(pdb_dir, DRFRONT_READ, &dir_exists) != DRFRONT_SUCCESS ||
            !dir_exists) {
            DO_DEBUG(DL_WARN,
                     printf("Failed to create directory for symbols: %s\n", pdb_dir);
                     );
Beispiel #3
0
int main()
{
    bool dir_exists;
    int res;
    res = drfront_create_dir("test_dir");
    if (res != DRFRONT_SUCCESS && res != DRFRONT_EXIST) {
        printf("drfront_create_dir failed \n");
        return -1;
    }
    if (drfront_access("test_dir", DRFRONT_EXIST, 
                       &dir_exists) != DRFRONT_SUCCESS ||
        !dir_exists) {
        printf("failed to get access to test_dir\n");
        return -1;
    }

    res = drfront_remove_dir("test_dir");
    if (res != DRFRONT_SUCCESS) {
        printf("drfront_remove_dir failed\n");
        return -1;
    }
#ifdef WINDOWS
    if (drfront_sym_init(NULL, DBGHELP_LIB) != DRFRONT_SUCCESS) {
        printf("drfront_sym_init failed\n");
        return -1;
    }
    if (drfront_sym_exit() != DRFRONT_SUCCESS) {
        printf("drfront_sym_init failed\n");
        return -1;
    }
#endif

    /* XXX i#1488: We need more tests for frontend routines. */
    printf("all done\n");
    return 0;
}
static bool
file_is_writable(char *path)
{
    bool ret = false;
    return (drfront_access(path, DRFRONT_WRITE, &ret) == DRFRONT_SUCCESS && ret);
}
static bool
file_is_readable(char *path)
{
    bool ret = false;
    return (drfront_access(path, DRFRONT_READ, &ret) == DRFRONT_SUCCESS && ret);
}
Beispiel #6
0
static bool
check_architecture(const char *dll, char **argv)
{
    bool is_64bit, also_32bit;
    if (drfront_is_64bit_app(dll, &is_64bit, &also_32bit) != DRFRONT_SUCCESS) {
        printf("ERROR: unable to get the architecture infomation of"
               " the target module %s\n", dll);
        return false;
    }
    if (IF_X64_ELSE(!is_64bit, is_64bit && !also_32bit)) {
        char *orig_argv0 = argv[0];
        char root[MAXIMUM_PATH];
        char buf[MAXIMUM_PATH];
        char *basename;
        int errcode;
        void *inject_data;
        bool is_readable;
        if (drfront_get_app_full_path(argv[0], root, BUFFER_SIZE_ELEMENTS(root)) !=
            DRFRONT_SUCCESS) {
            printf("ERROR: unable to get base dir of %s\n", argv[0]);
            return false;
        }
        basename = root + strlen(root) - 1;
        while (*basename != DIRSEP && *basename != ALT_DIRSEP && basename > root)
            basename--;
        if (basename <= root) {
            printf("ERROR: unable to get base dir of %s\n", argv[0]);
            return false;
        }
        *basename = '\0';
        basename++;
        _snprintf(buf, BUFFER_SIZE_ELEMENTS(buf) ,
                  "%s%c..%c%s%c%s", root, DIRSEP, DIRSEP,
                  IF_X64_ELSE("bin", "bin64"), DIRSEP, basename);
        NULL_TERMINATE_BUFFER(buf);
        if (drfront_access(buf, DRFRONT_READ, &is_readable) != DRFRONT_SUCCESS ||
            !is_readable) {
            printf("ERROR: unable to find frontend %s to match target file bitwidth: "
                   "is this an incomplete installation?\n", buf);
        }
        argv[0] = buf;
#ifdef UNIX
        errcode = dr_inject_prepare_to_exec(buf, (const char **)argv, &inject_data);
        if (errcode == 0 || errcode == WARN_IMAGE_MACHINE_TYPE_MISMATCH_EXE)
            dr_inject_process_run(inject_data); /* shouldn't return */
        printf("ERROR (%d): unable to launch frontend to match target file bitwidth\n",
               errcode);
        argv[0] = orig_argv0;
        return false;
#else
        errcode = dr_inject_process_create(buf, argv, &inject_data);
        if (errcode == 0 || errcode == WARN_IMAGE_MACHINE_TYPE_MISMATCH_EXE) {
            dr_inject_process_run(inject_data);
            /* Wait for the child so user's shell prompt doesn't come back early */
            errcode = WaitForSingleObject(dr_inject_get_process_handle(inject_data),
                                          INFINITE);
            if (errcode != WAIT_OBJECT_0)
                printf("WARNING: failed to wait for cross-arch frontend\n");
            dr_inject_process_exit(inject_data, false);
            argv[0] = orig_argv0;
            return false;
        } else {
            printf("ERROR (%d): unable to launch frontend to match target file bitwidth\n",
                  errcode);
            argv[0] = orig_argv0;
            return false;
        }
#endif
    }
    return true;
}
Beispiel #7
0
int
_tmain(int argc, TCHAR *targv[])
{
    int res = 1;
    char **argv;
    char dll[MAXIMUM_PATH];
    int i;
    /* module + address per line */
    char line[MAXIMUM_PATH*2];
    size_t modoffs;

    /* options that can be local vars */
    bool addr2sym = false;
    bool addr2sym_multi = false;
    bool sym2addr = false;
    bool enumerate = false;
    bool enumerate_all = false;
    bool search = false;
    bool searchall = false;
    bool enum_lines = false;

#if defined(WINDOWS) && !defined(_UNICODE)
# error _UNICODE must be defined
#else
    /* Convert to UTF-8 if necessary */
    if (drfront_convert_args((const TCHAR **)targv, &argv, argc) != DRFRONT_SUCCESS) {
        printf("ERROR: failed to process args\n");
        return 1;
    }
#endif

    for (i = 1; i < argc; i++) {
        if (_stricmp(argv[i], "-e") == 0) {
            bool is_readable;
            if (i+1 >= argc) {
                PRINT_USAGE(argv[0]);
                goto cleanup;
            }
            i++;
            if (drfront_get_absolute_path(argv[i], dll, BUFFER_SIZE_ELEMENTS(dll)) !=
                DRFRONT_SUCCESS) {
                printf("ERROR: invalid path %s\n", argv[i]);
                goto cleanup;
            }
            if (drfront_access(dll, DRFRONT_READ, &is_readable) != DRFRONT_SUCCESS ||
                !is_readable) {
                printf("ERROR: invalid path %s\n", argv[i]);
                goto cleanup;
            }
        } else if (_stricmp(argv[i], "-f") == 0) {
            show_func = true;
        } else if (_stricmp(argv[i], "-v") == 0) {
            verbose = true;
        } else if (_stricmp(argv[i], "-a") == 0 ||
                   _stricmp(argv[i], "-s") == 0) {
            if (i+1 >= argc) {
                PRINT_USAGE(argv[0]);
                goto cleanup;
            }
            if (_stricmp(argv[i], "-a") == 0)
                addr2sym = true;
            else
                sym2addr = true;
            i++;
            /* rest of args read below */
            break;
        } else if (_stricmp(argv[i], "--lines") == 0) {
            enum_lines = true;
        } else if (_stricmp(argv[i], "-q") == 0) {
            addr2sym_multi = true;
        } else if (_stricmp(argv[i], "--enum") == 0) {
            enumerate = true;
        } else if (_stricmp(argv[i], "--list") == 0) {
            enumerate_all = true;
        } else if (_stricmp(argv[i], "--search") == 0) {
            search = true;
        } else if (_stricmp(argv[i], "--searchall") == 0) {
            search = true;
            searchall = true;
        } else {
            PRINT_USAGE(argv[0]);
            goto cleanup;
        }
    }
    if ((!addr2sym_multi && dll == NULL) ||
        (addr2sym_multi && dll != NULL) ||
        (!sym2addr && !addr2sym && !addr2sym_multi && !enumerate_all && !enum_lines)) {
        PRINT_USAGE(argv[0]);
        goto cleanup;
    }

    dr_standalone_init();

    if (dll != NULL) {
        if (!check_architecture(dll, argv))
            goto cleanup;
    }

    if (drsym_init(IF_WINDOWS_ELSE(NULL, 0)) != DRSYM_SUCCESS) {
        printf("ERROR: unable to initialize symbol library\n");
        goto cleanup;
    }

    if (!addr2sym_multi) {
        if (enum_lines)
            enumerate_lines(dll);
        else if (enumerate_all)
            enumerate_symbols(dll, NULL, search, searchall);
        else {
            /* kind of a hack: assumes i hasn't changed and that -s/-a is last option */
            for (; i < argc; i++) {
                if (addr2sym) {
                    if (sscanf(argv[i], SIZE_FMT, &modoffs) == 1)
                        symquery_lookup_address(dll, modoffs);
                    else
                        printf("ERROR: unknown input %s\n", argv[i]);
                } else if (enumerate || search)
                    enumerate_symbols(dll, argv[i], search, searchall);
                else
                    symquery_lookup_symbol(dll, argv[i]);
            }
        }
    } else {
        while (!feof(stdin)) {
            char modpath[MAXIMUM_PATH];
            if (fgets(line, sizeof(line), stdin) == NULL ||
                /* when postprocess.pl closes the pipe, fgets is not
                 * returning, so using an alternative eof code
                 */
                strcmp(line, ";exit\n") == 0)
                break;
            /* Ensure we support spaces in paths by using ; to split.
             * Since ; separates PATH, no Windows dll will have ; in its name.
             */
            if (sscanf(line, "%"MAX_PATH_STR"[^;];"SIZE_FMT, (char *)&modpath,
                       &modoffs) == 2) {
                symquery_lookup_address(modpath, modoffs);
                fflush(stdout); /* ensure flush in case piped */
            } else if (verbose)
                printf("Error: unknown input %s\n", line);
        }
    }

    if (drsym_exit() != DRSYM_SUCCESS)
        printf("WARNING: error cleaning up symbol library\n");
    res = 0;

 cleanup:
    if (drfront_cleanup_args(argv, argc) != DRFRONT_SUCCESS)
        printf("WARNING: drfront_cleanup_args failed\n");
    return res;
}