Created
October 1, 2020 18:05
-
-
Save DownWithUp/9cbf84972e74576a2b3828db58997085 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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