Example #1
0
void
symcache_init(const char *symcache_dir_in,
              size_t modsize_cache_threshold)
{
    initialized = true;

    op_modsize_cache_threshold = modsize_cache_threshold;

    hashtable_init_ex(&symcache_table, SYMCACHE_MASTER_TABLE_HASH_BITS,
                      IF_WINDOWS_ELSE(HASH_STRING_NOCASE, HASH_STRING),
                      true/*strdup*/, false/*!synch*/,
                      symcache_free_entry, NULL, NULL);
    symcache_lock = dr_mutex_create();

    dr_snprintf(symcache_dir, BUFFER_SIZE_ELEMENTS(symcache_dir), 
                "%s", symcache_dir_in);
    NULL_TERMINATE_BUFFER(symcache_dir);
    if (!dr_directory_exists(symcache_dir)) {
        if (!dr_create_dir(symcache_dir)) {
            /* check again in case of a race (i#616) */
            if (!dr_directory_exists(symcache_dir)) {
                NOTIFY_ERROR("Unable to create symcache dir %s"NL, symcache_dir);
                ASSERT(false, "unable to create symcache dir");
                dr_abort();
            }
        }
    }
}
Example #2
0
ring(int x)
#endif
{
    print("looking at ring\n");
    *(ptr_int_t*) (((ptr_int_t*)&x) - IF_X64_ELSE(IF_WINDOWS_ELSE(5, 1), 1))
        = (ptr_int_t)&precious;
    return (ptr_int_t) x;
}
Example #3
0
void
test_alloca(void)
{
    /* test special shadow write from gencode */
    int *x = (int *) IF_WINDOWS_ELSE(_alloca,alloca)(128*1024);
    x[0] = 4;

    /* test special shadow write from code cache code */
    x = malloc(128*1024);
    x[64*1024/sizeof(int)] = 1;
    free(x);
}
Example #4
0
static void
wrap_pre(void *wrapcxt, OUT void **user_data)
{
    /* malloc(size) or HeapAlloc(heap, flags, size) */
    size_t sz = (size_t) drwrap_get_arg(wrapcxt, IF_WINDOWS_ELSE(2,0));
    /* find the maximum malloc request */
    if (sz > max_malloc) {
        dr_mutex_lock(max_lock);
        if (sz > max_malloc)
            max_malloc = sz;
        dr_mutex_unlock(max_lock);
    }
    *user_data = (void *) sz;
}
Example #5
0
static
void module_load_event(void *drcontext, const module_data_t *mod, bool loaded)
{
    app_pc towrap = (app_pc)
        dr_get_proc_address(mod->start, IF_WINDOWS_ELSE("HeapAlloc", "malloc"));
    if (towrap != NULL) {
#ifdef SHOW_RESULTS
        bool ok =
#endif
            drwrap_wrap(towrap, wrap_pre, wrap_post);
#ifdef SHOW_RESULTS
        if (ok)
            dr_fprintf(STDERR, "<wrapped HeapAlloc @"PFX"\n", towrap);
        else {
            /* We expect this w/ forwarded exports (e.g., on win7 both
             * kernel32!HeapAlloc and kernelbase!HeapAlloc forward to
             * the same routine in ntdll.dll)
             */
            dr_fprintf(STDERR, "<FAILED to wrap HeapAlloc @"PFX": already wrapped?\n",
                       towrap);
        }
#endif
    }
}
Example #6
0
int
main(int argc, char *argv[])
{
    char *dll = NULL;
    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;

    for (i = 1; i < argc; i++) {
        if (_stricmp(argv[i], "-e") == 0) {
            if (i+1 >= argc) {
                PRINT_USAGE(argv[0]);
                return 1;
            }
            i++;
            dll = argv[i];
            if (
#ifdef WINDOWS
                _access(dll, 4/*read*/) == -1
#else
                !dr_file_exists(dll)
#endif
                ) {
                printf("ERROR: invalid path %s\n", dll);
                return 1;
            }
        } 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]);
                return 1;
            }
            if (_stricmp(argv[i], "-a") == 0)
                addr2sym = true;
            else
                sym2addr = true;
            i++;
            /* rest of args read below */
            break;
        } 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]);
            return 1;
        }
    }
    if (((sym2addr || addr2sym) && dll == NULL) ||
        (addr2sym_multi && dll != NULL) ||
        (!sym2addr && !addr2sym && !addr2sym_multi && !enumerate_all)) {
        PRINT_USAGE(argv[0]);
        return 1;
    }

    dr_standalone_init();

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

    if (!addr2sym_multi) {
        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], "%x", (uint *)&modoffs) == 1)
                        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
                    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"[^;];%x", (char *)&modpath,
                       (uint *)&modoffs) == 2) {
                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");

    return 0;
}
Example #7
0
 "for slightly different cpu models that have insignificant cpuid feature differences "
 "as identical: for example, a request for Northwood will result in a Banias model.");

