Skip to content

Instantly share code, notes, and snippets.

@DownWithUp
Created October 1, 2020 18:05
Show Gist options
  • Save DownWithUp/9cbf84972e74576a2b3828db58997085 to your computer and use it in GitHub Desktop.
Save DownWithUp/9cbf84972e74576a2b3828db58997085 to your computer and use it in GitHub Desktop.
// Test of ntoskrnl build 20226's thread state APIs.
#include <Windows.h>
#include <winternl.h>
#include <stdio.h>
// Looking at the disassembly, Unknown must be 0 or STATUS_INVALID_PARAMETER (0xC000000D) will be returned
typedef NTSTATUS(__fastcall* NtCreateThreadStateChange)(OUT PHANDLE StateChangeHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ThreadHandle, IN INT Unknown);
/*
New type of object (and therefore handle) type PspThreadStateChangeType
(pseudo code of checks)
if Action is <= 2
{
If Unknown1 is NOT 0, then instant return with code STATUS_INVALID_PARAMETER (0xC000000D)
If Unknown2 is NOT 0, then instant return with code STATUS_INFO_LENGTH_MISMATCH (0xC0000004)
}
If Unknown3 is NOT 0, then instant return with code STATUS_INVALID_PARAMETER (0xC000000D)
Action must be set to 1 for suspend, 2 for resume
*/
typedef NTSTATUS(__fastcall* NtChangeThreadState)(IN HANDLE StateChangeHandle, IN HANDLE ThreadHandle, IN ULONG Action, IN ULONG64 Unknown1, IN ULONG64 Unknown2, IN ULONG64 Unknown3);
void ThreadProc()
{
while (TRUE)
{
printf("[i] Seperate thread is running!\n");
Sleep(2500);
}
}
void main()
{
NtCreateThreadStateChange pNtCreateThreadStateChange;
NtChangeThreadState pNtChangeThreadState;
NTSTATUS ntRet;
HMODULE hNtdll;
HANDLE hStateChange;
HANDLE hSeperateThread;
hNtdll = GetModuleHandleA("ntdll.dll");
if (hNtdll)
{
pNtCreateThreadStateChange = GetProcAddress(hNtdll, "NtCreateThreadStateChange");
if (pNtCreateThreadStateChange)
{
hSeperateThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)ThreadProc, NULL, 0, NULL);
if (hSeperateThread != INVALID_HANDLE_VALUE)
{
ntRet = pNtCreateThreadStateChange(&hStateChange, MAXIMUM_ALLOWED, NULL, hSeperateThread, 0);
printf("[i] NtCreateThreadStateChange returned: 0x%X\n", ntRet);
printf("[.] Press [ENTER] to suspend\n");
getchar();
pNtChangeThreadState = GetProcAddress(hNtdll, "NtChangeThreadState");
if (pNtChangeThreadState)
{
ntRet = pNtChangeThreadState(hStateChange, hSeperateThread, 1, 0, 0, 0);
printf("[i] NtChangeThreadState returned: 0x%X\n", ntRet);
printf("[.] Press [ENTER] to resume\n");
getchar();
ntRet = pNtChangeThreadState(hStateChange, hSeperateThread, 2, 0, 0, 0);
printf("[i] NtChangeThreadState returned: 0x%X\n", ntRet);
}
printf("[.] Press [ENTER] to exit the program\n");
getchar();
CloseHandle(hSeperateThread);
CloseHandle(hStateChange);
ExitProcess(0);
}
}
}
ExitProcess(-1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment