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

📄 rootkit.c

📁 一个用于按键模拟的驱动 利用 port I/O
💻 C
字号:
#include "rootkit.h"
#include "DBKFunc.h"
#include <windef.h>


BOOLEAN MakeWritableKM(PVOID StartAddress,UINT_PTR size)
{
	UINT_PTR PTE,PDE;
	struct PTEStruct *x;
	UINT_PTR CurrentAddress=(UINT_PTR)StartAddress;	

	while (CurrentAddress<((UINT_PTR)StartAddress+size))
	{
		//find the PTE or PDE of the selected address
		PTE=(UINT_PTR)CurrentAddress;
		PTE=PTE/0x1000*PTESize+0xc0000000;

		PTE=(UINT_PTR)StartAddress;
		PTE=PTE/0x1000*PTESize+0xc0000000;

    	//now check if the address in PTE is valid by checking the page table directory at 0xc0300000 (same location as CR3 btw)
	    PDE=PTE/0x1000*PTESize+0xc0000000; //same formula

		x=(PVOID)PDE;
		if ((x->P==0) && (x->A2==0))
		{
			CurrentAddress+=PAGE_SIZE_LARGE;
			continue;
		}

		if (x->PS==1)
		{
			//big page, no pte
			x->RW=1;
			CurrentAddress+=PAGE_SIZE_LARGE;
			continue;
		}

		CurrentAddress+=0x1000;
		x=(PVOID)PTE;
		if ((x->P==0) && (x->A2==0))
			continue; //see for explenation the part of the PDE

		x->RW=1;
	}

	return TRUE;
}

BOOLEAN MakeWritable(PVOID StartAddress,UINT_PTR size,BOOLEAN usecopyonwrite)
{
#ifndef AMD64
	struct PTEStruct *x;
	unsigned char y;
	UINT_PTR CurrentAddress=(UINT_PTR)StartAddress;	

	//Makes usermode <0x80000000 writable
	if (((UINT_PTR)StartAddress>=0x80000000) || ((UINT_PTR)StartAddress+size>=0x80000000)) 
		return MakeWritableKM(StartAddress,size); //safety check: don't do kernelmemory with this routine

	//4kb pages (assumption, I know, but thats the system i'm working with)
	//PTE/0x1000*4+0xc0000000;

	while (CurrentAddress<((UINT_PTR)StartAddress+size))
	{
		__try
		{
			y=*(PCHAR)CurrentAddress; //page it in if it wasn't loaded already
			x=(PVOID)(CurrentAddress/0x1000*PTESize+0xc0000000);
			if (x->RW==0) //if it's read only then
			{
				if (usecopyonwrite)
                    x->A1=1;  //set the copy-on-write bit to 1
				else
					x->RW=1; //just writable
			}
		}
		__except(1)
		{
			//ignore and continue
		}	

        CurrentAddress+=0x1000;
	}	

	return TRUE;
#else
	return FALSE;
#endif
}


//this unit will contain the functions and other crap used by the hider function
BOOLEAN CheckImageName(IN PUNICODE_STRING FullImageName, IN char* List,int listsize)
{
	/*
	pre:List has been initialized and all entries are UPPERCASE. Each entry is seperated
	    by a 0-marker so just setting the pointer ro the start and doing a compare will work

	*/
	ANSI_STRING tempstring;
	int i;

	//DbgPrint("Checking this image name...\n");
	RtlZeroMemory(&tempstring,sizeof(ANSI_STRING));
	if (RtlUnicodeStringToAnsiString(&tempstring,FullImageName,TRUE)== STATUS_SUCCESS)
	{
		char *p;
		INT_PTR modulesize;
		__try
		{
			RtlUpperString(&tempstring,&tempstring);

			p=List;
	
			for (i=0;i<listsize;i++)
			{
				if (List[i]=='\0')
				{
					modulesize=i-(INT_PTR)(p-List);
					if (modulesize>=0)
					{	
						//DbgPrint("Checking %s with %s\n",&tempstring.Buffer[tempstring.Length-modulesize],p);

						if ((tempstring.Length>=modulesize) && (strcmp(p,&tempstring.Buffer[tempstring.Length-modulesize])==0))
						{
							//we have a match!!!
							//DbgPrint("It's a match with %s\n",p);
							return TRUE;	
						}						
	
					}
					p=&List[i+1];
				}
	
			}
		
			
		}
		__finally
		{
			RtlFreeAnsiString(&tempstring);	
		}
	}

	//DbgPrint("No match\n");
	return FALSE;

}

