Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PsGetProcessCreateTimeQuadPart and PsGetProcessExitTime #193

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions inc/usersim/ps.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@ USERSIM_API
void
usersime_set_process_exit_status_callback(_In_ PGETPROCESSEXITSTATUS callback);

typedef LONGLONG (*PGETPROCESSCREATETIMEQUADPART)(_In_ PEPROCESS process);

USERSIM_API
_IRQL_requires_max_(DISPATCH_LEVEL) NTKERNELAPI LONGLONG PsGetProcessCreateTimeQuadPart(_In_ PEPROCESS Process);

USERSIM_API
void
usersime_set_process_create_time_quadpart_callback(_In_ PGETPROCESSCREATETIMEQUADPART callback);

typedef LARGE_INTEGER (*PGETPROCESSEXITTIME)(VOID);

USERSIM_API
_IRQL_requires_max_(APC_LEVEL) NTKERNELAPI LARGE_INTEGER PsGetProcessExitTime(VOID);

USERSIM_API
void
usersime_set_process_exit_time_callback(_In_ PGETPROCESSEXITTIME callback);

USERSIM_API
_IRQL_requires_max_(DISPATCH_LEVEL) NTKERNELAPI HANDLE PsGetCurrentThreadId();

Expand Down
45 changes: 44 additions & 1 deletion src/ps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ _IRQL_requires_max_(DISPATCH_LEVEL) NTKERNELAPI HANDLE PsGetCurrentThreadId()

static PGETPROCESSEXITSTATUS _usersim_get_process_exit_status_callback = NULL;

USERSIM_API
NTSTATUS
PsGetProcessExitStatus(_In_ PEPROCESS Process) {
PsGetProcessExitStatus(_In_ PEPROCESS Process)
{
if (_usersim_get_process_exit_status_callback != NULL) {
return _usersim_get_process_exit_status_callback(Process);
}
Expand All @@ -34,6 +36,47 @@ usersime_set_process_exit_status_callback(_In_ PGETPROCESSEXITSTATUS callback)
_usersim_get_process_exit_status_callback = callback;
}

static PGETPROCESSCREATETIMEQUADPART _usersim_get_process_create_time_quadpart_callback = NULL;

USERSIM_API
LONGLONG
PsGetProcessCreateTimeQuadPart(_In_ PEPROCESS Process)
{
if (_usersim_get_process_create_time_quadpart_callback != NULL) {
return _usersim_get_process_create_time_quadpart_callback(Process);
}

// Fall back to the beginning of time
return 0;
}

USERSIM_API
void
usersime_set_process_create_time_quadpart_callback(_In_ PGETPROCESSCREATETIMEQUADPART callback)
{
_usersim_get_process_create_time_quadpart_callback = callback;
}

static PGETPROCESSEXITTIME _usersim_get_process_exit_time_callback = NULL;

USERSIM_API
LARGE_INTEGER PsGetProcessExitTime(VOID)
{
if (_usersim_get_process_exit_time_callback != NULL) {
return _usersim_get_process_exit_time_callback();
}

// Fall back to the beginning of time
LARGE_INTEGER li = {0};
return li;
}

void
usersime_set_process_exit_time_callback(_In_ PGETPROCESSEXITTIME callback)
{
_usersim_get_process_exit_time_callback = callback;
}

static PCREATE_PROCESS_NOTIFY_ROUTINE_EX _usersim_process_creation_notify_routine = NULL;

USERSIM_API
Expand Down
39 changes: 38 additions & 1 deletion tests/ps_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ TEST_CASE("PsGetProcessExitStatus", "[ps]")
auto status = PsGetProcessExitStatus((PEPROCESS)0);
REQUIRE(status == -1);

usersime_set_process_exit_status_callback([](PEPROCESS proc) -> NTSTATUS { return ((int)proc) + 1; });
usersime_set_process_exit_status_callback([](PEPROCESS proc) -> NTSTATUS { return ((int)proc) + 1; });

status = PsGetProcessExitStatus((PEPROCESS)0);
REQUIRE(status == 1);
Expand All @@ -61,4 +61,41 @@ TEST_CASE("PsGetProcessExitStatus", "[ps]")
usersime_set_process_exit_status_callback(NULL);
status = PsGetProcessExitStatus((PEPROCESS)0);
REQUIRE(status == -1);
}

TEST_CASE("PsGetProcessCreateTimeQuadPart", "[ps]")
{
// If no callback is installed, we default to 0
auto time = PsGetProcessCreateTimeQuadPart((PEPROCESS)0);
REQUIRE(time == 0);

usersime_set_process_create_time_quadpart_callback([](PEPROCESS proc) -> LONGLONG { return ((int)proc) + 1; });

time = PsGetProcessCreateTimeQuadPart((PEPROCESS)0);
REQUIRE(time == 1);

time = PsGetProcessCreateTimeQuadPart((PEPROCESS)1234);
REQUIRE(time == 1235);

// Setting back to a NULL callback reverts to returning 0
usersime_set_process_create_time_quadpart_callback(NULL);
time = PsGetProcessCreateTimeQuadPart((PEPROCESS)0);
REQUIRE(time == 0);
}

TEST_CASE("PsGetProcessExitTime", "[ps]")
{
// If no callback is installed, we default to 0
auto time = PsGetProcessExitTime();
REQUIRE(time.QuadPart == 0);

usersime_set_process_exit_time_callback([]() -> LARGE_INTEGER { return {123}; });

time = PsGetProcessExitTime();
REQUIRE(time.QuadPart == 123);

// Setting back to a NULL callback reverts to returning 0
usersime_set_process_exit_time_callback(NULL);
time = PsGetProcessExitTime();
REQUIRE(time.QuadPart == 0);
}