Esempio n. 1
0
int
main(int argc, char *argv[])
{
    void *dcontext = dr_standalone_init();

    test_all_opcodes(dcontext);

#ifdef X64
    /* FIXME: NYI */
#else
    test_disp_control(dcontext);

    test_indirect_cti(dcontext);

    test_cti_prefixes(dcontext);

    test_modrm16(dcontext);

    test_size_changes(dcontext);
#endif

    test_nop_xchg(dcontext);

    print("all done\n");
    return 0;
}
Esempio n. 2
0
int
main(int argc, char *argv[])
{
#ifdef STANDALONE_DECODER
    void *dcontext = GLOBAL_DCONTEXT;
#else
    void *dcontext = dr_standalone_init();

    /* simple test of deadlock_avoidance, etc. being disabled in standalone */
    void *x = dr_mutex_create();
    dr_mutex_lock(x);
    dr_mutex_unlock(x);
    dr_mutex_destroy(x);
#endif

    test_all_opcodes_0(dcontext);
#ifndef STANDALONE_DECODER /* speed up compilation */
    test_all_opcodes_1(dcontext);
    test_all_opcodes_2(dcontext);
    test_all_opcodes_2_mm(dcontext);
    test_all_opcodes_3(dcontext);
    test_all_opcodes_3_avx(dcontext);
    test_all_opcodes_4(dcontext);
#endif

    test_disp_control(dcontext);

    test_indirect_cti(dcontext);

    test_cti_prefixes(dcontext);

#ifndef X64
    test_modrm16(dcontext);
#endif

    test_size_changes(dcontext);

    test_nop_xchg(dcontext);

#ifdef X64
    test_x86_mode(dcontext);

    test_x64_abs_addr(dcontext);

    test_x64_inc(dcontext);
#endif

    test_regs(dcontext);

    test_instr_opnds(dcontext);

    test_strict_invalid(dcontext);

    print("all done\n");
    return 0;
}
Esempio n. 3
0
int
main(int argc, char *argv[])
{
    void *dcontext = dr_standalone_init();

    /* i#1702: test that a cbr is outside the IT-block */
    test_dr_insert_it_instrs_cbr(dcontext);

    /* i#1702: test that a cti terminates the IT-block */
    test_dr_insert_it_instrs_cti(dcontext);

    return 0;
}
Esempio n. 4
0
int
main(int argc, char *argv[])
{
    file_t f;
    void *drcontext = dr_standalone_init();
    if (argc != 2) {
        dr_fprintf(STDERR, "Usage: %s <objfile>\n", argv[0]);
        return 1;
    }
    f = dr_open_file(argv[1], DR_FILE_READ | DR_FILE_ALLOW_LARGE);
    if (f == INVALID_FILE) {
        dr_fprintf(STDERR, "Error opening %s\n", argv[1]);
        return 1;
    }
    read_data(f, drcontext);
    dr_close_file(f);
    return 0;
}
Esempio n. 5
0
int
main(int argc, char *argv[])
{
    version_info_t info;
    HMODULE hmod;
    
    void *drcontext = dr_standalone_init();
    if (argc != 2) {
        printf("Usage: %s <dll to read>\n", argv[0]);
        return 1;
    }

    /* Don't use LOAD_LIBRARY_AS_DATAFILE, it doesn't layout the sections as we expect
     * use DONT_RESOLVE_DLL_REFERENCES instead */
    hmod = LoadLibraryEx(argv[1], NULL, DONT_RESOLVE_DLL_REFERENCES);
    if (hmod == NULL) {
        printf("Can't find module %s\n", argv[1]);
        return 2;
    }
    
    /* Need to round off the loaded as data flag to get actual base */
    if (!get_module_resource_version_info((app_pc)((uint)hmod & 0xfffffffe), &info)) {
        printf("Failed to read rsrc directory\n");
        return 3;
    }

    printf("File Version = %04d.%04d.%04d.%04d, Product Version = %04d.%04d.%04d.%04d\n",
           info.file_version.version_parts.p1, info.file_version.version_parts.p2,
           info.file_version.version_parts.p3, info.file_version.version_parts.p4,
           info.product_version.version_parts.p1, info.product_version.version_parts.p2,
           info.product_version.version_parts.p3, info.product_version.version_parts.p4);
    if (info.original_filename != NULL)
        printf("Original File Name = \"%S\"\n", info.original_filename);
    if (info.company_name != NULL)
        printf("Company Name = \"%S\"\n", info.company_name);
    if (info.product_name != NULL)
        printf("Product Name = \"%S\"\n", info.product_name);

    return 0;
}
Esempio n. 6
0
bool
drstrace_unit_test_syscall_init()
{
    uint const_arrays_num;
    uint i = 0;

    dr_standalone_init();

    if (drsym_init(0) != DRSYM_SUCCESS)
        return false;

    const_arrays_num = get_const_arrays_num();
    hashtable_init(&nconsts_table, HASHTABLE_BITSIZE, HASH_STRING, false);
    while (i < const_arrays_num) {
        const_values_t *named_consts = const_struct_array[i];
        bool res = hashtable_add(&nconsts_table,
                                 (void *) named_consts[0].const_name,
                                 (void *) named_consts);
        if (!res)
            return false;
        i++;
    }
    return true;
}
Esempio n. 7
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;
}
Esempio n. 8
0
int
_tmain(int argc, TCHAR *targv[])
{
    char **argv;
    char *process = NULL;
    char *dr_root = NULL;
    char *drheapstat_root = NULL;
    char default_dr_root[MAXIMUM_PATH];
    char default_drheapstat_root[MAXIMUM_PATH];
    char client_path[MAXIMUM_PATH];

    char client_ops[MAX_DR_CMDLINE];
    size_t cliops_sofar = 0; /* for BUFPRINT to client_ops */
    char dr_ops[MAX_DR_CMDLINE];
    size_t drops_sofar = 0; /* for BUFPRINT to dr_ops */
    ssize_t len; /* shared by all BUFPRINT */

    char logdir[MAXIMUM_PATH];
    bool have_logdir = false;
    bool use_root_for_logdir;

#ifdef WINDOWS
    char *pidfile = NULL;
#endif
#ifndef MACOS /* XXX i#1286: implement nudge on MacOS */
    process_id_t nudge_pid = 0;
#endif
    bool use_dr_debug = false;
    bool use_drheapstat_debug = false;

    char *app_name;
    char full_app_name[MAXIMUM_PATH];
    char **app_argv;

    int errcode;
    void *inject_data;
    int i;
    char *c;
    char buf[MAXIMUM_PATH];
    process_id_t pid;
    bool exit0 = false;
    bool dr_logdir_specified = false;
    bool doubledash_present = false;

    drfront_status_t sc;
    bool res;
#ifndef X64
    bool is64, is32;
#endif

    dr_standalone_init();

#if defined(WINDOWS) && !defined(_UNICODE)
# error _UNICODE must be defined
#else
    /* Convert to UTF-8 if necessary */
    sc = drfront_convert_args((const TCHAR **)targv, &argv, argc);
    if (sc != DRFRONT_SUCCESS)
        fatal("failed to process args: %d\n", sc);
#endif
    /* Default root: we assume this exe is <root>/bin/drheapstat.exe */
    get_full_path(argv[0], buf, BUFFER_SIZE_ELEMENTS(buf));
    c = buf + strlen(buf) - 1;
    while (*c != DIRSEP && *c != ALT_DIRSEP && c > buf)
        c--;
    _snprintf(c+1, BUFFER_SIZE_ELEMENTS(buf) - (c+1-buf), "../dynamorio");
    NULL_TERMINATE_BUFFER(buf);
    get_absolute_path(buf, default_dr_root, BUFFER_SIZE_ELEMENTS(default_dr_root));
    NULL_TERMINATE_BUFFER(default_dr_root);
    dr_root = default_dr_root;

    /* assuming we're in bin/ (mainly due to CPack NSIS limitations) */
    _snprintf(c+1, BUFFER_SIZE_ELEMENTS(buf) - (c+1-buf), "..");
    NULL_TERMINATE_BUFFER(buf);
    get_absolute_path(buf, default_drheapstat_root,
                      BUFFER_SIZE_ELEMENTS(default_drheapstat_root));
    NULL_TERMINATE_BUFFER(default_drheapstat_root);
    drheapstat_root = default_drheapstat_root;
    string_replace_character(drheapstat_root, ALT_DIRSEP, DIRSEP); /* canonicalize */

    BUFPRINT(dr_ops, BUFFER_SIZE_ELEMENTS(dr_ops),
             drops_sofar, len, "%s ", DEFAULT_DR_OPS);

    client_ops[0] = '\0';

    /* default logdir */
    if (drfront_appdata_logdir(drheapstat_root, "Dr. Heapstat", &use_root_for_logdir,
                               logdir, BUFFER_SIZE_ELEMENTS(logdir)) == DRFRONT_SUCCESS
        && !use_root_for_logdir) {
        if ((dr_create_dir(logdir) || dr_directory_exists(logdir)) &&
            file_is_writable(logdir))
            have_logdir = true;
    }
    if (!have_logdir) {
        _snprintf(logdir, BUFFER_SIZE_ELEMENTS(logdir), "%s%cdrheapstat%clogs",
                  drheapstat_root, DIRSEP, DIRSEP);
        NULL_TERMINATE_BUFFER(logdir);
        if (!file_is_writable(logdir)) {
            _snprintf(logdir, BUFFER_SIZE_ELEMENTS(logdir), "%s%clogs",
                      drheapstat_root, DIRSEP);
            NULL_TERMINATE_BUFFER(logdir);
            if (file_is_writable(logdir))
                have_logdir = true;
        } else
            have_logdir = true;
    } else
        have_logdir = true;
    if (!have_logdir) {
        /* try logs in cur dir */
        get_absolute_path("./logs", logdir, BUFFER_SIZE_ELEMENTS(logdir));
        NULL_TERMINATE_BUFFER(logdir);
        if (!file_is_writable(logdir)) {
            /* try cur dir */
            get_absolute_path(".", logdir, BUFFER_SIZE_ELEMENTS(logdir));
            NULL_TERMINATE_BUFFER(logdir);
        }
    }

    /* parse command line */
    /* FIXME PR 487993: use optionsx.h to construct this parsing code */
    for (i=1; i<argc; i++) {
        if (strcmp(argv[i], "--") == 0) {
            doubledash_present = true;
            break;
        }
    }
    for (i=1; i<argc; i++) {
        /* note that we pass unknown args to client, until -- */
        if (strcmp(argv[i], "--") == 0) {
            i++;
            break;
        }
        /* drag-and-drop does not include "--" so we try to identify the app.
         * we explicitly parse -logdir and -suppress, and all the other
         * client ops that take args take numbers so this should be safe.
         */
        else if (argv[i][0] != '-' && !doubledash_present && ends_in_exe(argv[i])) {
            /* leave i alone: this is the app itself */
            break;
        }
        else if (strcmp(argv[i], "-v") == 0) {
            verbose = true;
            continue;
        }
        else if (strcmp(argv[i], "-h") == 0 ||
                 strcmp(argv[i], "--help") == 0) {
            print_usage(true/*full*/);
            exit(0);
        }
        else if (strcmp(argv[i], "-dr_debug") == 0) {
            use_dr_debug = true;
            continue;
        }
        else if (strcmp(argv[i], "-dr_release") == 0) {
            use_dr_debug = false;
            continue;
        }
        else if (strcmp(argv[i], "-debug") == 0) {
            use_drheapstat_debug = true;
            continue;
        }
        else if (strcmp(argv[i], "-release") == 0) {
            use_drheapstat_debug = false;
            continue;
        }
        else if (!strcmp(argv[i], "-version")) {
#if defined(BUILD_NUMBER) && defined(VERSION_NUMBER)
          printf("Dr. Heapstat version %s -- build %d\n", VERSION_STRING, BUILD_NUMBER);
#elif defined(BUILD_NUMBER)
          printf("Dr. Heapstat custom build %d -- %s\n", BUILD_NUMBER, __DATE__);
#elif defined(VERSION_NUMBER)
          printf("Dr. Heapstat version %s -- custom build %s, %s\n",
                 VERSION_STRING, __DATE__, __TIME__);
#else
          printf("Dr. Heapstat custom build -- %s, %s\n", __DATE__, __TIME__);
#endif
          exit(0);
        }
        else if (strcmp(argv[i], "-dr") == 0) {
            if (i >= argc - 1)
                usage("invalid arguments");
            dr_root = argv[++i];
        }
        else if (strcmp(argv[i], "-drheapstat") == 0) {
            if (i >= argc - 1)
                usage("invalid arguments");
            drheapstat_root = argv[++i];
        }
        else if (strcmp(argv[i], "-follow_children") == 0 ||
                 strcmp(argv[i], "-no_follow_children") == 0) {
            BUFPRINT(dr_ops, BUFFER_SIZE_ELEMENTS(dr_ops),
                     drops_sofar, len, "%s ", argv[i]);
        }
#ifndef MACOS /* XXX i#1286: implement nudge on MacOS */
        else if (strcmp(argv[i], "-nudge") == 0) {
            if (i >= argc - 1)
                usage("invalid arguments");
            nudge_pid = strtoul(argv[++i], NULL, 10);
        }
#endif
        else if (strcmp(argv[i], "-dr_ops") == 0) {
            if (i >= argc - 1)
                usage("invalid arguments");
            /* Slight risk of some other option containing "-logdir " but
             * -dr_ops is really only be used by Dr. Memory developers anyway.
             */
            if (strstr(argv[i+1], "-logdir ") != NULL)
                dr_logdir_specified = true;
            BUFPRINT(dr_ops, BUFFER_SIZE_ELEMENTS(dr_ops),
                     drops_sofar, len, "%s ", argv[++i]);
        }
#ifdef WINDOWS
        else if (strcmp(argv[i], "-pid_file") == 0) {
            if (i >= argc - 1)
                usage("invalid arguments");
            pidfile = argv[++i];
        }
#endif
        else if (strcmp(argv[i], "-logdir") == 0) {
            if (i >= argc - 1)
                usage("invalid arguments");
            /* make absolute */
            get_absolute_path(argv[++i], logdir, BUFFER_SIZE_ELEMENTS(logdir));
            NULL_TERMINATE_BUFFER(logdir);
            /* added to client ops below */
        }
        else if (strcmp(argv[i], "-exit0") == 0) {
            exit0 = true;
        } /* FIXME i#1653: add support for options the old perl frontend supported */
        else {
            /* pass to client */
            BUFPRINT(client_ops, BUFFER_SIZE_ELEMENTS(client_ops),
                     cliops_sofar, len, "`%s` ", argv[i]);
        }
    }

#ifndef MACOS /* XXX i#1286: implement nudge on MacOS */
    if (nudge_pid != 0) {
        if (i < argc)
            usage("%s", "-nudge does not take an app to run");
        /* could also complain about other client or app specific ops */
        res = dr_nudge_pid(nudge_pid, CLIENT_ID, NUDGE_LEAK_SCAN, INFINITE);
        if (res != DR_SUCCESS) {
            fatal("error nudging %d%s", nudge_pid,
                  (res == DR_NUDGE_PID_NOT_INJECTED) ? ": no such Dr. Heapstat process"
                  : "");
            assert(false); /* shouldn't get here */
        }
        exit(0);
    }
#endif

    if (i >= argc)
        usage("%s", "no app specified");
    app_name = argv[i];
    get_full_path(app_name, full_app_name, BUFFER_SIZE_ELEMENTS(full_app_name));
    if (full_app_name[0] != '\0')
        app_name = full_app_name;
    info("targeting application: \"%s\"", app_name);

    /* XXX: See drmemory/frontend.c for notes about our argv processing. */
    app_argv = &argv[i];
    if (verbose) {
        int j;
        c = buf;
        for (j = 0; app_argv[j] != NULL; j++) {
            c += _snprintf(c, BUFFER_SIZE_ELEMENTS(buf) - (c - buf),
                           "\"%s\" ", app_argv[j]);
        }
        NULL_TERMINATE_BUFFER(buf);
        assert(c - buf < BUFFER_SIZE_ELEMENTS(buf));
        info("app cmdline: %s", buf);
    }

#ifndef X64
    /* XXX: See drmemory/frontend.c for notes about 64-bit support. */
    if (drfront_is_64bit_app(app_name, &is64, &is32) == DRFRONT_SUCCESS &&
        is64 && !is32) {
        fatal("This Dr. Heapstat release does not support 64-bit applications.");
        goto error; /* actually won't get here */
    }
#endif

    if (!file_is_readable(dr_root)) {
        fatal("invalid -dr %s", dr_root);
        goto error; /* actually won't get here */
    }
    if (dr_root != default_dr_root) {
        /* Workaround for DRi#1082 where DR root path can't have ".." */
        get_absolute_path(dr_root, default_dr_root,
                          BUFFER_SIZE_ELEMENTS(default_dr_root));
        NULL_TERMINATE_BUFFER(default_dr_root);
        dr_root = default_dr_root;
    }
    _snprintf(buf, BUFFER_SIZE_ELEMENTS(buf),
              "%s/"LIB_ARCH"/%s/%s", dr_root,
              use_dr_debug ? "debug" : "release", DR_LIB_NAME);
    NULL_TERMINATE_BUFFER(buf);
    if (!file_is_readable(buf)) {
        /* support debug build w/ integrated debug DR build and so no release */
        if (!use_dr_debug) {
            _snprintf(buf, BUFFER_SIZE_ELEMENTS(buf),
                      "%s/"LIB_ARCH"/%s/%s", dr_root, "debug", DR_LIB_NAME);
            NULL_TERMINATE_BUFFER(buf);
            if (!file_is_readable(buf)) {
                fatal("cannot find DynamoRIO library %s", buf);
                goto error; /* actually won't get here */
            }
            warn("using debug DynamoRIO since release not found");
            use_dr_debug = true;
        }
    }

    /* once we have 64-bit we'll need to address the NSIS "bin/" requirement */
    _snprintf(client_path, BUFFER_SIZE_ELEMENTS(client_path),
              "%s%c"BIN_ARCH"%c%s%c%s", drheapstat_root, DIRSEP, DIRSEP,
              use_drheapstat_debug ? "debug" : "release", DIRSEP, DRHEAPSTAT_LIB_NAME);
    NULL_TERMINATE_BUFFER(client_path);
    if (!file_is_readable(client_path)) {
        if (!use_drheapstat_debug) {
            _snprintf(client_path, BUFFER_SIZE_ELEMENTS(client_path),
                      "%s%c"BIN_ARCH"%c%s%c%s", drheapstat_root,
                      DIRSEP, DIRSEP, "debug", DIRSEP, DRHEAPSTAT_LIB_NAME);
            NULL_TERMINATE_BUFFER(client_path);
            if (!file_is_readable(client_path)) {
                fatal("invalid -drheapstat_root: cannot find %s", client_path);
                goto error; /* actually won't get here */
            }
            /* try to avoid warning for devs running from build dir */
            _snprintf(buf, BUFFER_SIZE_ELEMENTS(client_path),
                      "%s%cCMakeCache.txt", drheapstat_root, DIRSEP);
            NULL_TERMINATE_BUFFER(buf);
            if (!file_is_readable(buf))
                warn("using debug Dr. Heapstat since release not found");
            use_drheapstat_debug = true;
        }
    }

    drfront_string_replace_character(logdir, ALT_DIRSEP, DIRSEP); /* canonicalize */
    if (!file_is_writable(logdir)) {
        fatal("invalid -logdir: cannot find/write %s", logdir);
        goto error; /* actually won't get here */
    }
    info("logdir is \"%s\"", logdir);
    BUFPRINT(client_ops, BUFFER_SIZE_ELEMENTS(client_ops),
             cliops_sofar, len, "-logdir `%s` ", logdir);

    /* Put DR logs inside drheapstat logdir */
    if (!dr_logdir_specified) {
        _snprintf(buf, BUFFER_SIZE_ELEMENTS(buf), "%s%cdynamorio", logdir, DIRSEP);
        NULL_TERMINATE_BUFFER(buf);
        if (!dr_directory_exists(buf)) {
            if (!dr_create_dir(buf)) {
                /* check again in case of a race */
                if (!dr_directory_exists(buf)) {
                    fatal("cannot create %s", buf);
                    goto error; /* actually won't get here */
                }
            }
        }
        BUFPRINT(dr_ops, BUFFER_SIZE_ELEMENTS(dr_ops),
                 drops_sofar, len, "-logdir `%s` ", buf);
    }

#ifdef UNIX
    errcode = dr_inject_prepare_to_exec(app_name, (const char **)app_argv, &inject_data);
#else
    errcode = dr_inject_process_create(app_name, (const char **)app_argv, &inject_data);
#endif
    /* Mismatch is just a warning */
    if (errcode != 0 && errcode != WARN_IMAGE_MACHINE_TYPE_MISMATCH_EXE) {
#ifdef WINDOWS
        int sofar =
#endif
            _snprintf(buf, BUFFER_SIZE_ELEMENTS(buf),
                      "failed to create process for \"%s\": ", app_name);
#ifdef WINDOWS
        if (sofar > 0) {
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                          NULL, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                          (LPTSTR) buf + sofar,
                          BUFFER_SIZE_ELEMENTS(buf) - sofar*sizeof(char), NULL);
        }
        NULL_TERMINATE_BUFFER(buf);
#endif
        fatal("%s", buf);
        goto error; /* actually won't get here */
    }

    pid = dr_inject_get_process_id(inject_data);
#ifdef WINDOWS
    if (pidfile != NULL)
        write_pid_to_file(pidfile, pid);
#endif

    process = dr_inject_get_image_name(inject_data);
    /* we don't care if this app is already registered for DR b/c our
     * this-pid config will override
     */
    info("configuring %s pid=%d dr_ops=\"%s\"", process, pid, dr_ops);
    if (dr_register_process(process, pid,
                            false/*local*/, dr_root,  DR_MODE_CODE_MANIPULATION,
                            use_dr_debug, DR_PLATFORM_DEFAULT, dr_ops) != DR_SUCCESS) {
        fatal("failed to register DynamoRIO configuration");
        goto error; /* actually won't get here */
    }
    info("configuring client \"%s\" ops=\"%s\"", client_path, client_ops);
    if (dr_register_client(process, pid,
                           false/*local*/, DR_PLATFORM_DEFAULT, CLIENT_ID,
                           0, client_path, client_ops) != DR_SUCCESS) {
        fatal("failed to register DynamoRIO client configuration");
        goto error; /* actually won't get here */
    }
    if (!dr_inject_process_inject(inject_data, false/*!force*/, NULL)) {
        fatal("unable to inject");
        goto error; /* actually won't get here */
    }
    dr_inject_process_run(inject_data);
#ifdef UNIX
    fatal("Failed to exec application");
#else
    info("waiting for app to exit...");
    errcode = WaitForSingleObject(dr_inject_get_process_handle(inject_data), INFINITE);
    if (errcode != WAIT_OBJECT_0)
        info("failed to wait for app: %d\n", errcode);
#endif
    errcode = dr_inject_process_exit(inject_data, false/*don't kill process*/);
    goto cleanup;
 error:
    dr_inject_process_exit(inject_data, false);
    errcode = 1;
 cleanup:
    sc = drfront_cleanup_args(argv, argc);
    if (sc != DRFRONT_SUCCESS)
        fatal("drfront_cleanup_args failed: %d\n", sc);
    return (exit0 ? 0 : errcode);
}
Esempio n. 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;
}
Esempio n. 10
0
int
main(int argc, char *argv[])
{
    void *dcontext = dr_standalone_init();
    int res;
    char *dll;
    bool forced = false;

    dr_set_isa_mode(dcontext, DR_ISA_IA32, NULL);

    for (res=1; res < argc; res++) {
        if (strcmp(argv[res], "-sysenter") == 0) {
            expect_sysenter = true;
            forced = true;
        } else if (strcmp(argv[res], "-int2e") == 0) {
            expect_int2e = true;
            forced = true;
        } else if (strcmp(argv[res], "-wow") == 0) {
            expect_wow = true;
            forced = true;
        } else if (strcmp(argv[res], "-x64") == 0) {
            expect_x64 = true;
#ifdef X64
            dr_set_isa_mode(dcontext, DR_ISA_AMD64, NULL);
#else
            /* For 32-bit builds we hack a fix for -syscalls (see
             * decode_syscall_num()) but -Ki won't work.
             */
#endif
            forced = true;
        } else if (strcmp(argv[res], "-v") == 0) {
            verbose = true;
        } else if (strcmp(argv[res], "-exports") == 0) {
            list_exports = true;
            list_forwards = true; /* implied */
        } else if (strcmp(argv[res], "-forwards") == 0) {
            list_forwards = true;
        } else if (strcmp(argv[res], "-Ki") == 0) {
            list_Ki = true;
        } else if (strcmp(argv[res], "-syscalls") == 0) {
            list_syscalls = true;
        } else if (strcmp(argv[res], "-ignore_Zw") == 0) {
            ignore_Zw = true;
        } else if (strcmp(argv[res], "-usercalls") == 0) {
            list_usercalls = true;
        } else if (argv[res][0] == '-') {
            usage(argv[0]);
        } else {
            break;
        }
    }
    if (res >= argc ||
        (!list_syscalls && !list_Ki && !list_forwards && !verbose && !list_usercalls)) {
        usage(argv[0]);
    }
    dll = argv[res];

    if (!forced && list_syscalls) {
        usage(argv[0]);
    }

    load_and_analyze(dcontext, dll);
    return 0;
}
Esempio n. 11
0
int
main(int argc, char *argv[])
{
    byte *dll_1, *dll_2, *p1, *p2, *iat_start1, *iat_end1, *iat_start2, *iat_end2;
    bool has_iat = false;
    MEMORY_BASIC_INFORMATION info;
    void *drcontext = dr_standalone_init();
    uint writable_pages = 0, reserved_pages = 0, IAT_pages = 0;
    uint matched_pages = 0, second_matched_pages = 0, unmatched_pages = 0;
    uint exact_match_pages = 0, exact_no_match_pages = 0;
    char reloc_file[MAX_PATH] = {0}, orig_file[MAX_PATH], *input_file;
    uint old_size = 0, new_size = 0;
    uint old_base = 0, new_base = 0x69000000; /* unlikely to collide */

    /* user specified option defaults */
    uint arg_offs = 1;
    bool use_second_pass = true;
    bool assume_header_match = true;
    uint second_pass_offset = 16; /* FIXME arbitrary, what's a good choice? */
    bool assume_IAT_written = true;
    bool spin_for_debugger = false;

    if (argc < 2)
        return usage(argv[0]);
    while (argv[arg_offs][0] == '-') {
        if (strcmp(argv[arg_offs], "-vv") == 0) {
            vv = true;
        } else if (strcmp(argv[arg_offs], "-v") == 0) {
            v = true;
        } else if (strcmp(argv[arg_offs], "-no_second_pass") == 0) {
            use_second_pass = false;
        } else if (strcmp(argv[arg_offs], "-second_pass_offset") == 0) {
            if ((uint)argc <= arg_offs+1)
                return usage(argv[0]);
            second_pass_offset = atoi(argv[++arg_offs]);
        } else if (strcmp(argv[arg_offs], "-no_assume_IAT_written") == 0) {
            assume_IAT_written = false;
        } else if (strcmp(argv[arg_offs], "-spin_for_debugger") == 0) {
            spin_for_debugger = true;
        } else {
            return usage(argv[0]);
        }
        arg_offs++;
    }   
    input_file = argv[arg_offs++];
    if (arg_offs != argc)
        return usage(argv[0]);
    
    _snprintf(reloc_file, sizeof(reloc_file), "%s.reloc.dll", input_file);
    reloc_file[sizeof(reloc_file)-1] = '\0';
    if (!CopyFile(input_file, reloc_file, FALSE)) {
        LPSTR msg = NULL;
        uint error = GetLastError();
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,
                      0, GetLastError(), 0, msg, 0, NULL);
        VERBOSE_PRINT("Copy Error %d (0x%x) = %s\n", error, error, msg);
        return 1;
    }
    snprintf(orig_file, sizeof(orig_file), "%s.orig.dll", input_file);
    orig_file[sizeof(orig_file)-1] = '\0';
    if (!CopyFile(input_file, orig_file, FALSE)) {
        LPSTR msg = NULL;
        uint error = GetLastError();
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,
                      0, GetLastError(), 0, msg, 0, NULL);
        VERBOSE_PRINT("Copy Error %d (0x%x) = %s\n", error, error, msg);
        return 1;
    }
    if (ReBaseImage(reloc_file, "", TRUE, FALSE, FALSE, 0, &old_size, &old_base,
                    &new_size, &new_base, 0)) {
        VERBOSE_PRINT("Rebased imsage \"%s\" from 0x%08x to 0x%08x\n"
                      "Size changed from %d bytes to %d bytes\n",
                      input_file, old_base, new_base, old_size, new_size);
    } else {
        LPSTR msg = NULL;
        uint error = GetLastError();
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,
                      0, GetLastError(), 0, msg, 0, NULL);
        VERBOSE_PRINT("Rebase Error %d (0x%x) = %s\n", error, error, msg);
        return 1;
    }
    
    dll_1 = (byte *)ALIGN_BACKWARD(LoadLibraryExA(orig_file, NULL,
                                                  DONT_RESOLVE_DLL_REFERENCES),
                                   PAGE_SIZE);
    p1 = dll_1;
    dll_2 = (byte *)ALIGN_BACKWARD(LoadLibraryExA(reloc_file, NULL,
                                                  DONT_RESOLVE_DLL_REFERENCES),
                                   PAGE_SIZE);
    p2 = dll_2;
    VVERBOSE_PRINT("Loaded dll @ 0x%08x and 0x%08x\n", dll_1, dll_2);

    if (dll_1 == NULL || dll_2 == NULL) {
        VERBOSE_PRINT( "Error loading %s\n", input_file);
        return 1;
    }
    
    /* Handle the first page specially since I'm seeing problems with a handful of
     * dlls that aren't really getting rebased. mcupdate_GenuineIntel.dll for ex.
     * (which does have relocations etc.) not sure what's up, but it's only a couple of
     * dlls so will ignore them. If we really rebased the header should differ. */
    if (memcmp(dll_1, dll_2, PAGE_SIZE) == 0) {
        printf("%s - ERROR during relocating\n", input_file);
        return 1;
    } else {
        exact_no_match_pages++;
        if (assume_header_match)
            /* We could modify the hash function to catch header pages. */
            matched_pages++;
        else 
            unmatched_pages++;
    }
    p1 += PAGE_SIZE;
    p2 += PAGE_SIZE;

    if (assume_IAT_written && get_IAT_section_bounds(dll_1, &iat_start1, &iat_end1)) {
        has_iat = true;
        ASSERT(get_IAT_section_bounds(dll_2, &iat_start2, &iat_end2) &&
               iat_start1 - dll_1 == iat_start2 - dll_2 &&
               iat_end1 - dll_1 == iat_end2 - dll_2);
    }

    while (dr_virtual_query(p1, &info, sizeof(info)) == sizeof(info) &&
           info.State != MEM_FREE && info.AllocationBase == dll_1) {
        /* we only check read-only pages (assumption writable pages aren't shareable) */
        ASSERT(p1 == info.BaseAddress);
        if (info.State != MEM_COMMIT) {
            reserved_pages += info.RegionSize / PAGE_SIZE;
            VVERBOSE_PRINT("skipping %d reserved pages\n", info.RegionSize / PAGE_SIZE);
            p1 += info.RegionSize;
            p2 += info.RegionSize;
        } else if (!prot_is_writable(info.Protect)) {
            uint i;
            for (i = 0; i < info.RegionSize / PAGE_SIZE; i++) {
                bool exact = false;
                if (assume_IAT_written && has_iat &&
                    iat_end1 > p1 && iat_start1 < p1 + PAGE_SIZE) {
                    /* overlaps an IAT page */
                    IAT_pages++;
                    p1 += PAGE_SIZE;
                    p2 += PAGE_SIZE;
                    continue;
                }
                if (memcmp(p1, p2, PAGE_SIZE) == 0) {
                    VVERBOSE_PRINT("Page Exact Match\n");
                    exact_match_pages++;
                    exact = true;
                } else {
                    VVERBOSE_PRINT("Page Exact Mismatch\n");
                    exact_no_match_pages++;
                }
                if (compare_pages(drcontext, p1, p2, 0)) {
                    VVERBOSE_PRINT("Matched page\n");
                    matched_pages++;
                } else { 
                    VVERBOSE_PRINT("Failed to match page\n");
                    if (use_second_pass &&
                        compare_pages(drcontext, p1, p2, second_pass_offset)) {
                        second_matched_pages++;
                    } else {
                        unmatched_pages++;
                    }
                    ASSERT(!exact);
                }
                p1 += PAGE_SIZE;
                p2 += PAGE_SIZE;
            }
        } else {
            writable_pages += info.RegionSize / PAGE_SIZE;
            VVERBOSE_PRINT("skipping %d writable pages\n", info.RegionSize / PAGE_SIZE);
            p1 += info.RegionSize;
            p2 += info.RegionSize;
        }
    }

    VERBOSE_PRINT("%d exact match, %d not exact match\n%d hash_match, %d second_hash_match, %d hash_mismatch\n",
                  exact_match_pages, exact_no_match_pages, matched_pages, second_matched_pages, unmatched_pages); 

    printf("%s : %d pages - %d w %d res %d IAT = %d same %d differ : %d hash differ %d first hash differ : %d%% found, %d%% found first hash\n",
           input_file, writable_pages + reserved_pages + IAT_pages + exact_match_pages + exact_no_match_pages,
           writable_pages, reserved_pages, IAT_pages,
           exact_match_pages, exact_no_match_pages,
           unmatched_pages, unmatched_pages + second_matched_pages,
           (100 * (matched_pages + second_matched_pages - exact_match_pages))/exact_no_match_pages,
           (100 * (matched_pages - exact_match_pages))/exact_no_match_pages);

    while (spin_for_debugger)
        Sleep(1000);

    return 0;
}
Esempio n. 12
0
int
main(int argc, char *argv[])
{
    void *dcontext = dr_standalone_init();
    int res;
    char *dll;
    bool forced = false;

#ifdef X64
    set_x86_mode(dcontext, true/*x86*/);
#endif

    for (res=1; res < argc; res++) {
        if (strcmp(argv[res], "-sysenter") == 0) {
            expect_sysenter = true;
            forced = true;
        } else if (strcmp(argv[res], "-int2e") == 0) {
            expect_int2e = true;
            forced = true;
        } else if (strcmp(argv[res], "-wow") == 0) {
            expect_wow = true;
            forced = true;
        } else if (strcmp(argv[res], "-x64") == 0) {
            expect_x64 = true;
#ifdef X64
            set_x86_mode(dcontext, false/*x64*/);
#else
            /* For 32-bit builds we hack a fix for -syscalls (see
             * decode_syscall_num()) but -Ki won't work.
             */
#endif
            forced = true;
        } else if (strcmp(argv[res], "-v") == 0) {
            verbose = true;
        } else if (strcmp(argv[res], "-exports") == 0) {
            list_exports = true;
            list_forwards = true; /* implied */
        } else if (strcmp(argv[res], "-forwards") == 0) {
            list_forwards = true;
        } else if (strcmp(argv[res], "-Ki") == 0) {
            list_Ki = true;
        } else if (strcmp(argv[res], "-syscalls") == 0) {
            list_syscalls = true;
        } else if (strcmp(argv[res], "-ignore_Zw") == 0) {
            ignore_Zw = true;
        } else if (argv[res][0] == '-') {
            usage(argv[0]);
            assert(false); /* not reached */
        } else {
            break;
        }
    }
    if (res >= argc ||
        (!list_syscalls && !list_Ki && !list_forwards && !verbose)) {
        usage(argv[0]);
        assert(false); /* not reached */
    }
    dll = argv[res];

    if (!forced && list_syscalls) {
        usage(argv[0]);
        assert(false); /* not reached */
    }

    process_exports(dcontext, dll);
    return 0;
}