droption_t<bool> op_continue
(DROPTION_SCOPE_CLIENT, "continue", false, "Continue (don't abort) on bad instr.",
 "By default, drcpusim aborts when it encounters an invalid instruction.  This option "
 "requests that the tool continue, simply printing each invalid instruction it "
 "encounters.  It may print the same instruction twice, depending on whether the "
 "underlying tool engine needs to re-translate that code again.");

droption_t<bool> op_fool_cpuid
(DROPTION_SCOPE_CLIENT, "fool_cpuid", true, "Fake CPUID to match CPU model.",
 "When the application executes the CPUID instruction, when this option is enabled, "
 "drcpusim will supply CPUID results that match the CPU model being simulated.");

droption_t<bool> op_allow_prefetchw
(DROPTION_SCOPE_CLIENT, "allow_prefetchw", true, "Consider PREFETCHW to be harmless.",
 "The PREFETCHW instruction is only fully supported by AMD processors, yet most Intel "
 "processors, while they do not officially support it, will turn it into a NOP. "
 "As it is commonly seen on Windows, by default drcpusim does not complain about it.");

droption_t<std::string> op_blacklist
(DROPTION_SCOPE_CLIENT, "blacklist", IF_WINDOWS_ELSE("ntdll.dll",""),
 ":-separated list of libs to ignore.",
 "The blacklist is a :-separated list of library names for which violations "
 "should not be reported.");

droption_t<unsigned int> op_verbose
(DROPTION_SCOPE_CLIENT, "verbose", 0, 0, 64, "Verbosity level",
 "Verbosity level for notifications.");
Example #8
0
DR_EXPORT
drmf_status_t
drsymcache_init(client_id_t client_id,
                const char *symcache_dir_in,
                size_t modsize_cache_threshold)
{
#ifdef WINDOWS
    module_data_t *mod;
#endif
    drmf_status_t res;
    drmgr_priority_t pri_mod_load_cache =
        {sizeof(pri_mod_load_cache), DRMGR_PRIORITY_NAME_DRSYMCACHE, NULL, NULL,
         DRMGR_PRIORITY_MODLOAD_DRSYMCACHE_READ};
    drmgr_priority_t pri_mod_unload_cache =
        {sizeof(pri_mod_unload_cache), DRMGR_PRIORITY_NAME_DRSYMCACHE, NULL, NULL,
         DRMGR_PRIORITY_MODUNLOAD_DRSYMCACHE};
    drmgr_priority_t pri_mod_save_cache =
        {sizeof(pri_mod_save_cache), DRMGR_PRIORITY_NAME_DRSYMCACHE_SAVE, NULL, NULL,
         DRMGR_PRIORITY_MODLOAD_DRSYMCACHE_SAVE};

    /* handle multiple sets of init/exit calls */
    int count = dr_atomic_add32_return_sum(&symcache_init_count, 1);
    if (count > 1)
        return DRMF_WARNING_ALREADY_INITIALIZED;

    res = drmf_check_version(client_id);
    if (res != DRMF_SUCCESS)
        return res;

    drmgr_init();
    drmgr_register_module_load_event_ex(symcache_module_load, &pri_mod_load_cache);
    drmgr_register_module_unload_event_ex(symcache_module_unload, &pri_mod_unload_cache);
    drmgr_register_module_load_event_ex(symcache_module_load_save, &pri_mod_save_cache);

    initialized = true;

    op_modsize_cache_threshold = modsize_cache_threshold;

    hashtable_init_ex(&symcache_table, SYMCACHE_MASTER_TABLE_HASH_BITS,
                      IF_WINDOWS_ELSE(HASH_STRING_NOCASE, HASH_STRING),
                      true/*strdup*/, false/*!synch*/,
                      symcache_free_entry, NULL, NULL);
    symcache_lock = dr_mutex_create();

    dr_snprintf(symcache_dir, BUFFER_SIZE_ELEMENTS(symcache_dir),
                "%s", symcache_dir_in);
    NULL_TERMINATE_BUFFER(symcache_dir);
    if (!dr_directory_exists(symcache_dir)) {
        if (!dr_create_dir(symcache_dir)) {
            /* check again in case of a race (i#616) */
            if (!dr_directory_exists(symcache_dir)) {
                NOTIFY_ERROR("Unable to create symcache dir %s"NL, symcache_dir);
                ASSERT(false, "unable to create symcache dir");
                dr_abort();
            }
        }
    }

#ifdef WINDOWS
    /* It's common for tools to query ntdll in their init routines so we add it
     * early here
     */
    mod = dr_lookup_module_by_name("ntdll.dll");
    if (mod != NULL) {
        symcache_module_load(dr_get_current_drcontext(), mod, true);
        dr_free_module_data(mod);
    }
#endif

    return DRMF_SUCCESS;
}
Example #9
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;
}