VOID LoadImageNotifyRoutine(IN PUNICODE_STRING  FullImageName, IN HANDLE  ProcessId, IN PIMAGE_INFO  ImageInfo)
{
	BOOLEAN RemoveIt=FALSE;

	if ((ProtectOn) && (GlobalDenyList) && (DenyList)) //check for denylist to be %100 sure
		RemoveIt=CheckImageName(FullImageName,ModuleList,ModuleListSize);

	if ((ProtectOn) && (!RemoveIt) && (ProcessId==(HANDLE)ProtectedProcessID))
	{
		if (DenyList)
			RemoveIt=CheckImageName(FullImageName,ModuleList,ModuleListSize);
		else //it's an accept list
			RemoveIt=!CheckImageName(FullImageName,ModuleList,ModuleListSize);
	}

	
	if ((RemoveIt) && (!ImageInfo->SystemModeImage))
	{
		ULONG i;
		char* p;

		MakeWritable(ImageInfo->ImageBase,ImageInfo->ImageSize,TRUE);

		p=ImageInfo->ImageBase;
		__try
		{
			for(i=0;i<ImageInfo->ImageSize;i++)
				p[i]=0xc3;
		}
		__except(1)
		{
		}
	}
		
}

int counter=0;
NTSTATUS NewPsGetContextThread(IN PETHREAD Thread, IN OUT PCONTEXT ThreadContext, IN KPROCESSOR_MODE PreviousMode)
{
	//DbgPrint("PsGetContextThread called: %d\n",PsGetCurrentProcessId());
	counter++;
	return OldPsGetContextThread(Thread,ThreadContext,PreviousMode);
}


NTSTATUS NewZwOpenProcess(OUT PHANDLE ProcessHandle,  IN ACCESS_MASK DesiredAccess,  IN POBJECT_ATTRIBUTES ObjectAttributes,  IN PCLIENT_ID ClientId)
{	
#ifndef AMD64
	if ((ProtectOn) && (PsGetCurrentProcessId()!=ProtectedProcessID) && (((UINT_PTR)(ClientId->UniqueProcess)>=(UINT_PTR)ProtectedProcessID)) && ((UINT_PTR)(ClientId->UniqueProcess)<(UINT_PTR)ProtectedProcessID+4))
	{
		if ((UINT_PTR)ProcessHandle<=0x80000000) //make it more genuine
		{
			__try
			{
                *ProcessHandle=0;
			}
			__except(1)
			{

			}
		}


		return 0xC0000005;		
	
	}
	else
#endif
		return OldZwOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
}

