mirror of
https://github.com/Hue-Jhan/Syscalls-Thread-Hijacking
synced 2026-06-06 15:44:31 +00:00
233 lines
15 KiB
C
233 lines
15 KiB
C
#pragma once
|
|
#include <stdio.h>
|
|
#include <windows.h>
|
|
#include <tlhelp32.h>
|
|
#include <winbase.h>
|
|
#define STATUS_SUCCESS (NTSTATUS)0x00000000L
|
|
#define PRINTXD(FUNCTION_NAME, NTSTATUS_ERROR) \
|
|
do { \
|
|
fprintf(stderr, FUNCTION_NAME " line %d, error: 0x%lx\n", __LINE__, NTSTATUS_ERROR); \
|
|
} while (0)
|
|
|
|
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004)
|
|
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
|
|
|
typedef LONG NTSTATUS;
|
|
typedef struct _PS_ATTRIBUTE {
|
|
ULONG Attribute;
|
|
SIZE_T Size;
|
|
union
|
|
{
|
|
ULONG Value;
|
|
PVOID ValuePtr;
|
|
} u1;
|
|
PSIZE_T ReturnLength;
|
|
} PS_ATTRIBUTE, * PPS_ATTRIBUTE;
|
|
typedef struct _UNICODE_STRING {
|
|
USHORT Length;
|
|
USHORT MaximumLength;
|
|
_Field_size_bytes_part_opt_(MaximumLength, Length) PWCH Buffer;
|
|
} UNICODE_STRING, * PUNICODE_STRING;
|
|
typedef struct _OBJECT_ATTRIBUTES {
|
|
ULONG Length;
|
|
HANDLE RootDirectory;
|
|
PUNICODE_STRING ObjectName;
|
|
ULONG Attributes;
|
|
PVOID SecurityDescriptor;
|
|
PVOID SecurityQualityOfService;
|
|
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
|
|
typedef const UNICODE_STRING* PCUNICODE_STRING;
|
|
typedef const OBJECT_ATTRIBUTES* PCOBJECT_ATTRIBUTES;
|
|
typedef struct _INITIAL_TEB {
|
|
struct {
|
|
PVOID OldStackBase; // Pointer to the base address of the previous stack.
|
|
PVOID OldStackLimit; // Pointer to the limit address of the previous stack.
|
|
} OldInitialTeb;
|
|
PVOID StackBase; // Pointer to the base address of the new stack.
|
|
PVOID StackLimit; // Pointer to the limit address of the new stack.
|
|
PVOID StackAllocationBase; // Pointer to the base address where the stack was allocated.
|
|
} INITIAL_TEB, * PINITIAL_TEB;
|
|
typedef struct _CLIENT_ID {
|
|
HANDLE UniqueProcess;
|
|
HANDLE UniqueThread;
|
|
} CLIENT_ID, * PCLIENT_ID;
|
|
typedef struct _PS_ATTRIBUTE_LIST {
|
|
SIZE_T TotalLength;
|
|
PS_ATTRIBUTE Attributes[1];
|
|
} PS_ATTRIBUTE_LIST, * PPS_ATTRIBUTE_LIST;
|
|
typedef LONG KPRIORITY, * PKPRIORITY;
|
|
typedef enum _SYSTEM_INFORMATION_CLASS {
|
|
SystemProcessInformation = 5
|
|
} SYSTEM_INFORMATION_CLASS;
|
|
typedef enum _KWAIT_REASON
|
|
{
|
|
Executive, // Waiting for an executive event.
|
|
FreePage, // Waiting for a free page.
|
|
PageIn, // Waiting for a page to be read in.
|
|
PoolAllocation, // Waiting for a pool allocation.
|
|
DelayExecution, // Waiting due to a delay execution. // NtDelayExecution
|
|
Suspended, // Waiting because the thread is suspended. // NtSuspendThread
|
|
UserRequest, // Waiting due to a user request. // NtWaitForSingleObject
|
|
WrExecutive, // Waiting for an executive event.
|
|
WrFreePage, // Waiting for a free page.
|
|
WrPageIn, // Waiting for a page to be read in.
|
|
WrPoolAllocation, // Waiting for a pool allocation. // 10
|
|
WrDelayExecution, // Waiting due to a delay execution.
|
|
WrSuspended, // Waiting because the thread is suspended.
|
|
WrUserRequest, // Waiting due to a user request.
|
|
WrEventPair, // Waiting for an event pair. // NtCreateEventPair
|
|
WrQueue, // Waiting for a queue. // NtRemoveIoCompletion
|
|
WrLpcReceive, // Waiting for an LPC receive. // NtReplyWaitReceivePort
|
|
WrLpcReply, // Waiting for an LPC reply. // NtRequestWaitReplyPort
|
|
WrVirtualMemory, // Waiting for virtual memory.
|
|
WrPageOut, // Waiting for a page to be written out. // NtFlushVirtualMemory
|
|
WrRendezvous, // Waiting for a rendezvous. // 20
|
|
WrKeyedEvent, // Waiting for a keyed event. // NtCreateKeyedEvent
|
|
WrTerminated, // Waiting for thread termination.
|
|
WrProcessInSwap, // Waiting for a process to be swapped in.
|
|
WrCpuRateControl, // Waiting for CPU rate control.
|
|
WrCalloutStack, // Waiting for a callout stack.
|
|
WrKernel, // Waiting for a kernel event.
|
|
WrResource, // Waiting for a resource.
|
|
WrPushLock, // Waiting for a push lock.
|
|
WrMutex, // Waiting for a mutex.
|
|
WrQuantumEnd, // Waiting for the end of a quantum. // 30
|
|
WrDispatchInt, // Waiting for a dispatch interrupt.
|
|
WrPreempted, // Waiting because the thread was preempted.
|
|
WrYieldExecution, // Waiting to yield execution.
|
|
WrFastMutex, // Waiting for a fast mutex.
|
|
WrGuardedMutex, // Waiting for a guarded mutex.
|
|
WrRundown, // Waiting for a rundown.
|
|
WrAlertByThreadId, // Waiting for an alert by thread ID.
|
|
WrDeferredPreempt, // Waiting for a deferred preemption.
|
|
WrPhysicalFault, // Waiting for a physical fault.
|
|
WrIoRing, // Waiting for an I/O ring. // 40
|
|
WrMdlCache, // Waiting for an MDL cache.
|
|
WrRcu, // Waiting for read-copy-update (RCU) synchronization.
|
|
MaximumWaitReason
|
|
} KWAIT_REASON, * PKWAIT_REASON;
|
|
typedef enum _KTHREAD_STATE
|
|
{
|
|
Initialized,
|
|
Ready,
|
|
Running,
|
|
Standby,
|
|
Terminated,
|
|
Waiting,
|
|
Transition,
|
|
DeferredReady,
|
|
GateWaitObsolete,
|
|
WaitingForProcessInSwap,
|
|
MaximumThreadState
|
|
} KTHREAD_STATE, * PKTHREAD_STATE;
|
|
typedef struct _SYSTEM_THREAD_INFORMATION
|
|
{
|
|
LARGE_INTEGER KernelTime; // Number of 100-nanosecond intervals spent executing kernel code.
|
|
LARGE_INTEGER UserTime; // Number of 100-nanosecond intervals spent executing user code.
|
|
LARGE_INTEGER CreateTime; // The date and time when the thread was created.
|
|
ULONG WaitTime; // The current time spent in ready queue or waiting (depending on the thread state).
|
|
PVOID StartAddress; // The initial start address of the thread.
|
|
CLIENT_ID ClientId; // The identifier of the thread and the process owning the thread.
|
|
KPRIORITY Priority; // The dynamic priority of the thread.
|
|
KPRIORITY BasePriority; // The starting priority of the thread.
|
|
ULONG ContextSwitches; // The total number of context switches performed.
|
|
KTHREAD_STATE ThreadState; // The current state of the thread.
|
|
KWAIT_REASON WaitReason; // The current reason the thread is waiting.
|
|
} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;
|
|
typedef struct _SYSTEM_PROCESS_INFORMATION
|
|
{
|
|
ULONG NextEntryOffset; // The address of the previous item plus the value in the NextEntryOffset member. For the last item in the array, NextEntryOffset is 0.
|
|
ULONG NumberOfThreads; // The NumberOfThreads member contains the number of threads in the process.
|
|
ULONGLONG WorkingSetPrivateSize; // The total private memory that a process currently has allocated and is physically resident in memory. // since VISTA
|
|
ULONG HardFaultCount; // The total number of hard faults for data from disk rather than from in-memory pages. // since WIN7
|
|
ULONG NumberOfThreadsHighWatermark; // The peak number of threads that were running at any given point in time, indicative of potential performance bottlenecks related to thread management.
|
|
ULONGLONG CycleTime; // The sum of the cycle time of all threads in the process.
|
|
LARGE_INTEGER CreateTime; // Number of 100-nanosecond intervals since the creation time of the process. Not updated during system timezone changes.
|
|
LARGE_INTEGER UserTime; // Number of 100-nanosecond intervals the process has executed in user mode.
|
|
LARGE_INTEGER KernelTime; // Number of 100-nanosecond intervals the process has executed in kernel mode.
|
|
UNICODE_STRING ImageName; // The file name of the executable image.
|
|
KPRIORITY BasePriority; // The starting priority of the process.
|
|
HANDLE UniqueProcessId; // The identifier of the process.
|
|
HANDLE InheritedFromUniqueProcessId; // The identifier of the process that created this process. Not updated and incorrectly refers to processes with recycled identifiers.
|
|
ULONG HandleCount; // The current number of open handles used by the process.
|
|
ULONG SessionId; // The identifier of the Remote Desktop Services session under which the specified process is running.
|
|
ULONG_PTR UniqueProcessKey; // since VISTA (requires SystemExtendedProcessInformation)
|
|
SIZE_T PeakVirtualSize; // The peak size, in bytes, of the virtual memory used by the process.
|
|
SIZE_T VirtualSize; // The current size, in bytes, of virtual memory used by the process.
|
|
ULONG PageFaultCount; // The total number of page faults for data that is not currently in memory. The value wraps around to zero on average 24 hours.
|
|
SIZE_T PeakWorkingSetSize; // The peak size, in kilobytes, of the working set of the process.
|
|
SIZE_T WorkingSetSize; // The number of pages visible to the process in physical memory. These pages are resident and available for use without triggering a page fault.
|
|
SIZE_T QuotaPeakPagedPoolUsage; // The peak quota charged to the process for pool usage, in bytes.
|
|
SIZE_T QuotaPagedPoolUsage; // The quota charged to the process for paged pool usage, in bytes.
|
|
SIZE_T QuotaPeakNonPagedPoolUsage; // The peak quota charged to the process for nonpaged pool usage, in bytes.
|
|
SIZE_T QuotaNonPagedPoolUsage; // The current quota charged to the process for nonpaged pool usage.
|
|
SIZE_T PagefileUsage; // The total number of bytes of page file storage in use by the process.
|
|
SIZE_T PeakPagefileUsage; // The maximum number of bytes of page-file storage used by the process.
|
|
SIZE_T PrivatePageCount; // The number of memory pages allocated for the use by the process.
|
|
LARGE_INTEGER ReadOperationCount; // The total number of read operations performed.
|
|
LARGE_INTEGER WriteOperationCount; // The total number of write operations performed.
|
|
LARGE_INTEGER OtherOperationCount; // The total number of I/O operations performed other than read and write operations.
|
|
LARGE_INTEGER ReadTransferCount; // The total number of bytes read during a read operation.
|
|
LARGE_INTEGER WriteTransferCount; // The total number of bytes written during a write operation.
|
|
LARGE_INTEGER OtherTransferCount; // The total number of bytes transferred during operations other than read and write operations.
|
|
SYSTEM_THREAD_INFORMATION Threads[1]; // This type is not defined in the structure but was added for convenience.
|
|
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;
|
|
|
|
#ifndef InitializeObjectAttributes
|
|
#define InitializeObjectAttributes( p, n, a, r, s ) { \
|
|
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
|
|
(p)->RootDirectory = r; \
|
|
(p)->Attributes = a; \
|
|
(p)->ObjectName = n; \
|
|
(p)->SecurityDescriptor = s; \
|
|
(p)->SecurityQualityOfService = NULL; \
|
|
}
|
|
#endif
|
|
#ifndef _In_
|
|
#define _In_
|
|
#endif
|
|
#ifndef _Out_opt_
|
|
#define _Out_opt_
|
|
#endif
|
|
#ifndef _Out_writes_bytes_opt_
|
|
#define _Out_writes_bytes_opt_(x)
|
|
#endif
|
|
|
|
BOOL HijackThread(IN HANDLE hThread, IN PVOID pAddress);
|
|
VOID temp(VOID);
|
|
VOID GetSyscallNumber(_In_ HMODULE NtdllHandle, _In_ LPCSTR NtFunctionName, _Out_ PDWORD NtFunctionSSN);
|
|
BOOL GetProcessNative(LPCWSTR processName, DWORD* outPid);
|
|
BOOL GetThreadNative(DWORD pid, DWORD* outTid);
|
|
|
|
DWORD h_NtOpenProcessSSN;
|
|
DWORD h_NtAllocateVirtualMemorySSN;
|
|
DWORD h_NtWriteVirtualMemorySSN;
|
|
DWORD h_NtProtectVirtualMemorySSN;
|
|
DWORD h_NtCreateThreadSSN;
|
|
DWORD h_NtCreateThreadExSSN;
|
|
DWORD h_NtWaitForSingleObjectSSN;
|
|
DWORD h_NtFreeVirtualMemorySSN;
|
|
DWORD h_NtCloseSSN;
|
|
DWORD h_NtSuspendThreadSSN;
|
|
DWORD h_NtResumeThreadSSN;
|
|
DWORD h_NtQuerySystemInformationSSN;
|
|
DWORD h_NtGetContextThreadSSN;
|
|
DWORD h_NtSetContextThreadSSN;
|
|
DWORD h_NtOpenThreadSSN;
|
|
|
|
extern NTSTATUS NtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL);
|
|
extern NTSTATUS NtAllocateVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID* BaseAddress, IN ULONG ZeroBits, IN OUT PSIZE_T RegionSize, IN ULONG AllocationType, IN ULONG Protect);
|
|
extern NTSTATUS NtProtectVirtualMemory(_In_ HANDLE ProcessHandle, _Inout_ PVOID* BaseAddress, _Inout_ PSIZE_T RegionSize, _In_ ULONG NewProtect, _Out_ PULONG OldProtect);
|
|
extern NTSTATUS NtWriteVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN SIZE_T NumberOfBytesToWrite, OUT PSIZE_T NumberOfBytesWritten OPTIONAL);
|
|
extern NTSTATUS NtCreateThreadEx(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle, IN PVOID StartRoutine, IN PVOID Argument OPTIONAL, IN ULONG CreateFlags, IN SIZE_T ZeroBits, IN SIZE_T StackSize, IN SIZE_T MaximumStackSize, IN PPS_ATTRIBUTE_LIST AttributeList OPTIONAL);
|
|
extern NTSTATUS NtCreateThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, _In_opt_ PCOBJECT_ATTRIBUTES ObjectAttributes,IN HANDLE ProcessHandle, _Out_ PCLIENT_ID ClientId, _In_ PCONTEXT ThreadContext, _In_ PINITIAL_TEB InitialTeb, _In_ BOOLEAN CreateSuspended);
|
|
extern NTSTATUS NtWaitForSingleObject(_In_ HANDLE Handle, _In_ BOOLEAN Alertable, _In_opt_ PLARGE_INTEGER Timeout);
|
|
extern NTSTATUS NtFreeVirtualMemory(_In_ HANDLE ProcessHandle, _Inout_ PVOID* BaseAddress, _Inout_ PSIZE_T RegionSize, _In_ ULONG FreeType);
|
|
extern NTSTATUS NtClose(IN HANDLE Handle);
|
|
extern NTSTATUS NtQuerySystemInformation(_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, _Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation, _In_ ULONG SystemInformationLength, _Out_opt_ PULONG ReturnLength);
|
|
extern NTSTATUS NtSuspendThread(_In_ HANDLE ThreadHandle, _Out_opt_ PULONG PreviousSuspendCount);
|
|
extern NTSTATUS NtResumeThread(_In_ HANDLE ThreadHandle, _Out_opt_ PULONG PreviousSuspendCount);
|
|
extern NTSTATUS NtGetContextThread(_In_ HANDLE ThreadHandle, _Inout_ PCONTEXT ThreadContext);
|
|
extern NTSTATUS NtSetContextThread(_In_ HANDLE ThreadHandle, _In_ PCONTEXT ThreadContext);
|
|
extern NTSTATUS NtOpenThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL);
|