Skip to content

Commit

Permalink
i#2273: Use sysnum file for drmf tests (#2280)
Browse files Browse the repository at this point in the history
Adds use of a sysnum file generated by a prior Dr. Memory test to the
drmf tests which use dryscall.  #2279 covers a better long-term solution.

Fixes #2273
  • Loading branch information
derekbruening authored Mar 9, 2020
1 parent fd96499 commit a587015
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 19 deletions.
19 changes: 16 additions & 3 deletions tests/framework/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# **********************************************************
# Copyright (c) 2012-2019 Google, Inc. All rights reserved.
# Copyright (c) 2012-2020 Google, Inc. All rights reserved.
# **********************************************************

# Dr. Memory: the memory debugger
Expand Down Expand Up @@ -101,11 +101,24 @@ function(add_drmf_test test_name app_name src_client ext_list client_options pas
endif ()
endfunction(add_drmf_test)

# i#2273: We need to locate a sysnum file. Unfortunately creating one is only
# supported from a front end so we rely on a Dr. Memory test having created one.
# These will fail w/ direct-named test launches in a fresh dir but we can live with
# that for now: a suite run will run "hello" first.
# TODO: i#2279: Come up with a better method.
set(symcache_dir "${PROJECT_BINARY_DIR}/logs/symcache")

add_drmf_test_app(drsyscall_app drsyscall_app.c)
add_drmf_test(drsyscall_test drsyscall_app drsyscall_client.c
drsyscall "" "done\nTEST PASSED")
drsyscall "${symcache_dir}" "done\nTEST PASSED")
if (NOT ANDROID) # XXX i#1860: Android tests not enabled yet.
set_property(TEST drsyscall_test APPEND PROPERTY DEPENDS hello)
endif ()
add_drmf_test(strace_test drsyscall_app strace_client.c
drsyscall "" "done\n.*TEST PASSED")
drsyscall "${symcache_dir}" "done\n.*TEST PASSED")
if (NOT ANDROID) # XXX i#1860: Android tests not enabled yet.
set_property(TEST strace_test APPEND PROPERTY DEPENDS hello)
endif ()

# drfuzz tests
add_drmf_test_app(drfuzz_app_empty drfuzz_app_empty.c)
Expand Down
64 changes: 50 additions & 14 deletions tests/framework/drsyscall_client.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2012-2017 Google, Inc. All rights reserved.
* Copyright (c) 2012-2020 Google, Inc. All rights reserved.
* **********************************************************/

/* Dr. Memory: the memory debugger
Expand Down Expand Up @@ -27,7 +27,9 @@
#include <string.h>
#ifdef WINDOWS
# include <windows.h>
# define IF_WINDOWS_ELSE(x,y) x
#else
# define IF_WINDOWS_ELSE(x,y) y
# include <sys/types.h>
# include <sys/socket.h>
#endif
Expand All @@ -41,7 +43,21 @@
__FILE__, __LINE__, #cond, msg), \
dr_abort(), 0) : 0))

#define BUFFER_SIZE_BYTES(buf) sizeof(buf)
#define BUFFER_SIZE_ELEMENTS(buf) (BUFFER_SIZE_BYTES(buf) / sizeof((buf)[0]))
#define BUFFER_LAST_ELEMENT(buf) (buf)[BUFFER_SIZE_ELEMENTS(buf) - 1]
#define NULL_TERMINATE_BUFFER(buf) BUFFER_LAST_ELEMENT(buf) = 0

#ifdef WINDOWS
/* TODO i#2279: Make it easier for clients to auto-generate! */
# define SYSNUM_FILE IF_X64_ELSE("syscalls_x64.txt", "syscalls_x86.txt")
# define SYSNUM_FILE_WOW64 "syscalls_wow64.txt"
#endif

static bool verbose;
#ifdef WINDOWS
static dr_os_version_info_t os_version = {sizeof(os_version),};
#endif

static void
check_mcontext(void *drcontext)
Expand Down Expand Up @@ -166,7 +182,8 @@ event_pre_syscall(void *drcontext, int sysnum)
ASSERT(false, "failed to get syscall return type");

if (drsys_syscall_is_known(syscall, &known) != DRMF_SUCCESS || !known)
ASSERT(false, "no syscalls in this app should be unknown");
ASSERT(IF_WINDOWS_ELSE(os_version.version >= DR_WINDOWS_VERSION_10_1607, false),
"no syscalls in this app should be unknown");

if (drsys_iterate_args(drcontext, drsys_iter_arg_cb, NULL) != DRMF_SUCCESS)
ASSERT(false, "drsys_iterate_args failed");
Expand Down Expand Up @@ -199,12 +216,9 @@ event_post_syscall(void *drcontext, int sysnum)

if (drsys_cur_syscall_result(drcontext, &success, NULL, NULL) !=
DRMF_SUCCESS || !success) {
/* With the new early injector on Linux, we see access, open, + stat64 fail */
#ifdef WINDOWS
/* On win10, NtQueryValueKey fails */
ASSERT(strcmp(name, "NtQueryValueKey") == 0,
"syscalls in this app shouldn't fail");
#endif
/* With the new early injector on Linux, we see access, open, + stat64 fail,
* And on Win10, several syscalls fail.
*/
} else {
if (drsys_iterate_memargs(drcontext, drsys_iter_memarg_cb, NULL) != DRMF_SUCCESS)
ASSERT(false, "drsys_iterate_memargs failed");
Expand Down Expand Up @@ -249,7 +263,7 @@ test_static_queries(void)
/* test Zw variant */
num.secondary = 4;
if (drsys_name_to_syscall("ZwContinue", &syscall) != DRMF_SUCCESS)
ASSERT(false, "drsys_name_to_syscall failed");
ASSERT(false, "drsys_name_to_syscall failed on ZwContinue");
res = drsys_syscall_number(syscall, &num);
ASSERT(res == DRMF_SUCCESS && num.secondary == 0, "drsys_name_to_syscall failed");
/* test not found */
Expand Down Expand Up @@ -282,15 +296,26 @@ test_static_queries(void)
ASSERT(res == DRMF_SUCCESS && name != NULL, "drsys_syscall_name failed");

#ifdef WINDOWS
/* test secondary number to name, in particular where secondary==0 */
if (drsys_name_to_syscall("NtUserCallNoParam.CREATEMENU", &syscall) != DRMF_SUCCESS)
ASSERT(false, "drsys_name_to_syscall failed");
/* Test secondary number to name, in particular where secondary==0 */
bool secondary_zero = false;
if (drsys_name_to_syscall("NtUserCallNoParam.CREATEMENU", &syscall) == DRMF_SUCCESS)
secondary_zero = true;
else {
/* Some auto-generations don't find CREATEMENU. */
if (drsys_name_to_syscall("NtUserCallNoParam.DESTROY_CARET", &syscall) !=
DRMF_SUCCESS) {
ASSERT(false, "drsys_name_to_syscall failed on NtUserCallNoParam");
}
}
res = drsys_syscall_number(syscall, &num);
ASSERT(res == DRMF_SUCCESS && num.secondary == 0, "drsys_syscall_number failed");
ASSERT(res == DRMF_SUCCESS && (!secondary_zero || num.secondary == 0),
"drsys_syscall_number failed");
if (drsys_number_to_syscall(num, &syscall) != DRMF_SUCCESS)
ASSERT(false, "drsys_number_to_syscall failed");
res = drsys_syscall_name(syscall, &name);
ASSERT(res == DRMF_SUCCESS && strcmp(name, "NtUserCallNoParam.CREATEMENU") == 0,
ASSERT(res == DRMF_SUCCESS &&
((secondary_zero && strcmp(name, "NtUserCallNoParam.CREATEMENU") == 0) ||
(!secondary_zero && strcmp(name, "NtUserCallNoParam.DESTROY_CARET") == 0)),
"drsys_syscall_name failed");
#endif
}
Expand Down Expand Up @@ -347,6 +372,17 @@ DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
drsys_options_t ops = { sizeof(ops), 0, };
#ifdef WINDOWS
if (argc > 1) {
/* Takes an optional argument pointing at the base dir for a sysnum file. */
char sysnum_path[MAXIMUM_PATH];
dr_snprintf(sysnum_path, BUFFER_SIZE_ELEMENTS(sysnum_path),
"%s\\%s", argv[1], SYSNUM_FILE);
NULL_TERMINATE_BUFFER(sysnum_path);
ops.sysnum_file = sysnum_path;
}
dr_get_os_version(&os_version);
#endif
drmgr_init();
if (drsys_init(id, &ops) != DRMF_SUCCESS)
ASSERT(false, "drsys failed to init");
Expand Down
34 changes: 32 additions & 2 deletions tests/framework/strace_client.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2013-2014 Google, Inc. All rights reserved.
* Copyright (c) 2013-2020 Google, Inc. All rights reserved.
* **********************************************************/

/* Dr. Memory: the memory debugger
Expand Down Expand Up @@ -32,6 +32,9 @@
#include <string.h>
#ifdef WINDOWS
# include <windows.h>
# define IF_WINDOWS_ELSE(x,y) x
#else
# define IF_WINDOWS_ELSE(x,y) y
#endif

#define TEST(mask, var) (((mask) & (var)) != 0)
Expand All @@ -43,8 +46,23 @@
__FILE__, __LINE__, #cond, msg), \
dr_abort(), 0) : 0))

#define BUFFER_SIZE_BYTES(buf) sizeof(buf)
#define BUFFER_SIZE_ELEMENTS(buf) (BUFFER_SIZE_BYTES(buf) / sizeof((buf)[0]))
#define BUFFER_LAST_ELEMENT(buf) (buf)[BUFFER_SIZE_ELEMENTS(buf) - 1]
#define NULL_TERMINATE_BUFFER(buf) BUFFER_LAST_ELEMENT(buf) = 0

#ifdef WINDOWS
/* TODO i#2279: Make it easier for clients to auto-generate! */
# define SYSNUM_FILE IF_X64_ELSE("syscalls_x64.txt", "syscalls_x86.txt")
# define SYSNUM_FILE_WOW64 "syscalls_wow64.txt"
#endif

static bool verbose = true;

#ifdef WINDOWS
static dr_os_version_info_t os_version = {sizeof(os_version),};
#endif

static bool
drsys_iter_memarg_cb(drsys_arg_t *arg, void *user_data)
{
Expand Down Expand Up @@ -156,7 +174,8 @@ event_pre_syscall(void *drcontext, int sysnum)
dr_fprintf(STDERR, "\treturn type: %d\n", ret_type);

if (drsys_syscall_is_known(syscall, &known) != DRMF_SUCCESS || !known)
ASSERT(false, "no syscalls in this app should be unknown");
ASSERT(IF_WINDOWS_ELSE(os_version.version >= DR_WINDOWS_VERSION_10_1607, false),
"no syscalls in this app should be unknown");

if (drsys_iterate_args(drcontext, drsys_iter_arg_cb, NULL) != DRMF_SUCCESS)
ASSERT(false, "drsys_iterate_args failed");
Expand Down Expand Up @@ -215,6 +234,17 @@ DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
drsys_options_t ops = { sizeof(ops), 0, };
#ifdef WINDOWS
if (argc > 1) {
/* Takes an optional argument pointing at the base dir for a sysnum file. */
char sysnum_path[MAXIMUM_PATH];
dr_snprintf(sysnum_path, BUFFER_SIZE_ELEMENTS(sysnum_path),
"%s\\%s", argv[1], SYSNUM_FILE);
NULL_TERMINATE_BUFFER(sysnum_path);
ops.sysnum_file = sysnum_path;
}
dr_get_os_version(&os_version);
#endif
drmgr_init();
if (drsys_init(id, &ops) != DRMF_SUCCESS)
ASSERT(false, "drsys failed to init");
Expand Down

0 comments on commit a587015

Please sign in to comment.