NTSTATUS NewZwQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation,IN ULONG SystemInformationLength,OUT PULONG ReturnLength OPTIONAL )
{
	typedef struct _SYSTEM_THREAD_INFORMATION {
	    LARGE_INTEGER KernelTime;
	    LARGE_INTEGER UserTime;
	    LARGE_INTEGER CreateTime;
	    ULONG         WaitTime;
	    PVOID         StartAddress;
	    CLIENT_ID     ClientId;
	    KPRIORITY     Priority;
	    KPRIORITY     BasePriority;
	    ULONG         ContextSwitchCount;
	    LONG          State;
	    LONG          WaitReason;
	} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;


	typedef struct _SYSTEM_PROCESS_INFORMATION {
	    ULONG             NextEntryDelta; //long live the delta, without it i'd be lost
	    ULONG             ThreadCount;
	    ULONG             Reserved1[6];
	    LARGE_INTEGER     CreateTime;
	    LARGE_INTEGER     UserTime;
	    LARGE_INTEGER     KernelTime;
	    UNICODE_STRING    ProcessName;
	    KPRIORITY         BasePriority;
	    ULONG             ProcessId;
	    ULONG             InheritedFromProcessId;
	    ULONG             HandleCount;
	    ULONG             Reserved2[2];
	    ULONG		      VmCounters;
	    ULONG		      IoCounters;
		SYSTEM_THREAD_INFORMATION Threads[1];
	} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;

	
	NTSTATUS result;

	result=OldZwQuerySystemInformation(SystemInformationClass,SystemInformation,SystemInformationLength,ReturnLength);;

#ifndef AMD64	
	if ((ProtectOn) && (PsGetCurrentProcessId()!=ProtectedProcessID) && (SystemInformationClass==5) && (NT_SUCCESS(result))) //process/thread info
	{
		PSYSTEM_PROCESS_INFORMATION pspi;
		PSYSTEM_PROCESS_INFORMATION pspi2;
		PSYSTEM_PROCESS_INFORMATION oldpspi=NULL;
		ULONG LastDelta=0;

		pspi=SystemInformation;
		
		while (1)
		{
			if (pspi->ProcessId==(ULONG)ProtectedProcessID)
			{
	
                pspi2= (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pspi)+pspi->NextEntryDelta);
				
				if (pspi==pspi2) //it's the last entry in the list
				{
					//just delete it and make the length shorter					
					oldpspi->NextEntryDelta=0; //mark the previous one as last entry in the list
					RtlZeroMemory(pspi,LastDelta);					
					break;
				}
				else
				{
					//link over it
					oldpspi->NextEntryDelta+=pspi->NextEntryDelta;
					RtlZeroMemory(pspi,pspi->NextEntryDelta);
					break;
				}
				
				break;
			}

            if (pspi->NextEntryDelta == 0) //end of list
				break;

			LastDelta=pspi->NextEntryDelta;
			oldpspi=pspi;
			pspi= (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pspi)+pspi->NextEntryDelta);
		}
	}
#endif
	
	return result;
}

UINT_PTR NewNtUserQueryWindow(IN ULONG WindowHandle,IN ULONG TypeInformation)
{
#ifndef AMD64
	ULONG WindowHandleProcessID;

	if ((ProtectOn) && (PsGetCurrentProcessId()!=ProtectedProcessID))
	{
		WindowHandleProcessID=OldNtUserQueryWindow(WindowHandle,0);
		if (WindowHandleProcessID==(ULONG)ProtectedProcessID)
			return 0;
	}
#endif

	return OldNtUserQueryWindow(WindowHandle,TypeInformation);
}


NTSTATUS NewNtUserBuildHwndList(IN HDESK hdesk, IN HWND hwndNext, IN ULONG fEnumChildren, IN DWORD idThread, IN UINT cHwndMax, OUT HWND *phwndFirst, OUT ULONG* pcHwndNeeded)
{
#ifndef AMD64
	NTSTATUS result;

	if ((ProtectOn) && (PsGetCurrentProcessId()!=ProtectedProcessID))
	{
		ULONG ProcessID;
		//scan the results for windowhandles of the protected processid
		if (fEnumChildren==1)
		{
            ProcessID=OldNtUserQueryWindow((ULONG)hwndNext,0);
			if (ProcessID==(ULONG)ProtectedProcessID)
				return STATUS_UNSUCCESSFUL;
		}
		result=OldNtUserBuildHwndList(hdesk,hwndNext,fEnumChildren,idThread,cHwndMax,phwndFirst,pcHwndNeeded);

		if (result==STATUS_SUCCESS)
		{
		//not go through the list and check for windows with a process that is protected
		//if it's found, remove it from the list
			ULONG i=0;
			ULONG j;

			while (i<*pcHwndNeeded)
			{
				ProcessID=OldNtUserQueryWindow((ULONG)phwndFirst[i],0);
				if (ProcessID==(ULONG)ProtectedProcessID)
				{
					//Whoa there baby, don't tell the user this exists
					for (j=i; j<(*pcHwndNeeded)-1; j++)					
						phwndFirst[j]=phwndFirst[j+1]; //shift all handles after this one place

					phwndFirst[*pcHwndNeeded-1]=0; //just make it empty

					(*pcHwndNeeded)--; //return less 
					continue; //continue the loop and check the current i
				}
                i++;				
			}
			
		}

		return result;
	}
#endif
	return OldNtUserBuildHwndList(hdesk,hwndNext,fEnumChildren,idThread,cHwndMax,phwndFirst,pcHwndNeeded);
}

