mirror of
https://github.com/DynamoRIO/dynamorio.git
synced 2026-10-12 02:02:04 +00:00
Updates all the "FIXME" comments in the repository to instead use "TODO" (for those about missing implementations: "NYI" or "ASSERT_NOT_IMPLEMENTED") or "XXX" (everything else). This matches our style guide which discourages "FIXME" as its connotations are too negative and too easily mis-interpreted by readers and in code audits to imply that the current state of things is broken in some way instead of just meaning something could be improved.
501 lines
18 KiB
C
501 lines
18 KiB
C
/* **********************************************************
|
|
* Copyright (c) 2005-2006 VMware, Inc. All rights reserved.
|
|
* **********************************************************/
|
|
|
|
/*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of VMware, Inc. nor the names of its contributors may be
|
|
* used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
* DAMAGE.
|
|
*/
|
|
|
|
/* DR core / shared library interface unit tests */
|
|
/* executed as part of the unit tests for processes.c */
|
|
|
|
/* need to have a core build anyway for these tests to work */
|
|
#include "win32/events.h"
|
|
|
|
/* nudge tends to hang/timeout if you nudge right after the
|
|
* process starts. so in order to let the basic tests pass,
|
|
* they all sleep for at least this long before trying to
|
|
* nudge.
|
|
* of course this should be fixed and then we should create
|
|
* stress tests to address this specifically. */
|
|
#define NUDGE_LET_PROCESS_START_WAIT 500
|
|
|
|
#define TEST_TIMEOUT 2000
|
|
#define LAUNCH_TIMEOUT 1000
|
|
|
|
#define WAIT_FOR_APP(hProc) \
|
|
DO_ASSERT(WAIT_OBJECT_0 == WaitForSingleObject(hProc, TEST_TIMEOUT * 2))
|
|
|
|
#define LONG_WAIT_FOR_APP(hProc) \
|
|
DO_ASSERT(WAIT_OBJECT_0 == WaitForSingleObject(hProc, TEST_TIMEOUT * 20))
|
|
|
|
#define DO_TEST(name, appstr, block) DO_TEST_HP(name, appstr, TRUE, block)
|
|
|
|
#define TESTER_1_BLOCK \
|
|
"BEGIN_BLOCK\n" \
|
|
"APP_NAME=tester_1.exe\n" \
|
|
"DYNAMORIO_OPTIONS=-kill_thread -kill_thread_max 1000 -report_max 0 -dumpcore_mask " \
|
|
"0xff\n" \
|
|
"END_BLOCK\n"
|
|
|
|
#define TESTER_2_BLOCK \
|
|
"BEGIN_BLOCK\n" \
|
|
"APP_NAME=tester_2.exe\n" \
|
|
"DYNAMORIO_OPTIONS=-dumpcore_mask 0xff\n" \
|
|
"END_BLOCK\n"
|
|
|
|
#define TESTER_1_HOT_PATCH_BLOCK \
|
|
"BEGIN_BLOCK\n" \
|
|
"APP_NAME=tester_1.exe\n" \
|
|
"DYNAMORIO_OPTIONS=-kill_thread -dumpcore_mask 0xff\n" \
|
|
"DYNAMORIO_HOT_PATCH_MODES=\\conf\\test-modes.cfg\n" \
|
|
"BEGIN_MP_MODES\n" \
|
|
"1\n" \
|
|
"TEST.000A:2\n" \
|
|
"END_MP_MODES\n" \
|
|
"END_BLOCK\n"
|
|
|
|
#define TESTER_1_HOT_PATCH_DETECT_BLOCK \
|
|
"BEGIN_BLOCK\n" \
|
|
"APP_NAME=tester_1.exe\n" \
|
|
"DYNAMORIO_OPTIONS=-kill_thread -dumpcore_mask 0xff\n" \
|
|
"DYNAMORIO_HOT_PATCH_MODES=\\conf\\test-modes.cfg\n" \
|
|
"BEGIN_MP_MODES\n" \
|
|
"1\n" \
|
|
"TEST.000A:1\n" \
|
|
"END_MP_MODES\n" \
|
|
"END_BLOCK\n"
|
|
|
|
/* simple detach */
|
|
DO_TEST(detach, TESTER_1_BLOCK, {
|
|
UINT pid;
|
|
LAUNCH_APP(L"tester_1.exe 5000", &pid);
|
|
/* XXX: if this isn't here, the first run (right after
|
|
* building the tests) always fails. */
|
|
Sleep(LAUNCH_TIMEOUT * 2);
|
|
VERIFY_UNDER_DR(pid);
|
|
CHECKED_OPERATION(detach(pid, TRUE, DETACH_RECOMMENDED_TIMEOUT));
|
|
VERIFY_NOT_UNDER_DR(pid);
|
|
TERMINATE_PROCESS(pid);
|
|
});
|
|
|
|
/* pending restart */
|
|
DO_TEST(pending_restart, TESTER_1_BLOCK, {
|
|
UINT pid;
|
|
LAUNCH_APP(L"tester_1.exe 5000", &pid);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid);
|
|
CHECKED_OPERATION(detach(pid, TRUE, DETACH_RECOMMENDED_TIMEOUT));
|
|
VERIFY_NOT_UNDER_DR(pid);
|
|
DO_ASSERT(is_process_pending_restart(pid));
|
|
DO_ASSERT(is_any_process_pending_restart());
|
|
TERMINATE_PROCESS(pid);
|
|
});
|
|
|
|
/* detach_exe */
|
|
DO_TEST(detach_exe, TESTER_1_BLOCK TESTER_2_BLOCK, {
|
|
UINT pid1;
|
|
UINT pid2;
|
|
UINT pid3;
|
|
LAUNCH_APP(L"tester_1.exe", &pid1);
|
|
LAUNCH_APP(L"tester_2.exe", &pid2);
|
|
LAUNCH_APP(L"tester_1.exe", &pid3);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid1);
|
|
VERIFY_UNDER_DR(pid2);
|
|
VERIFY_UNDER_DR(pid3);
|
|
CHECKED_OPERATION(detach_exe(L"tester_1.exe", DETACH_RECOMMENDED_TIMEOUT));
|
|
VERIFY_NOT_UNDER_DR(pid1);
|
|
VERIFY_UNDER_DR(pid2);
|
|
VERIFY_NOT_UNDER_DR(pid3);
|
|
DO_ASSERT(is_process_pending_restart(pid1));
|
|
DO_ASSERT(!is_process_pending_restart(pid2));
|
|
DO_ASSERT(is_any_process_pending_restart());
|
|
TERMINATE_PROCESS(pid1);
|
|
TERMINATE_PROCESS(pid2);
|
|
TERMINATE_PROCESS(pid3);
|
|
});
|
|
|
|
/* detach_all */
|
|
DO_TEST(detach_all, TESTER_1_BLOCK TESTER_2_BLOCK, {
|
|
UINT pid1;
|
|
UINT pid2;
|
|
UINT pid3;
|
|
LAUNCH_APP(L"tester_1.exe", &pid1);
|
|
LAUNCH_APP(L"tester_2.exe", &pid2);
|
|
LAUNCH_APP(L"tester_1.exe", &pid3);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid1);
|
|
VERIFY_UNDER_DR(pid2);
|
|
VERIFY_UNDER_DR(pid3);
|
|
CHECKED_OPERATION(detach_all(DETACH_RECOMMENDED_TIMEOUT));
|
|
VERIFY_NOT_UNDER_DR(pid1);
|
|
VERIFY_NOT_UNDER_DR(pid2);
|
|
VERIFY_NOT_UNDER_DR(pid3);
|
|
DO_ASSERT(is_process_pending_restart(pid1));
|
|
DO_ASSERT(is_any_process_pending_restart());
|
|
TERMINATE_PROCESS(pid1);
|
|
TERMINATE_PROCESS(pid2);
|
|
TERMINATE_PROCESS(pid3);
|
|
});
|
|
|
|
/* consistency_detach */
|
|
DO_TEST(consistency_detach, TESTER_1_BLOCK TESTER_2_BLOCK, {
|
|
UINT pid1;
|
|
UINT pid2;
|
|
UINT pid3;
|
|
LAUNCH_APP(L"tester_1.exe", &pid1);
|
|
LAUNCH_APP(L"tester_2.exe", &pid2);
|
|
LAUNCH_APP(L"tester_1.exe", &pid3);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid1);
|
|
VERIFY_UNDER_DR(pid2);
|
|
VERIFY_UNDER_DR(pid3);
|
|
CHECKED_OPERATION(load_test_config(TESTER_2_BLOCK, FALSE));
|
|
CHECKED_OPERATION(consistency_detach(DETACH_RECOMMENDED_TIMEOUT));
|
|
VERIFY_NOT_UNDER_DR(pid1);
|
|
VERIFY_UNDER_DR(pid2);
|
|
VERIFY_NOT_UNDER_DR(pid3);
|
|
TERMINATE_PROCESS(pid1);
|
|
TERMINATE_PROCESS(pid2);
|
|
TERMINATE_PROCESS(pid3);
|
|
});
|
|
|
|
/* check start/stop events */
|
|
DO_TEST(start_stop_event, TESTER_1_BLOCK, {
|
|
UINT pid;
|
|
HANDLE hProc;
|
|
LAUNCH_APP_HANDLE(L"tester_1.exe 10", &pid, &hProc);
|
|
WAIT_FOR_APP(hProc);
|
|
DO_ASSERT(
|
|
check_for_event(MSG_INFO_PROCESS_START, L"tester_1.exe", pid, NULL, NULL, 0));
|
|
DO_ASSERT(
|
|
check_for_event(MSG_INFO_PROCESS_STOP, L"tester_1.exe", pid, NULL, NULL, 0));
|
|
});
|
|
|
|
/* check detach event */
|
|
DO_TEST(detach_event, TESTER_1_BLOCK, {
|
|
UINT pid;
|
|
LAUNCH_APP(L"tester_1.exe 2000", &pid);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid);
|
|
CHECKED_OPERATION(detach(pid, TRUE, DETACH_RECOMMENDED_TIMEOUT));
|
|
VERIFY_NOT_UNDER_DR(pid);
|
|
Sleep(100);
|
|
DO_ASSERT(
|
|
check_for_event(MSG_INFO_PROCESS_START, L"tester_1.exe", pid, NULL, NULL, 0));
|
|
DO_ASSERT(check_for_event(MSG_INFO_DETACHING, L"tester_1.exe", pid, NULL, NULL, 0));
|
|
TERMINATE_PROCESS(pid);
|
|
});
|
|
|
|
/* check attack event */
|
|
DO_TEST(attack_event, TESTER_1_BLOCK, {
|
|
UINT pid;
|
|
HANDLE hProc;
|
|
WCHAR s3[MAX_PATH];
|
|
WCHAR s4[MAX_PATH];
|
|
LAUNCH_APP_HANDLE(L"tester_1.exe 10 10 1", &pid, &hProc);
|
|
WAIT_FOR_APP(hProc);
|
|
DO_ASSERT(check_for_event(MSG_SEC_VIOLATION_THREAD, L"tester_1.exe", pid, s3, s4,
|
|
MAX_PATH));
|
|
/* make sure threat id looks ok */
|
|
DO_ASSERT(11 == wcslen(s3));
|
|
});
|
|
|
|
/* check forensics event/file */
|
|
DO_TEST(forensics_file, TESTER_1_BLOCK, {
|
|
UINT pid;
|
|
HANDLE hProc;
|
|
WCHAR s3[MAX_PATH];
|
|
WCHAR s4[MAX_PATH];
|
|
LAUNCH_APP_HANDLE(L"tester_1.exe 10 10 1", &pid, &hProc);
|
|
WAIT_FOR_APP(hProc);
|
|
DO_ASSERT(
|
|
check_for_event(MSG_SEC_VIOLATION_THREAD, L"tester_1.exe", pid, NULL, NULL, 0));
|
|
DO_ASSERT(check_for_event(MSG_SEC_FORENSICS, L"tester_1.exe", pid, s3, s4, MAX_PATH));
|
|
DO_ASSERT(file_exists(s3));
|
|
});
|
|
|
|
/* stress forensics event/file */
|
|
DO_TEST(forensics_stress, TESTER_1_BLOCK, {
|
|
UINT pid;
|
|
HANDLE hProc;
|
|
WCHAR s3[MAX_PATH];
|
|
WCHAR s4[MAX_PATH];
|
|
int i;
|
|
LAUNCH_APP_HANDLE(L"tester_1.exe 10 10 0 100", &pid, &hProc);
|
|
LONG_WAIT_FOR_APP(hProc);
|
|
for (i = 0; i < 100; i++) {
|
|
DO_ASSERT(check_for_event(MSG_SEC_VIOLATION_THREAD, L"tester_1.exe", pid, NULL,
|
|
NULL, 0));
|
|
DO_ASSERT(
|
|
check_for_event(MSG_SEC_FORENSICS, L"tester_1.exe", pid, s3, s4, MAX_PATH));
|
|
DO_ASSERT(file_exists(s3));
|
|
}
|
|
DO_ASSERT(
|
|
check_for_event(MSG_INFO_PROCESS_STOP, L"tester_1.exe", pid, NULL, NULL, 0));
|
|
});
|
|
|
|
/* check to make sure nudge doesn't leave the code lying around */
|
|
DO_TEST(check_nudge, TESTER_1_BLOCK, {
|
|
UINT pid;
|
|
WCHAR nudge_code_buf[MAX_PATH];
|
|
|
|
LAUNCH_APP(L"tester_1.exe", &pid);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid);
|
|
Sleep(NUDGE_LET_PROCESS_START_WAIT);
|
|
CHECKED_OPERATION(hotp_notify_modes_update(pid, TRUE, TEST_TIMEOUT));
|
|
DO_ASSERT(ERROR_SUCCESS !=
|
|
get_config_parameter(L_PRODUCT_NAME, FALSE, L_DYNAMORIO_VAR_NUDGE,
|
|
nudge_code_buf, MAX_PATH));
|
|
TERMINATE_PROCESS(pid);
|
|
});
|
|
|
|
/* simple test for hotpatching */
|
|
DO_TEST(hotp_protect, TESTER_1_HOT_PATCH_BLOCK, {
|
|
UINT pid;
|
|
char fc[MAX_PATH];
|
|
LAUNCH_APP_AND_WAIT(L"tester_1.exe 100", &pid);
|
|
CHECKED_OPERATION(read_file_contents(L"tester.out", fc, MAX_PATH, NULL));
|
|
DO_ASSERT(0 == strncmp(fc, "10", 2));
|
|
});
|
|
|
|
/* detect should report 00 */
|
|
DO_TEST(hotp_detect, TESTER_1_HOT_PATCH_DETECT_BLOCK, {
|
|
UINT pid;
|
|
char fc[MAX_PATH];
|
|
LAUNCH_APP_AND_WAIT(L"tester_1.exe 100", &pid);
|
|
CHECKED_OPERATION(read_file_contents(L"tester.out", fc, MAX_PATH, NULL));
|
|
DO_ASSERT(0 == strncmp(fc, "00", 2));
|
|
});
|
|
|
|
/* basic nudge test */
|
|
DO_TEST_HP(hotp_defs_nudge, TESTER_1_BLOCK, FALSE, /* don't load the modes file! */
|
|
{
|
|
UINT pid;
|
|
char fc[MAX_PATH];
|
|
HANDLE hProc;
|
|
hotp_policy_status_table_t *status_table = NULL;
|
|
|
|
/* first launch app w/o hotpatch */
|
|
LAUNCH_APP_AND_WAIT(L"tester_1.exe 10", &pid);
|
|
CHECKED_OPERATION(read_file_contents(L"tester.out", fc, MAX_PATH, NULL));
|
|
DO_ASSERT(0 == strncmp(fc, "00", 2));
|
|
|
|
/* now, same thing with longer wait */
|
|
LAUNCH_APP_HANDLE(L"tester_1.exe 2000", &pid, &hProc);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid);
|
|
|
|
/* make sure nothing's there */
|
|
DO_ASSERT(ERROR_DRMARKER_ERROR == get_hotp_status(pid, &status_table));
|
|
|
|
/* load the new config -- this time with hot patching*/
|
|
CHECKED_OPERATION(load_test_config(TESTER_1_HOT_PATCH_BLOCK, TRUE));
|
|
|
|
/* and nudge */
|
|
Sleep(NUDGE_LET_PROCESS_START_WAIT);
|
|
CHECKED_OPERATION(hotp_notify_defs_update(pid, TRUE, TEST_TIMEOUT));
|
|
VERIFY_UNDER_DR(pid);
|
|
WAIT_FOR_APP(hProc);
|
|
|
|
CHECKED_OPERATION(read_file_contents(L"tester.out", fc, MAX_PATH, NULL));
|
|
DO_ASSERT(0 == strncmp(fc, "10", 2));
|
|
});
|
|
|
|
DO_TEST(hotp_modes_nudge, TESTER_1_HOT_PATCH_BLOCK, {
|
|
UINT pid;
|
|
char fc[MAX_PATH];
|
|
HANDLE hProc;
|
|
|
|
/* first launch app w/hotpatch protect */
|
|
LAUNCH_APP_AND_WAIT(L"tester_1.exe 10", &pid);
|
|
CHECKED_OPERATION(read_file_contents(L"tester.out", fc, MAX_PATH, NULL));
|
|
DO_ASSERT(0 == strncmp(fc, "10", 2));
|
|
|
|
/* now, same thing with longer wait */
|
|
LAUNCH_APP_HANDLE(L"tester_1.exe 2000", &pid, &hProc);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid);
|
|
|
|
/* load the new config */
|
|
CHECKED_OPERATION(load_test_config(TESTER_1_HOT_PATCH_DETECT_BLOCK, TRUE));
|
|
|
|
/* and do a modes nudge */
|
|
Sleep(NUDGE_LET_PROCESS_START_WAIT);
|
|
CHECKED_OPERATION(hotp_notify_modes_update(pid, TRUE, TEST_TIMEOUT));
|
|
VERIFY_UNDER_DR(pid);
|
|
WAIT_FOR_APP(hProc);
|
|
|
|
CHECKED_OPERATION(read_file_contents(L"tester.out", fc, MAX_PATH, NULL));
|
|
DO_ASSERT(0 == strncmp(fc, "00", 2));
|
|
});
|
|
|
|
/* nudge twice to make sure we don't die */
|
|
DO_TEST_HP(hotp_nudge_twice, TESTER_1_BLOCK, FALSE, {
|
|
UINT pid;
|
|
char fc[MAX_PATH];
|
|
HANDLE hProc;
|
|
|
|
/* first launch app w/o hotpatch */
|
|
LAUNCH_APP_AND_WAIT(L"tester_1.exe 10", &pid);
|
|
CHECKED_OPERATION(read_file_contents(L"tester.out", fc, MAX_PATH, NULL));
|
|
DO_ASSERT(0 == strncmp(fc, "00", 2));
|
|
|
|
LAUNCH_APP_HANDLE(L"tester_1.exe 2000", &pid, &hProc);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid);
|
|
|
|
/* load the new config */
|
|
CHECKED_OPERATION(load_test_config(TESTER_1_HOT_PATCH_BLOCK, TRUE));
|
|
Sleep(NUDGE_LET_PROCESS_START_WAIT);
|
|
CHECKED_OPERATION(hotp_notify_defs_update(pid, TRUE, TEST_TIMEOUT));
|
|
VERIFY_UNDER_DR(pid);
|
|
|
|
/* load the old config back */
|
|
CHECKED_OPERATION(load_test_config(TESTER_1_HOT_PATCH_DETECT_BLOCK, TRUE));
|
|
CHECKED_OPERATION(hotp_notify_defs_update(pid, TRUE, TEST_TIMEOUT));
|
|
VERIFY_UNDER_DR(pid);
|
|
WAIT_FOR_APP(hProc);
|
|
|
|
CHECKED_OPERATION(read_file_contents(L"tester.out", fc, MAX_PATH, NULL));
|
|
DO_ASSERT(0 == strncmp(fc, "00", 2));
|
|
});
|
|
|
|
/* tests state of the patches */
|
|
DO_TEST(hotp_protect_status, TESTER_1_HOT_PATCH_BLOCK, {
|
|
UINT pid;
|
|
HANDLE hProc;
|
|
hotp_policy_status_table_t *status_table = NULL;
|
|
|
|
LAUNCH_APP_HANDLE(L"tester_1.exe 10 2500", &pid, &hProc);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid);
|
|
Sleep(500);
|
|
CHECKED_OPERATION(get_hotp_status(pid, &status_table));
|
|
DO_ASSERT(status_table != NULL && status_table->num_policies > 0);
|
|
if (status_table != NULL && status_table->num_policies > 0) {
|
|
UINT j;
|
|
for (j = 0; j < status_table->num_policies; j++) {
|
|
if (0 ==
|
|
strcmp(status_table->policy_status_array[j].policy_id, "TEST.000A") ||
|
|
0 ==
|
|
strcmp(status_table->policy_status_array[j].policy_id, "TEST.000B")) {
|
|
DO_ASSERT(status_table->policy_status_array[j].inject_status ==
|
|
HOTP_INJECT_PROTECT);
|
|
}
|
|
}
|
|
free_hotp_status_table(status_table);
|
|
}
|
|
WAIT_FOR_APP(hProc);
|
|
});
|
|
|
|
/* tests state of the patches */
|
|
DO_TEST(hotp_pending_status, TESTER_1_HOT_PATCH_BLOCK, {
|
|
UINT pid;
|
|
HANDLE hProc;
|
|
hotp_policy_status_table_t *status_table = NULL;
|
|
|
|
LAUNCH_APP_HANDLE(L"tester_1.exe 2500", &pid, &hProc);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid);
|
|
Sleep(200);
|
|
CHECKED_OPERATION(get_hotp_status(pid, &status_table));
|
|
DO_ASSERT(status_table != NULL && status_table->num_policies > 0);
|
|
if (status_table != NULL && status_table->num_policies > 0) {
|
|
UINT j;
|
|
for (j = 0; j < status_table->num_policies; j++) {
|
|
if (0 ==
|
|
strcmp(status_table->policy_status_array[j].policy_id, "TEST.000A") ||
|
|
0 ==
|
|
strcmp(status_table->policy_status_array[j].policy_id, "TEST.000B")) {
|
|
DO_ASSERT(status_table->policy_status_array[j].inject_status ==
|
|
HOTP_INJECT_PENDING);
|
|
}
|
|
}
|
|
free_hotp_status_table(status_table);
|
|
}
|
|
WAIT_FOR_APP(hProc);
|
|
});
|
|
|
|
/* sanity check to make sure we have different state */
|
|
DO_TEST(hotp_detect_status, TESTER_1_HOT_PATCH_DETECT_BLOCK, {
|
|
UINT pid;
|
|
HANDLE hProc;
|
|
hotp_policy_status_table_t *status_table = NULL;
|
|
|
|
LAUNCH_APP_HANDLE(L"tester_1.exe 10 2500", &pid, &hProc);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid);
|
|
Sleep(500);
|
|
CHECKED_OPERATION(get_hotp_status(pid, &status_table));
|
|
DO_ASSERT(status_table != NULL && status_table->num_policies > 0);
|
|
if (status_table != NULL && status_table->num_policies > 0) {
|
|
UINT j;
|
|
for (j = 0; j < status_table->num_policies; j++) {
|
|
if (0 ==
|
|
strcmp(status_table->policy_status_array[j].policy_id, "TEST.000A") ||
|
|
0 ==
|
|
strcmp(status_table->policy_status_array[j].policy_id, "TEST.000B")) {
|
|
DO_ASSERT(status_table->policy_status_array[j].inject_status ==
|
|
HOTP_INJECT_DETECT);
|
|
}
|
|
}
|
|
free_hotp_status_table(status_table);
|
|
}
|
|
WAIT_FOR_APP(hProc);
|
|
});
|
|
|
|
DO_TEST(hotp_modes_nudge_all, TESTER_1_HOT_PATCH_BLOCK, {
|
|
UINT pid;
|
|
char fc[MAX_PATH];
|
|
HANDLE hProc;
|
|
|
|
/* first launch app w/hotpatch protect */
|
|
LAUNCH_APP_AND_WAIT(L"tester_1.exe 10", &pid);
|
|
CHECKED_OPERATION(read_file_contents(L"tester.out", fc, MAX_PATH, NULL));
|
|
DO_ASSERT(0 == strncmp(fc, "10", 2));
|
|
|
|
/* now, same thing with longer wait */
|
|
LAUNCH_APP_HANDLE(L"tester_1.exe 2000", &pid, &hProc);
|
|
Sleep(LAUNCH_TIMEOUT);
|
|
VERIFY_UNDER_DR(pid);
|
|
|
|
/* load the new config */
|
|
CHECKED_OPERATION(load_test_config(TESTER_1_HOT_PATCH_DETECT_BLOCK, TRUE));
|
|
|
|
/* and do a modes nudge */
|
|
Sleep(NUDGE_LET_PROCESS_START_WAIT);
|
|
CHECKED_OPERATION(hotp_notify_all_modes_update(TEST_TIMEOUT));
|
|
VERIFY_UNDER_DR(pid);
|
|
WAIT_FOR_APP(hProc);
|
|
|
|
CHECKED_OPERATION(read_file_contents(L"tester.out", fc, MAX_PATH, NULL));
|
|
DO_ASSERT(0 == strncmp(fc, "00", 2));
|
|
});
|