Exemple #1
0
/* for tasks unrelated to shadowing that are common to all tools */
void
os_shared_post_syscall(void *drcontext, cls_syscall_t *pt, drsys_sysnum_t sysnum,
                       dr_mcontext_t *mc, drsys_syscall_t *syscall)
{
    switch (sysnum.number) {
    case SYS_clone: {
        uint flags = (uint) syscall_get_param(drcontext, 0);
        if (TEST(CLONE_VM, flags)) {
            thread_id_t child = dr_syscall_get_result(drcontext);
            report_child_thread(drcontext, child);
            break;
        }
        /* else, fall through */
    }
    case SYS_fork: {
#ifndef USE_DRSYMS
        /* PR 453867: tell postprocess.pl to not exit until it sees a message
         * from the child starting up.
         */
        process_id_t child = dr_syscall_get_result(drcontext);
        if (child != 0)
            ELOGF(0, f_fork, "FORK child=%d\n", child);
#endif
        break;
    }
    }
}
Exemple #2
0
/* Caller should check for success and only call if syscall is successful (for !pre) */
static void
syscall_check_gdi(bool pre, void *drcontext, drsys_sysnum_t sysnum, cls_syscall_t *pt,
                  dr_mcontext_t *mc)
{
    app_loc_t loc;
    ASSERT(options.check_gdi, "shouldn't be called");
    if (drsys_sysnums_equal(&sysnum, &sysnum_UserGetDC) ||
        drsys_sysnums_equal(&sysnum, &sysnum_UserGetDCEx) ||
        drsys_sysnums_equal(&sysnum, &sysnum_UserGetWindowDC) ||
        drsys_sysnums_equal(&sysnum, &sysnum_UserBeginPaint) ||
        drsys_sysnums_equal(&sysnum, &sysnum_GdiGetDCforBitmap) ||
        drsys_sysnums_equal(&sysnum, &sysnum_GdiDdGetDC)) {
        if (!pre) {
            HDC hdc = (HDC) dr_syscall_get_result(drcontext);
            /* i#1192: NtGdiGetDCforBitmap does not allocate a new DC
             * that needs to be freed.  We leave it enabled as an
             * "allocation" to have more DC's in our table (presumably
             * adding in those created before we took over).
             */
            uint flags = 0;
            if (!drsys_sysnums_equal(&sysnum, &sysnum_GdiGetDCforBitmap))
                flags |= GDI_DC_ALLOC_GET;
            syscall_to_loc(&loc, sysnum, "");
            gdicheck_dc_alloc(hdc, flags, sysnum, mc, &loc);
            if (drsys_sysnums_equal(&sysnum, &sysnum_UserBeginPaint)) {
                /* we store the hdc for access in EndPaint */
                pt->paintDC = hdc;
            }
        }
    } else if (drsys_sysnums_equal(&sysnum, &sysnum_GdiCreateMetafileDC) ||
               drsys_sysnums_equal(&sysnum, &sysnum_GdiCreateCompatibleDC) ||
               drsys_sysnums_equal(&sysnum, &sysnum_GdiOpenDCW)) {
        if (!pre) {
            HDC hdc = (HDC) dr_syscall_get_result(drcontext);
            uint flags = GDI_DC_ALLOC_CREATE;
            if (drsys_sysnums_equal(&sysnum, &sysnum_GdiCreateCompatibleDC) &&
                syscall_get_param(drcontext, 0) == 0)
                flags |= GDI_DC_ALLOC_DUP_NULL;
            syscall_to_loc(&loc, sysnum, "");
            gdicheck_dc_alloc(hdc, flags, sysnum, mc, &loc);
        }
    } else if (drsys_sysnums_equal(&sysnum, &sysnum_UserReleaseDC) ||
               drsys_sysnums_equal(&sysnum, &sysnum_UserEndPaint)) {
        if (pre) {
            HDC hdc;
            if (drsys_sysnums_equal(&sysnum, &sysnum_UserReleaseDC))
                hdc = (HDC)syscall_get_param(drcontext, 0);
            else {
                hdc = pt->paintDC;
                pt->paintDC = NULL;
            }
            gdicheck_dc_free(hdc, false/*Get not Create*/, sysnum, mc);
        }
    } else if (drsys_sysnums_equal(&sysnum, &sysnum_GdiDeleteObjectApp)) {
        if (pre)
            gdicheck_obj_free((HANDLE)syscall_get_param(drcontext, 0), sysnum, mc);
    }
}
Exemple #3
0
static void
event_post_syscall(void *drcontext, int sysnum)
{
	unsigned long ret;
    per_thread_t *data = drmgr_get_tls_field(drcontext, tls_index);

//	dr_fprintf(STDERR, "post sysnum %d\n", sysnum);

	switch (sysnum) {

		case BRK_SYSCALL :
			ret = dr_syscall_get_result(drcontext);

			if (!data->param[0]) {
				global_range.upper = ret;
				global_range.upper_addr = (void *)ret;

				heap_range.lower = ret;
				heap_range.lower_addr = (void *)ret;
			}
			else {
				heap_range.upper = ret;
				heap_range.upper_addr = (void *)ret;
				markAlloc(heap_range.lower, heap_range.upper - heap_range.lower);
			}
//			dr_printf("brk %u ret %x\n", data->param[0], ret);
//			dr_fprintf(STDERR, "	ret %x\n", ret);

			break;

		case MMAP_SYSCALL :
			ret = dr_syscall_get_result(drcontext);

//			dr_printf("mmap %u %x\n", data->param[1], ret);
	//		dr_fprintf(STDERR, "	ret %x\n", ret);

			markAlloc(ret, data->param[1]);

			break;

		case MUNMAP_SYSCALL :
//			dr_printf("unmap %x %u\n", data->param[0], data->param[1]);
			ret = dr_syscall_get_result(drcontext);
	//		dr_fprintf(STDERR, "ret %u\n", ret);

			unmarkAlloc(data->param[0], data->param[1]);

			break;
	}
}
Exemple #4
0
static void
event_post_syscall(void *drcontext, int sysnum)
{
#ifdef SHOW_RESULTS
    dr_fprintf(STDERR, "  [%d] => "PFX" ("SZFMT")\n",
               sysnum, 
               dr_syscall_get_result(drcontext),
               (ptr_int_t)dr_syscall_get_result(drcontext));
#endif
    if (sysnum == write_sysnum) {
        per_thread_t *data = (per_thread_t *) drmgr_get_cls_field(drcontext, tcls_idx);
        /* we repeat a write originally to stdout that we redirected to
         * stderr: on the repeat we use stdout
         */
        if (data->repeat) {
            /* repeat syscall with stdout */
            int i;
#ifdef SHOW_RESULTS
            dr_fprintf(STDERR, "  [%d] => repeating\n", sysnum);
#endif
            dr_syscall_set_sysnum(drcontext, write_sysnum);
            dr_syscall_set_param(drcontext, 0, (reg_t) STDOUT);
            for (i = 1; i < SYS_MAX_ARGS; i++) 
                dr_syscall_set_param(drcontext, i, data->param[i]);
#ifdef WINDOWS
            if (dr_is_wow64()) {
                /* Set the xcx emulation parameter for wow64: since
                 * we're executing the same system call again we can
                 * use that same parameter.  For new system calls we'd
                 * need to determine the parameter from the ntdll
                 * wrapper.
                 */
                dr_mcontext_t mc = {sizeof(mc),DR_MC_INTEGER/*only need xcx*/};
                dr_get_mcontext(drcontext, &mc);
                mc.xcx = data->xcx;
                dr_set_mcontext(drcontext, &mc);
            }
#endif
            dr_syscall_invoke_another(drcontext);
        }
    }
}
Exemple #5
0
static void
event_post_syscall(void *drcontext, int sysnum)
{
    drsys_syscall_t *syscall;
    bool success = false;

    if (drsys_cur_syscall(drcontext, &syscall) != DRMF_SUCCESS)
        ASSERT(false, "drsys_cur_syscall failed");

    if (drsys_syscall_succeeded(syscall, dr_syscall_get_result(drcontext), &success) !=
        DRMF_SUCCESS)
        ASSERT(false, "drsys_syscall_succeeded failed");

    OUTPUT("    %s =>\n", success ? "succeeded" : "failed");
    if (drsys_iterate_args(drcontext, drsys_iter_arg_cb, NULL) != DRMF_SUCCESS)
        ASSERT(false, "drsys_iterate_args failed");
}
static bool
drsys_iter_arg_cb(drsys_arg_t *arg, void *user_data)
{
    ptr_uint_t val;
    uint64 val64;

    ASSERT(arg->valid, "no args should be invalid in this app");
    ASSERT(arg->mc != NULL, "mc check");
    ASSERT(arg->drcontext == dr_get_current_drcontext(), "dc check");

    if (arg->reg == DR_REG_NULL && !TEST(DRSYS_PARAM_RETVAL, arg->mode)) {
        ASSERT((byte *)arg->start_addr >= (byte *)arg->mc->xsp &&
               (byte *)arg->start_addr < (byte *)arg->mc->xsp + PAGE_SIZE,
               "mem args should be on stack");
    }

    if (TEST(DRSYS_PARAM_RETVAL, arg->mode)) {
        ASSERT(arg->pre ||
               arg->value == dr_syscall_get_result(dr_get_current_drcontext()),
               "return val wrong");
    } else {
        if (drsys_pre_syscall_arg(arg->drcontext, arg->ordinal, &val) != DRMF_SUCCESS)
            ASSERT(false, "drsys_pre_syscall_arg failed");
        if (drsys_pre_syscall_arg64(arg->drcontext, arg->ordinal, &val64) != DRMF_SUCCESS)
            ASSERT(false, "drsys_pre_syscall_arg64 failed");
        if (arg->size < sizeof(val)) {
            val = truncate_int_to_size(val, arg->size);
            val64 = truncate_int_to_size(val64, arg->size);
        }
        ASSERT(val == arg->value, "values do not match");
        ASSERT(val64 == arg->value64, "values do not match");
    }

    /* We could test drsys_handle_is_current_process() but we'd have to
     * locate syscalls operating on processes.  Currently drsyscall.c
     * already tests this call.
     */

    return true; /* keep going */
}
Exemple #7
0
static void post_open(void *drcontext)
{
	int fd;
	struct per_thread_journal_state *jstate;

	jstate = (struct per_thread_journal_state *)
		drmgr_get_tls_field(drcontext, tls_idx);

	if (jstate->state == THREAD_STATE_DEFAULT)
		return;

	fd = (int)dr_syscall_get_result(drcontext);

	if (jstate->state == THREAD_STATE_OPENING_JFILE_0) {
		fi_printf("fd of jfile0: %d\n", fd);
		jfile_fds[0] = fd;
	} else if (jstate->state == THREAD_STATE_OPENING_JFILE_1) {
		fi_printf("fd of jfile1: %d\n", fd);
		jfile_fds[1] = fd;
	}

	jstate->state = THREAD_STATE_DEFAULT;
}