ULONG NewNtUserFindWindowEx(IN HWND hwndParent, IN HWND hwndChild, IN PUNICODE_STRING pstrClassName OPTIONAL, IN PUNICODE_STRING pstrWindowName OPTIONAL, IN DWORD dwType)
{
	ULONG result;
	result=OldNtUserFindWindowEx(hwndParent,hwndChild,pstrClassName,pstrWindowName,dwType);
#ifndef AMD64	
	if ((ProtectOn) && (PsGetCurrentProcessId()!=ProtectedProcessID))
	{
		ULONG ProcessID;
		ProcessID=OldNtUserQueryWindow(result,0);
		if (ProcessID==(ULONG)ProtectedProcessID)
			return 1230;
	}
#endif

	return result;
}

ULONG NewNtUserGetForegroundWindow(VOID)
{
	ULONG result;
	result=OldNtUserGetForegroundWindow();
#ifndef AMD64	
	if ((ProtectOn) && (PsGetCurrentProcessId()!=ProtectedProcessID))
	{
		ULONG ProcessID;
		ProcessID=OldNtUserQueryWindow(result,0);
		if (ProcessID==(ULONG)ProtectedProcessID)
			result=LastForegroundWindow;
		else
            LastForegroundWindow=result;
	}
#endif
	
	return result;
}

_declspec( naked ) NTSTATUS OriginalObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState OPTIONAL, IN ACCESS_MASK DesiredAccess,
													  IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle )
{
	__asm
	{
		mov edi,edi
		push ebp
		mov ebp,esp
		//jmp back to the originalcode AFTER the jmp
		mov ebp,esp
		mov ebp,esp
		mov ebp,esp
		mov ebp,esp
		mov ebp,esp
		mov ebp,esp
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
	}


}


NTSTATUS NewObOpenObjectByPointer (IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState OPTIONAL, IN ACCESS_MASK DesiredAccess,
								   IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle )
{
	/*if (testprotect==Object)
	{	
		*Handle=NULL;
		return 0;
	}*/

	return OriginalObOpenObjectByPointer(Object,HandleAttributes,PassedAccessState,DesiredAccess,ObjectType,AccessMode,Handle);

}


void cr3_change_callback(ULONG oldcr3, ULONG newcr3)
{
	ULONG *stack;

	HANDLE pid=PsGetCurrentProcessId();

   // if newcr3 = protectedprocess and pid isn't protected process then block
	
	stack=(ULONG *)(((ULONG)&oldcr3)-4);

	//DbgPrint("stack=%p ...\n",stack);
	//DbgPrint("stack[0]=%x\n",stack[0]);
	//DbgPrint("stack[1]=%x\n",stack[1]);
	//DbgPrint("stack[2]=%x\n",stack[2]);	

	//DbgPrint("CR3 changed at %x : oldcr3=%x newcr3=%x - PID=%x\n",stack[0], oldcr3, newcr3, pid);

    //KeBugCheckEx(0xce, (ULONG)stack,stack[0],stack[1],stack[2]);


	//vmx_exit_cr3_callback(newcr3);
	//DbgPrint("OMGWTF I'M STILL HERE! WAAAAAAAAAAAAH!!!!!\n");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -