关于怎么禁止一些特定程序运行的问题咯!!! ( 积分: 100 )

  • 主题发起人 主题发起人 I情人下载
  • 开始时间 开始时间
I

I情人下载

Unregistered / Unconfirmed
GUEST, unregistred user!
我想在自己的软件中添加禁止用户指定的程序运行。。不知道怎么实现??是通过注册表还是WInAPI??能否给出代码??系统是2000或XP的
 
从 http://www.delphibbs.com/delphibbs/dispq.asp?lid=3517284 帖子看来,写驱动似
乎是一个可行方法,呵呵:P
如果不会写驱动,那就只能靠HOOK或者注册表了,请参考:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2009830
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2466647
 
to:creation-zy
非常感谢你。。。。
写驱动那个帖子,,不太明白。。水平还达不到咯。。。
注册表的方法好像智能在win98下才可以实现吧。。。
不知道还有什么方法能够提供么??或者有源代码让我参考一下么?
 
我做过这类软件,不过我是使用驱动方式完成的.
建了一个特征码库
 
to:wr960204
谢谢你,能不能详细点?能不能给点源码给我参考一下咯。。
 
PsSetCreateProcessNotifyRoutine,所有的进程创建,微软都给了hook的接口,就是上面这个函数,这里有一个完整的驱动例子。

代码:
#include <ntddk.h>
#include <wcstr.h>
#include <stdio.h>
#include "winkernel.h"
#include "list.h"
#include "LDasm.h"

//#define DEBUG

UNICODE_STRING DeviceName;
UNICODE_STRING SymbolicLinkName;

PDEVICE_OBJECT deviceObject = NULL;

ULONG pIdOffset, ActPsLink, NameOffset, ppIdOffset, ThreadProc, WaitProcOffset;
ULONG HandleTableOffset, HandleTableListOffset, QuotaProcessOffset;

PVOID OldSyscall                      = NULL;
PVOID OldSwapContext                  = NULL;
PVOID pSwapContext                    = NULL;
PVOID OldInt2E;

PLIST_ENTRY PsActiveProcessHead       = NULL;
PLIST_ENTRY KiWaitInListHead          = NULL;
PLIST_ENTRY KiWaitOutListHead         = NULL;
PLIST_ENTRY KiDispatcherReadyListHead = NULL;
PLIST_ENTRY HandleTableListHead       = NULL;

PHANDLE_TABLE PspCidTable = NULL;

PCHAR SendMsgs;

#define MSG_BUFF_SIZE 4096

KSPIN_LOCK  LogSpinLock;

#define BASE_IOCTL (FILE_DEVICE_UNKNOWN << 16) | (FILE_READ_ACCESS << 14) | METHOD_BUFFERED

#define IOCTL_SET_SWAPCONTEXT_HOOK BASE_IOCTL | (1 << 2)
#define IOCTL_SWAPCONTEXT_UNHOOK   BASE_IOCTL | (2 << 2)
#define IOCTL_SET_SYSCALL_HOOK     BASE_IOCTL | (3 << 2)
#define IOCTL_SYSCALL_UNHOOK       BASE_IOCTL | (4 << 2)
#define IOCTL_GET_EXTEND_PSLIST    BASE_IOCTL | (5 << 2)
#define IOCTL_GET_NATIVE_PSLIST    BASE_IOCTL | (6 << 2)
#define IOCTL_GET_EPROCESS_PSLIST  BASE_IOCTL | (7 << 2)
#define IOCTL_SCAN_THREADS         BASE_IOCTL | (8 << 2)
#define IOCTL_SCAN_PSP_CID_TABLE   BASE_IOCTL | (9 << 2)
#define IOCTL_HANDLETABLES_LIST    BASE_IOCTL | (10 << 2)
#define IOCTL_GET_MESSAGES         BASE_IOCTL | (11 << 2)

#define MemOpen()  __asm cli; __asm mov eax, cr0; __asm mov oData, eax; /
                   __asm and eax, 0xFFFEFFFF; __asm mov cr0, eax;
#define MemClose() __asm mov eax, oData; __asm mov cr0, eax; __asm sti;

#pragma pack (push, 1)

typedef struct _ProcessRecord
{
	BOOLEAN     Visible;
	ULONG       SignalState;
    BOOLEAN     Present;
	ULONG       ProcessId;
	ULONG       ParrentPID;
	PEPROCESS   pEPROCESS;
	CHAR        ProcessName[256];
} TProcessRecord, *PProcessRecord;

typedef struct _WorkItemStruct
{
	PEPROCESS     pEPROCESS;
	PIO_WORKITEM  IoWorkItem;
} TWorkItemStruct, *PWorkItemStruct;

#pragma pack (pop)

PProcessList wLastItem = NULL;

typedef void (*pFn)();
typedef void (*pFnParam)(PVOID Param);

pFn      SetSyscallHook;
pFn      SyscallUnhook;
pFnParam ScanHandleTable;

PVOID GetInfoTable(ULONG ATableType)
{
	ULONG mSize = 0x4000;
	PVOID mPtr = NULL;
	NTSTATUS St;
	do
	{
		mPtr = ExAllocatePool(PagedPool, mSize);
		memset(mPtr, 0, mSize);
		if (mPtr) 
		{
			St = ZwQuerySystemInformation(ATableType, mPtr, mSize, NULL); 
		} else return NULL;
		if (St == STATUS_INFO_LENGTH_MISMATCH)
		{
			ExFreePool(mPtr);
			mSize = mSize * 2;
		}
	} while (St == STATUS_INFO_LENGTH_MISMATCH);
	if (St == STATUS_SUCCESS) return mPtr;
	ExFreePool(mPtr);
	return NULL;
}

UCHAR SaveOldFunction(PUCHAR Proc, PUCHAR Old)
{
	ULONG  Size;
	PUCHAR pOpcode;
	ULONG  Offset;
	PUCHAR oPtr;
	ULONG Result = 0;

	Offset = (ULONG)Proc - (ULONG)Old;
	oPtr = Old;
	while (Result < 5)
	{
		Size = SizeOfCode(Proc, &pOpcode);
		memcpy(oPtr, Proc, Size);
		if (IsRelativeCmd(pOpcode))	*(PULONG)((ULONG)pOpcode - (ULONG)Proc + (ULONG)oPtr + 1) += Offset;
		oPtr   += Size;
		Proc   += Size;
		Result += Size;
	}  
	*(PUCHAR)((ULONG)Old + Result) = 0xE9;
	*(PULONG)((ULONG)Old + Result + 1) = Offset - 5;
	return (UCHAR)Result;
}


PVOID HookCode(PVOID TargetProc, PVOID NewProc)
{
	ULONG Address;
	PVOID OldFunction;
	PVOID Proc = TargetProc;
	ULONG oData;

	Address = (ULONG)NewProc - (ULONG)Proc - 5;
	MemOpen();
	OldFunction = ExAllocatePool(NonPagedPool, 20);
	*(PULONG)OldFunction = (ULONG)Proc;
	*(PUCHAR)((ULONG)OldFunction + 4) = SaveOldFunction((PUCHAR)Proc, (PUCHAR)((ULONG)OldFunction + 5));
	*(PUCHAR)Proc = 0xE9;
	*(PULONG)((ULONG)Proc + 1) = Address;
	MemClose();
	return (PVOID)((ULONG)OldFunction + 5);
}


void UnhookCode(PVOID OldProc)
{
	PUCHAR Proc, pMem;
	PUCHAR pOpcode;
	ULONG  Size, ThisSize;
	ULONG  SaveSize, Offset;
	ULONG oData;

	Proc = (PUCHAR)(*(PULONG)((ULONG)OldProc - 5));
	pMem = Proc;
	SaveSize = *(PUCHAR)((ULONG)OldProc - 1);
	Offset   = (ULONG)Proc - (ULONG)OldProc;
	MemOpen();
	memcpy(Proc, OldProc, SaveSize);
	ThisSize = 0;
	while (ThisSize < SaveSize)
	{
		Size = SizeOfCode(Proc, &pOpcode);
		if (IsRelativeCmd(pOpcode)) *(PULONG)((ULONG)pOpcode + 1) -= Offset;
		Proc     += Size;
		ThisSize += Size;
	}
	MemClose();
	ExFreePool((PVOID)((ULONG)OldProc - 5));
	return;
}

PVOID GetNativeProcessList(ULONG *MemSize)
{
	ULONG PsCount = 0;
	PVOID Info = GetInfoTable(SystemProcessesAndThreadsInformation);
	PSYSTEM_PROCESSES Proc;
	PVOID Mem = NULL;
	PProcessRecord Data;

	if (!Info) return NULL; else Proc = Info;

	do 
	{
		Proc = (PSYSTEM_PROCESSES)((ULONG)Proc + Proc->NextEntryDelta);	
		PsCount++;
	} while (Proc->NextEntryDelta);

	*MemSize = (PsCount + 1) * sizeof(TProcessRecord);

	Mem = ExAllocatePool(PagedPool, *MemSize);

	if (!Mem) return NULL; else Data = Mem;
    
	Proc = Info;
	do
	{
		Proc = (PSYSTEM_PROCESSES)((ULONG)Proc + Proc->NextEntryDelta);
		wcstombs(Data->ProcessName, Proc->ProcessName.Buffer, 255);
		Data->Present    = TRUE;
		Data->ProcessId  = Proc->ProcessId;
		Data->ParrentPID = Proc->InheritedFromProcessId;
		PsLookupProcessByProcessId((HANDLE)Proc->ProcessId, &Data->pEPROCESS);
		ObDereferenceObject(Data->pEPROCESS);
		Data++;
	} while (Proc->NextEntryDelta);

	Data->Present = FALSE;

	ExFreePool(Info);

	return Mem;
}

PVOID GetEprocessProcessList(ULONG *MemSize)
{
	PLIST_ENTRY Process;
	ULONG PsCount = 0;
	PVOID Mem = NULL;
	PProcessRecord Data;

	if (!PsActiveProcessHead) return NULL;

	Process = PsActiveProcessHead->Flink;

	while (Process != PsActiveProcessHead)
	{
		PsCount++;
		Process = Process->Flink;
	}

	PsCount++;

	*MemSize = PsCount * sizeof(TProcessRecord);

	Mem = ExAllocatePool(PagedPool, *MemSize);
	memset(Mem, 0, *MemSize);

	if (!Mem) return NULL; else Data = Mem;

	Process = PsActiveProcessHead->Flink;

	while (Process != PsActiveProcessHead)
	{
		Data->Present     = TRUE;
		Data->ProcessId   = *(PULONG)((ULONG)Process - ActPsLink + pIdOffset);
		Data->ParrentPID  = *(PULONG)((ULONG)Process - ActPsLink + ppIdOffset);
		Data->SignalState = *(PULONG)((ULONG)Process - ActPsLink + 4);
		Data->pEPROCESS   = (PEPROCESS)((ULONG)Process - ActPsLink);
		strncpy(Data->ProcessName, (PVOID)((ULONG)Process - ActPsLink + NameOffset), 16);		
		Data++;
	    Process = Process->Flink;
	
	}

	return Mem;
}


void XPGetKiWaitListHead()
{
	PUCHAR cPtr, pOpcode;
	ULONG Length;

	for (cPtr = (PUCHAR)KeDelayExecutionThread; 
	     cPtr < (PUCHAR)KeDelayExecutionThread + PAGE_SIZE; 
		 cPtr += Length)
	{
		Length = SizeOfCode(cPtr, &pOpcode);

		if (!Length) break;

		if (*(PUSHORT)cPtr == 0x03C7 && *(PUSHORT)(pOpcode + 6) == 0x4389) 
		{
			KiWaitInListHead = *(PVOID *)(pOpcode + 2);
			break;
		}
	}

	return;
}

void XPGetKiDispatcherReadyListHead()
{
	PUCHAR cPtr, pOpcode;
	PUCHAR CallAddr = NULL;
	ULONG Length;

	for (cPtr = (PUCHAR)KiDispatchInterrupt; 
	     cPtr < (PUCHAR)KiDispatchInterrupt + PAGE_SIZE; 
		 cPtr += Length)
	{
		Length = SizeOfCode(cPtr, &pOpcode);

		if (!Length) return;

		if (*pOpcode == 0xE8 && *(PUSHORT)(pOpcode + 5) == 0x01B1) 
		{
			CallAddr = (PUCHAR)(*(PULONG)(pOpcode + 1) + (ULONG)cPtr + Length);
			break;
		}
	}

	if (!CallAddr || !MmIsAddressValid(CallAddr)) return;

	for (cPtr = CallAddr; cPtr < CallAddr + PAGE_SIZE; cPtr += Length)
	{
		Length = SizeOfCode(cPtr, &pOpcode);

		if (!Length) return;

		if (*(PUSHORT)pOpcode == 0x148D && *(pOpcode + 2) == 0xCD && IsRelativeCmd(pOpcode + 7))
		{
			KiDispatcherReadyListHead = *(PLIST_ENTRY *)(pOpcode + 3);
			break;
		}
	}

	return;
}


void Win2KGetKiWaitInOutListHeads()
{
	PUCHAR cPtr, pOpcode;
	ULONG Length;
	
	for (cPtr = (PUCHAR)KeWaitForSingleObject; 
	     cPtr < (PUCHAR)KeWaitForSingleObject + PAGE_SIZE; 
		 cPtr += Length) 
	{
		Length = SizeOfCode(cPtr, &pOpcode);

		if (!Length) break;
		
		if (*pOpcode == 0xB9 && *(pOpcode + 5) == 0x84 && *(pOpcode + 24) == 0xB9)
		{
			KiWaitInListHead  = *(PLIST_ENTRY *)(pOpcode + 1);
			KiWaitOutListHead = *(PLIST_ENTRY *)(pOpcode + 25);
			break;
		}
	}

	return;
}


void Win2KGetKiDispatcherReadyListHead()
{
	PUCHAR cPtr, pOpcode;
	ULONG Length;
	
	for (cPtr = (PUCHAR)KeSetAffinityThread; 
	     cPtr < (PUCHAR)KeSetAffinityThread + PAGE_SIZE; 
		 cPtr += Length) 
	{
		Length = SizeOfCode(cPtr, &pOpcode);

		if (!Length) break;		

		if (*(PUSHORT)pOpcode == 0x048D && *(pOpcode + 2) == 0xCD && *(pOpcode + 7) == 0x39)
		{
			KiDispatcherReadyListHead = *(PLIST_ENTRY *)(pOpcode + 3);
			break;
		}
	}

	return;
}

void GetSwapContextAddress()
{
	PUCHAR cPtr, pOpcode;
	ULONG Length;
	
	for (cPtr = (PUCHAR)KiDispatchInterrupt; 
	     cPtr < (PUCHAR)KiDispatchInterrupt + PAGE_SIZE; 
		 cPtr += Length) 
	{
		Length = SizeOfCode(cPtr, &pOpcode);

		if (!Length) break;		

		if (*(PUSHORT)pOpcode == 0x01B1 && *(pOpcode + 2) == 0xE8)
		{
			pSwapContext = (PVOID)(*(PULONG)(pOpcode + 3) + (ULONG)cPtr + 7);
			break;
		}
	}

	return;
}

void GetPspCidTable()
{
	PUCHAR cPtr, pOpcode;
	ULONG Length;

	for (cPtr = (PUCHAR)PsLookupProcessByProcessId; 
	     cPtr < (PUCHAR)PsLookupProcessByProcessId + PAGE_SIZE; 
		 cPtr += Length)
	{
		Length = SizeOfCode(cPtr, &pOpcode);

		if (!Length) break;

		if (*(PUSHORT)cPtr == 0x35FF && *(pOpcode + 6) == 0xE8) 
		{
			PspCidTable = **(PVOID **)(pOpcode + 2);
			break;
		}
	}
}


void GetHandleTableListHead()
{
	PSYSTEM_MODULE_INFORMATION_EX Info = GetInfoTable(SystemModuleInformation);
	ULONG NtoskrnlBase = (ULONG)Info->Modules[0].Base;
	ULONG NtoskrnlSize = Info->Modules[0].Size;
	PHANDLE_TABLE HandleTable = *(PHANDLE_TABLE *)((ULONG)PsGetCurrentProcess() + HandleTableOffset);
	PLIST_ENTRY HandleTableList = (PLIST_ENTRY)((ULONG)HandleTable + HandleTableListOffset);
	PLIST_ENTRY CurrTable;

	ExFreePool(Info);

	for (CurrTable = HandleTableList->Flink; 
	     CurrTable != HandleTableList; 
		 CurrTable = CurrTable->Flink)
	{
		if ((ULONG)CurrTable > NtoskrnlBase && (ULONG)CurrTable < NtoskrnlBase + NtoskrnlSize) 
		{
			HandleTableListHead = CurrTable;
			break;
		}
	}	
}

void _stdcall CollectProcess(PEPROCESS pEPROCESS)
{
	if (!IsAdded(wLastItem, pEPROCESS)) AddItem(&wLastItem, pEPROCESS);
	return;
}

void __stdcall ThreadCollect(PUCHAR pEthread)
{
	PEPROCESS pEprocess = *(PEPROCESS *)(pEthread + ThreadProc);
	if (pEprocess) CollectProcess(pEprocess);
	return;
}

PVOID GetHooksProcessList(ULONG *MemSize)
{
	PProcessList Item = wLastItem;
	PVOID Mem = NULL;
	PProcessRecord Data;
	ULONG PsCount = 0;

	while (Item)
	{
		PsCount++;
		Item = Item->NextItem;
	}

	Item = wLastItem;

	*MemSize = (PsCount + 1) * sizeof(TProcessRecord);

	Mem = ExAllocatePool(PagedPool, *MemSize);

	if (!Mem) return NULL; else Data = Mem;

	while (Item)
	{
		Data->Present    = TRUE;
		Data->ProcessId  = *(PULONG)((ULONG)Item->pEPROCESS + pIdOffset);
		Data->ParrentPID = *(PULONG)((ULONG)Item->pEPROCESS + ppIdOffset);
		Data->pEPROCESS  = Item->pEPROCESS;
		strncpy(Data->ProcessName, (PVOID)((ULONG)Item->pEPROCESS + NameOffset), 16);
	    Data++;
		Item = Item->NextItem;
	}
	Data->Present = FALSE;

	return Mem;
}

void ProcessListHead(PLIST_ENTRY ListHead)
{
	PLIST_ENTRY Item;

	if (ListHead)
	{
		Item = ListHead->Flink;

		while (Item != ListHead)
		{
			CollectProcess(*(PEPROCESS *)((ULONG)Item + WaitProcOffset));
			Item = Item->Flink;
		}
	}

	return;
}

void __declspec(naked) NewSyscall()
{
	__asm
	{
		pushad
		pushfd
    	push fs
	    mov di, 0x30
        mov fs, di
		mov eax, fs:[0x124]
		mov eax, [eax + 0x44]
	    push eax
		call CollectProcess
		pop fs
		popfd
		popad
		jmp OldSyscall
	}
}


void __declspec(naked) NewSwapContext()
{
	__asm 
	{
		pushad
		pushfd
    	push edi
		call ThreadCollect
		push esi
		call ThreadCollect
		popfd
		popad
		jmp OldSwapContext
	}
}

void Set2kSyscallHook()
{
	TIdt Idt;
	__asm
	{
		pushad
		cli
		sidt [Idt]
		mov esi, NewSyscall
		mov ebx, Idt.Base
		xchg [ebx + 0x170], si
		rol esi, 0x10
		xchg [ebx + 0x176], si
		ror esi, 0x10
		mov OldSyscall, esi
		sti
		popad
	}
}

void Win2kSyscallUnhook()
{
	TIdt Idt;
	__asm
	{
		pushad
		cli
		sidt [Idt]
		mov esi, OldSyscall
		mov ebx, Idt.Base
		mov [ebx + 0x170], si
		rol esi, 0x10
		mov [ebx + 0x176], si
		sti
		xor eax, eax
		mov OldSyscall, eax
		popad
	}
}

void SetXpSyscallHook()
{
	TIdt Idt;
	__asm
	{
		pushad
        mov ecx, 0x176
        rdmsr
        mov OldSyscall, eax
		mov eax, NewSyscall
		xor edx, edx
		wrmsr
		sidt [Idt]
		mov ebx, Idt.Base
		xchg [ebx + 0x170], ax
		rol eax, 0x10
		xchg [ebx + 0x176], ax
		ror eax, 0x10
		mov OldInt2E, eax
		popad
	}
}

void XpSyscallUnhook()
{
	TIdt Idt;
	__asm
	{
		pushad
		mov ecx, 0x176
		mov eax, OldSyscall
		xor edx, edx
		wrmsr
		sidt [Idt]
		mov eax, OldInt2E
		mov ebx, Idt.Base
		mov [ebx + 0x170], ax
		rol eax, 0x10
		mov [ebx + 0x176], ax
		xor eax, eax
		mov OldSyscall, eax
		popad
	}
}	
		

void WorkItemProc(PDEVICE_OBJECT DeviceObject, PWorkItemStruct Data)
{
	KeWaitForSingleObject(Data->pEPROCESS, Executive, KernelMode, FALSE, NULL);
 
	DelItem(&wLastItem, Data->pEPROCESS);

	ObDereferenceObject(Data->pEPROCESS);

	IoFreeWorkItem(Data->IoWorkItem);

	ExFreePool(Data);

	return;
}

void AddLog(PCHAR Message)
{
	KIRQL OldIrql;

	KeAcquireSpinLock(&LogSpinLock, &OldIrql);
 
	if (MSG_BUFF_SIZE - strlen(SendMsgs) > strlen(Message) + 3)
	{
		strcat(SendMsgs, Message);
		strcat(SendMsgs, "/x0D/x0A");
	}

	KeReleaseSpinLock(&LogSpinLock, OldIrql);
}

void NotifyRoutine(IN HANDLE  ParentId,
                   IN HANDLE  ProcessId,
                   IN BOOLEAN Create)
{
	PEPROCESS       process; 
	PWorkItemStruct Data;
	CHAR str[256];

	if (Create) 
	{
		PsLookupProcessByProcessId(ProcessId, &process);

		CollectProcess(process);

		sprintf(str, "Process %s created, Pid = %d, ParentPid = %d", (PVOID)((ULONG)process + NameOffset), ProcessId, ParentId);

		AddLog(str);

		ObDereferenceObject(process);

	} else
	{
		process = PsGetCurrentProcess();

		ObReferenceObject(process);

		Data = ExAllocatePool(NonPagedPool, sizeof(TWorkItemStruct));

		Data->IoWorkItem = IoAllocateWorkItem(deviceObject);
		
		Data->pEPROCESS  = process;

		sprintf(str, "Process %s terminated, Pid = %d", (PVOID)((ULONG)process + NameOffset), ProcessId);

		AddLog(str);

		IoQueueWorkItem(Data->IoWorkItem, WorkItemProc, DelayedWorkQueue, Data);
	}

	return;
}


void ProcessObject(PVOID Object)
{
	POBJECT_HEADER ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);

	if (ObjectHeader->Type == *PsProcessType) CollectProcess(Object);

	if (ObjectHeader->Type == *PsThreadType)  ThreadCollect(Object);
}

void ScanXpHandleTable(PXP_HANDLE_TABLE HandleTable)
{
	int i, j, k;
	PHANDLE_TABLE_ENTRY Entry;
	ULONG TableCode = HandleTable->TableCode & ~TABLE_LEVEL_MASK;

	switch (HandleTable->TableCode & TABLE_LEVEL_MASK)
	{
		case 0 :
     	  for (i = 0; i < 0x200; i++)
		  {
			  Entry = &((PHANDLE_TABLE_ENTRY)TableCode)[i];

			  if (Entry->Object) ProcessObject((PVOID)((ULONG)Entry->Object & ~XP_TABLE_ENTRY_LOCK_BIT));
		  }			  
		break;

		case 1 :
		  for (i = 0; i < 0x200; i++)
		  {
			  if (((PVOID *)TableCode)[i])
			  {
				  for (j = 0; j < 0x200; j++)
				  {
					  Entry = &((PHANDLE_TABLE_ENTRY *)TableCode)[i][j];

					  if (Entry->Object) ProcessObject((PVOID)((ULONG)Entry->Object & ~XP_TABLE_ENTRY_LOCK_BIT));
				  }
			  }
		  }		  
		break;

		case 2 :
		  for (i = 0; i < 0x200; i++)
		  {
			  if (((PVOID *)TableCode)[i])
			  {
				  for (j = 0; j < 0x200; j++)
				  {
					  if (((PVOID **)TableCode)[i][j])
					  {
						  for (k = 0; k < 0x200; k++)
						  {
							  Entry = &((PHANDLE_TABLE_ENTRY **)TableCode)[i][j][k];

							  if (Entry->Object) ProcessObject((PVOID)((ULONG)Entry->Object & ~XP_TABLE_ENTRY_LOCK_BIT));
						  }
					  }
				  }
			  }
		  }		 
		break;
	}
}

void ScanWin2KHandleTable(PWIN2K_HANDLE_TABLE HandleTable)
{
	int i, j, k;
	PHANDLE_TABLE_ENTRY Entry;

	for (i = 0; i < 0x100; i++)
	{
		if (HandleTable->Table[i])
		{
			for (j = 0; j < 0x100; j++)
			{
				if (HandleTable->Table[i][j])
				{
					for (k = 0; k < 0x100; k++)
					{
						Entry = &HandleTable->Table[i][j][k];

						if (Entry->Object) ProcessObject((PVOID)((ULONG)Entry->Object | WIN2K_TABLE_ENTRY_LOCK_BIT));
					}
				}
			}
		}
	}
}

void ScanHandleTablesList()
{
	PLIST_ENTRY CurrTable;
	PEPROCESS QuotaProcess;

	for (CurrTable =  HandleTableListHead->Flink;
	     CurrTable != HandleTableListHead;
		 CurrTable =  CurrTable->Flink)
	{
		QuotaProcess = *(PEPROCESS *)((PUCHAR)CurrTable - HandleTableListOffset + QuotaProcessOffset);
		if (QuotaProcess) CollectProcess(QuotaProcess);
	}
}

#ifdef DEBUG
void DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
	if (OldSwapContext) UnhookCode(OldSwapContext);

	if (OldSyscall) SyscallUnhook();
  
	PsSetCreateProcessNotifyRoutine(NotifyRoutine, TRUE);

	FreePointers(wLastItem);

	IoDeleteSymbolicLink(&SymbolicLinkName);
    IoDeleteDevice(deviceObject);

	ExFreePool(SendMsgs);
}
#endif

NTSTATUS GetServiceConsts()
{
    NTSTATUS st = STATUS_SUCCESS;
	PEPROCESS SysProc = PsGetCurrentProcess();

	switch (*NtBuildNumber)
    {
        case 2195 :  //win 2k
         pIdOffset                 = 0x09C;
		 ActPsLink                 = 0x0A0;
		 NameOffset                = 0x1FC;
         ppIdOffset                = 0x1C8;
		 ThreadProc                = 0x22C;
		 WaitProcOffset            = 0x1D0;
		 HandleTableOffset         = 0x128;
		 HandleTableListOffset     = 0x054;
		 QuotaProcessOffset        = 0x00C;
		 SetSyscallHook            = Set2kSyscallHook;
		 SyscallUnhook             = Win2kSyscallUnhook;
		 ScanHandleTable           = ScanWin2KHandleTable;
		 
		 Win2KGetKiDispatcherReadyListHead();
		 Win2KGetKiWaitInOutListHeads();	 
         break;
        
        case 2600 : //win xp
         pIdOffset                 = 0x084;
         NameOffset                = 0x174;
         ppIdOffset                = 0x14C;
		 ActPsLink                 = 0x088;
		 ThreadProc                = 0x220;
		 WaitProcOffset            = 0x1C0;
		 HandleTableOffset         = 0x0C4;
		 HandleTableListOffset     = 0x01C;
		 QuotaProcessOffset        = 0x004;
		 SetSyscallHook            = SetXpSyscallHook;
		 SyscallUnhook             = XpSyscallUnhook;
		 ScanHandleTable           = ScanXpHandleTable;
		 
		 XPGetKiWaitListHead();
		 XPGetKiDispatcherReadyListHead();
         break;
        
        default :
         st = STATUS_NOT_IMPLEMENTED;
		 break;
    }

	GetSwapContextAddress();
	GetPspCidTable();
	GetHandleTableListHead();

	PsActiveProcessHead = *(PVOID *)((PUCHAR)SysProc + ActPsLink + 4);
    return st;
}


NTSTATUS DriverIoControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
    PIO_STACK_LOCATION pisl;
    NTSTATUS ns = STATUS_UNSUCCESSFUL;
    ULONG BuffSize, DataSize;
	PVOID pBuff, pData;
	KIRQL OldIrql;
   
    pisl = IoGetCurrentIrpStackLocation (Irp);

	BuffSize = pisl->Parameters.DeviceIoControl.OutputBufferLength;

	pBuff = Irp->AssociatedIrp.SystemBuffer;

	Irp->IoStatus.Information = 0;

	switch(pisl->Parameters.DeviceIoControl.IoControlCode)
	{
		case IOCTL_SET_SWAPCONTEXT_HOOK : 
		  if (pSwapContext && !OldSwapContext) 
		  {
			  OldSwapContext = HookCode(pSwapContext, NewSwapContext);
			  ns = STATUS_SUCCESS;
		  }
		 break;

		case IOCTL_SWAPCONTEXT_UNHOOK :
		  if (OldSwapContext)
		  {
			  UnhookCode(OldSwapContext);
			  OldSwapContext = NULL;
			  ns = STATUS_SUCCESS;
		  }
		 break;

		case IOCTL_SET_SYSCALL_HOOK :
		  if (!OldSyscall)
		  {
			  SetSyscallHook(); 
			  ns = STATUS_SUCCESS;
		  }
		 break;

		case IOCTL_SYSCALL_UNHOOK :
		  if (OldSyscall)
		  {
			  SyscallUnhook();
			  ns = STATUS_SUCCESS;
		  }
		 break;

		case IOCTL_GET_EXTEND_PSLIST :
		   pData = GetHooksProcessList(&DataSize);
		   if (pData)
		   {
			   if (BuffSize >= DataSize)
			   {
				   memcpy(pBuff, pData, DataSize);
				   Irp->IoStatus.Information = DataSize;
				   ns = STATUS_SUCCESS;
			   } else ns = STATUS_INFO_LENGTH_MISMATCH;

			   ExFreePool(pData);
		   }
		 break;

		case IOCTL_GET_NATIVE_PSLIST :
		   pData = GetNativeProcessList(&DataSize);
		   if (pData)
		   {
			   if (BuffSize >= DataSize)
			   {
				   memcpy(pBuff, pData, DataSize);
				   Irp->IoStatus.Information = DataSize;
				   ns = STATUS_SUCCESS;
			   } else ns = STATUS_INFO_LENGTH_MISMATCH;

			   ExFreePool(pData);
		   }		   
		 break;

		case IOCTL_GET_EPROCESS_PSLIST :
		   pData = GetEprocessProcessList(&DataSize);
		   if (pData)
		   {
			   if (BuffSize >= DataSize)
			   {
				   memcpy(pBuff, pData, DataSize);
				   Irp->IoStatus.Information = DataSize;
				   ns = STATUS_SUCCESS;
			   } else ns = STATUS_INFO_LENGTH_MISMATCH;

			   ExFreePool(pData);
		   }
		 break;

		case IOCTL_SCAN_THREADS :
		   ProcessListHead(KiWaitInListHead);
		   ProcessListHead(KiWaitOutListHead);
		   ProcessListHead(KiDispatcherReadyListHead);
		   ns = STATUS_SUCCESS;
		 break;

		case IOCTL_SCAN_PSP_CID_TABLE :
		   if(PspCidTable) 
		   {
			   ScanHandleTable(PspCidTable);
			   ns = STATUS_SUCCESS;
		   }
		 break;

		case IOCTL_HANDLETABLES_LIST :
		   if (HandleTableListHead)
		   {
			   ScanHandleTablesList();
			   ns = STATUS_SUCCESS;
		   }
		 break;

		case IOCTL_GET_MESSAGES :
		  if (BuffSize >= MSG_BUFF_SIZE)
		  {
			  KeAcquireSpinLock(&LogSpinLock, &OldIrql);

			  strcpy(pBuff, SendMsgs);
			  memset(SendMsgs, 0, MSG_BUFF_SIZE);
			  Irp->IoStatus.Information = MSG_BUFF_SIZE;
			  ns = STATUS_SUCCESS;

			  KeReleaseSpinLock(&LogSpinLock, OldIrql);			  
		  }
		 break;
	}   

    Irp->IoStatus.Status = ns;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return ns;
}

NTSTATUS DriverCreateClose(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
    Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}



NTSTATUS DriverEntry(IN PDRIVER_OBJECT  DriverObject,
                     IN PUNICODE_STRING RegistryPath)
{
    NTSTATUS status;    
    PDRIVER_DISPATCH *ppdd;
	PCWSTR dDeviceName       = L"//Device//phunter";
	PCWSTR dSymbolicLinkName = L"//DosDevices//phunter";

	RtlInitUnicodeString(&DeviceName,       dDeviceName);
    RtlInitUnicodeString(&SymbolicLinkName, dSymbolicLinkName);

	KeInitializeSpinLock(&LogSpinLock);

    status = GetServiceConsts();

	if (!NT_SUCCESS(status)) return status;

	status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &deviceObject);
	
	if (!NT_SUCCESS(status)) return status;

	status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);

	SendMsgs = ExAllocatePool(NonPagedPool, MSG_BUFF_SIZE);

	if (!NT_SUCCESS(status) || !SendMsgs)
	{
		IoDeleteDevice(deviceObject);
		if (!SendMsgs) status = STATUS_INSUFFICIENT_RESOURCES;
		return status;
	}

	memset(SendMsgs, 0, MSG_BUFF_SIZE);	

	PsSetCreateProcessNotifyRoutine(NotifyRoutine, FALSE);	

#ifdef DEBUG
	DriverObject->DriverUnload = DriverUnload;
#endif

	ppdd = DriverObject->MajorFunction;
   
	ppdd [IRP_MJ_CREATE] =
    ppdd [IRP_MJ_CLOSE ] = DriverCreateClose;
    ppdd [IRP_MJ_DEVICE_CONTROL ] = DriverIoControl;		
	
	return status;
}
 
to:爱元元的哥哥
C语言的啊。。呵呵。。。谢谢啊!!!
 
代码:
unit ProcList;

interface

uses
 windows, advApiHook, NativeAPI, TlHelp32, UList, SysUtils;

type
  PProcessRecord = ^TProcessRecord;
  TProcessRecord = packed record
    Visible: boolean;
    SignalState: dword;
    Present: boolean;
    ProcessId: dword;
    ParrentPID: dword;
    pEPROCESS: dword;
    ProcessName: array [0..255] of Char;
  end;    


procedure GetFullProcessesInfo(var List: PListStruct);
function  OpenDriver(): boolean;
function  SetSwapcontextHook(): boolean;
function  SetSyscallHook(): boolean;
function  UnhookAll(): boolean;
function  DrvGetLogString(): string;

var
 hDriver: dword = 0;
 
implementation

uses
  Unit1;

type
 JOBOBJECTINFOCLASS  =
 (
    JobObjectBasicAccountingInformation = 1,
    JobObjectBasicLimitInformation,
    JobObjectBasicProcessIdList,
    JobObjectBasicUIRestrictions,
    JobObjectSecurityLimitInformation,
    JobObjectEndOfJobTimeInformation,
    JobObjectAssociateCompletionPortInformation,
    MaxJobObjectInfoClass
 );

 PJOBOBJECT_BASIC_PROCESS_ID_LIST = ^JOBOBJECT_BASIC_PROCESS_ID_LIST;
 JOBOBJECT_BASIC_PROCESS_ID_LIST  = packed record
    NumberOfAssignedProcesses,
    NumberOfProcessIdsInList: dword;
    ProcessIdList: array [0..0] of dword;
 end;


function QueryInformationJobObject(hJob: dword; JobObjectInfoClass: JOBOBJECTINFOCLASS;
                                   lpJobObjectInfo: pointer;
                                   bJobObjectInfoLength: dword;
                                   lpReturnLength: pdword): bool; stdcall; external 'kernel32.dll';


const
 MSG_BUFF_SIZE = 4096;
 
 BASE_IOCTL = (FILE_DEVICE_UNKNOWN shl 16) or (FILE_READ_ACCESS shl 14) or METHOD_BUFFERED;
 IOCTL_SET_SWAPCONTEXT_HOOK  = BASE_IOCTL  or (1 shl 2);
 IOCTL_SWAPCONTEXT_UNHOOK    = BASE_IOCTL  or (2 shl 2);
 IOCTL_SET_SYSCALL_HOOK      = BASE_IOCTL  or (3 shl 2);
 IOCTL_SYSCALL_UNHOOK        = BASE_IOCTL  or (4 shl 2);
 IOCTL_GET_EXTEND_PSLIST     = BASE_IOCTL  or (5 shl 2);
 IOCTL_GET_NATIVE_PSLIST     = BASE_IOCTL  or (6 shl 2);
 IOCTL_GET_EPROCESS_PSLIST   = BASE_IOCTL  or (7 shl 2);
 IOCTL_SCAN_THREADS          = BASE_IOCTL  or (8 shl 2);
 IOCTL_SCAN_PSP_CID_TABLE    = BASE_IOCTL  or (9 shl 2);
 IOCTL_HANDLETABLES_LIST     = BASE_IOCTL  or (10 shl 2);
 IOCTL_GET_MESSAGES          = BASE_IOCTL  or (11 shl 2);

var
 CsrPid: dword;
 Version: TOSVersionInfo;
 Res: boolean = false;
 IsWin2K: boolean = false;
 ZwQuerySystemInfoCall: function(ASystemInformationClass: dword;
                                 ASystemInformation: Pointer;
                                 ASystemInformationLength: dword;
                                 AReturnLength: pdword): dword; stdcall;

{
 项塍麇龛?耧桉赅 镳铞羼耦?麇疱?ToolHelp API.
}
procedure GetToolHelpProcessList(var List: PListStruct);
var
 Snap: dword;
 Process: TPROCESSENTRY32;
 NewItem: PProcessRecord;
begin
  Snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if Snap <> INVALID_HANDLE_VALUE then
     begin
      Process.dwSize := SizeOf(TPROCESSENTRY32);
      if Process32First(Snap, Process) then
         repeat
          GetMem(NewItem, SizeOf(TProcessRecord));
          ZeroMemory(NewItem, SizeOf(TProcessRecord));
          NewItem^.ProcessId  := Process.th32ProcessID;
          NewItem^.ParrentPID := Process.th32ParentProcessID;
          lstrcpy(@NewItem^.ProcessName, Process.szExeFile);
          AddItem(List, NewItem);
         until not Process32Next(Snap, Process);
      CloseHandle(Snap);
     end;
end;

{
  项塍麇龛?耧桉赅 镳铞羼耦?麇疱?ZwQuerySystemInformation.
}
procedure GetNativeProcessList(var List: PListStruct);
var
 Info: PSYSTEM_PROCESSES;
 NewItem: PProcessRecord;
 Mem: pointer;
begin
  Info := GetInfoTable(SystemProcessesAndThreadsInformation);
  Mem := Info;
  if Info = nil then Exit;
  repeat
   GetMem(NewItem, SizeOf(TProcessRecord));
   ZeroMemory(NewItem, SizeOf(TProcessRecord));
   lstrcpy(@NewItem^.ProcessName,
           PChar(WideCharToString(Info^.ProcessName.Buffer)));
   NewItem^.ProcessId  := Info^.ProcessId;
   NewItem^.ParrentPID := Info^.InheritedFromProcessId;
   AddItem(List, NewItem);
   Info := pointer(dword(info) + info^.NextEntryDelta);
  until Info^.NextEntryDelta = 0;
  VirtualFree(Mem, 0, MEM_RELEASE);
end;

{
  项塍麇龛?耧桉赅 镳铞羼耦?镱 耧桉牦 铗牮?? 觚礓腩?
  骂玮疣?弪 蝾朦觐 ProcessId.
}
procedure GetHandlesProcessList(var List: PListStruct);
var
 Info: PSYSTEM_HANDLE_INFORMATION_EX;
 NewItem: PProcessRecord;
 r: dword;
 OldPid: dword;
begin
  OldPid := 0;
  Info := GetInfoTable(SystemHandleInformation);
  if Info = nil then Exit;
  for r := 0 to Info^.NumberOfHandles do
    if Info^.Information[r].ProcessId <> OldPid then
     begin
       OldPid := Info^.Information[r].ProcessId;
       GetMem(NewItem, SizeOf(TProcessRecord));
       ZeroMemory(NewItem, SizeOf(TProcessRecord));
       NewItem^.ProcessId   := OldPid;
       AddItem(List, NewItem);
     end;
  VirtualFree(Info, 0, MEM_RELEASE);
end;

function IsPidAdded(List: PListStruct; Pid: dword): boolean;
begin
  Result := false;
  while (List <> nil) do
    begin
      if PProcessRecord(List^.pData)^.ProcessId = Pid then
        begin
          Result := true;
          Exit;
        end;
      List := List^.pNext;
    end;
end;

function IsEprocessAdded(List: PListStruct; pEPROCESS: dword): boolean;
begin
  Result := false;
  while (List <> nil) do
    begin
      if PProcessRecord(List^.pData)^.pEPROCESS = pEPROCESS then
        begin
          Result := true;
          Exit;
        end;
      List := List^.pNext;
    end;
end;

Procedure CopyListWithData(var NewList: PListStruct; List: PListStruct);
var
 NewItem: PProcessRecord;
begin
  while (List <> nil) do
    begin
      GetMem(NewItem, SizeOf(TProcessRecord));
      ZeroMemory(NewItem, SizeOf(TProcessRecord));
      NewItem^ := PProcessRecord(List^.pData)^;
      NewItem^.Visible := false;
      AddItem(NewList, NewItem);
      List := List^.pNext;
    end;
end;

function FindProcess(List: PListStruct; Pid, pEPROCESS: dword): PProcessRecord;
var
 Process: PProcessRecord;
begin
  Result := nil;
  while (List <> nil) do
    begin
      Process := List^.pData;
      if ( ((pEPROCESS <> 0) and (Process^.pEPROCESS = pEPROCESS)) or
           ((Pid <> 0) and (Process^.ProcessId = Pid)) or
           ((Pid = 0) and (pEPROCESS = 0) and (Process^.pEPROCESS = 0)
           and (Process^.ProcessId = 0))  ) then
        begin
          Result := Process;
          Exit;
        end;
      List := List^.pNext;
    end;  
end;

procedure MergeList(var List: PListStruct; List2: PListStruct);
var
 Process, Process2: PProcessRecord;
begin
  while (List2 <> nil) do
    begin
      Process := List2^.pData;
      Process2 := FindProcess(List, Process^.ProcessId, Process^.pEPROCESS);
      if Process2 = nil then AddItem(List, Process) else
        begin
         if Process2^.ProcessId   = 0  then Process2^.ProcessId   := Process^.ProcessId;
         if Process2^.pEPROCESS   = 0  then Process2^.pEPROCESS   := Process^.pEPROCESS;
         if Process2^.ParrentPID  = 0  then Process2^.ParrentPID  := Process^.ParrentPID;
         if Process2^.ProcessName = '' then Process2^.ProcessName := Process^.ProcessName;
         if Process2^.SignalState = 0  then Process2^.SignalState := Process^.SignalState;
        end;
      List2 := List2^.pNext;
    end;
end;

procedure MakeVisible(AllProc: PListStruct; CmpList: PListStruct);
var
 Process: PProcessRecord;
begin
  while (AllProc <> nil) do
    begin
      Process := AllProc^.pData;
      Process.Visible := FindProcess(CmpList, Process^.ProcessId, Process^.pEPROCESS) <> nil;
      AllProc := AllProc^.pNext;
    end;
end; 

{
  项塍麇龛?耧桉赅 镳铞羼耦?镱 耧桉牦 铌铐.
  骂玮疣?弪 蝾朦觐 ProcessId.
}
procedure GetWindowsProcessList(var List: PListStruct);

 function EnumWindowsProc(hwnd: dword; PList: PPListStruct): bool; stdcall;
 var
  ProcId: dword;
  NewItem: PProcessRecord;
 begin
  GetWindowThreadProcessId(hwnd, ProcId);
   if not IsPidAdded(PList^, ProcId) then
    begin
     GetMem(NewItem, SizeOf(TProcessRecord));
     ZeroMemory(NewItem, SizeOf(TProcessRecord));
     NewItem^.ProcessId   := ProcId;
     AddItem(PList^, NewItem);
  end;
  Result := true;
 end;

begin
 EnumWindows(@EnumWindowsProc, dword(@List));
end;


{
  谚耱屐睇?恹珙?ZwQuerySystemInformation 潆
 
C是驱动的,还有一个delphi的调用例子,这个是俄罗斯人写的代码,呵呵,凭这个你可以写个小型的杀木马软件了[:D]
 
PsSetCreateProcessNotifyRoutine是不保险的.
因为这个函数只是一个通知,这个时候进程已经创建并运行起来了.它完全可以做一些非法勾当了.
我是用驱动程序Hook了ZwCreateProcess和ZwCreateProcessEx这两个函数.里面有SectionHandle可以知道文件信息,在这个时候进行检查,如果不让运行只要返回-1就可以了.
ZwCreateProcess是Win2000用的.在XP里面只有系统进程中的前2-3个进程是用这个函数创建的,之后所有的进程都是使用ZwCreateProcessEx创建的.所以这两个函数都要接管.
 
to:wr960204
请教你得具体实现行么??谢谢
 
to wr960204:
我同意一些PsSetCreateProcessNotifyRoutine是不保险的,呵呵,我觉得ZwCreateProcess和ZwCreateProcessEx也不保险,创建进程的原始代码在PspCreateThread和pspCreateProcess函数中。

PspCreateThread的实现中,是这样调用PsSetCreateProcessNotifyRoutine设置的回调函数的:
if ( NeedToFixProcessId )
{
ExChangeHandle(PspCidTable,
Thread->Cid.UniqueProcess,
PspMarkProcessIdValid,
(ULONG_PTR)Process);

if (PspCreateProcessNotifyRoutineCount != 0)
{
ULONG i;
for (i=0; i<PSP_MAX_CREATE_PROCESS_NOTIFY; i++)
{
if (PspCreateProcessNotifyRoutine != NULL)
{
(*PspCreateProcessNotifyRoutine)( Process>InheritedFromUniqueProcessId,
Process->UniqueProcessId,
TRUE );
}
}
}

}
最后调用了 KeReadyThread,开始启动线程。不是你说的“因为这个函数只是一个通知,这个时候进程已经创建并运行起来了.它完全可以做一些非法勾当了.”。

我个人认为从文件系统过滤驱动中做这个过滤是比较保险的。
 
ZwCreateProcess和ZwCreateProcessEx是保险的.
这个时候仅仅是打开过文件并.作用就是创建进程对象.Hook他们当然是安全的了.
主线程还没有创建.如果这连个函数失败了没到主线程创建就会推出了.
我们公司以前的产品是用PsSetCreateProcessNotifyRoutine,我只几行代码就击溃它了.
看一下Windows进程创建的流程吧.
CreateProcessA/W最终调用的是CreateProcessInternalA/W
CreateProcessInternalA/W中代码是
1)打开文件(ZwCreateFile),建立内存镜像,创建Section
2)创建进程对象(ZwCreateProcess和ZwCreateProcessEx),
3)创建主线程().这个时候进程的代码才开始得到执行.
贴出Windows源代码的函数CreateProcessInternalW的部分
BOOL
STDCALL
CreateProcessInternalW(HANDLE hToken,
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation,
PHANDLE hNewToken)
{
NTSTATUS Status;
PROCESS_PRIORITY_CLASS PriorityClass;
BOOLEAN FoundQuotes = FALSE;
BOOLEAN QuotesNeeded = FALSE;
BOOLEAN CmdLineIsAppName = FALSE;
UNICODE_STRING ApplicationName;
OBJECT_ATTRIBUTES LocalObjectAttributes;
POBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hSection, hProcess, hThread;
SECTION_IMAGE_INFORMATION SectionImageInfo;
LPWSTR CurrentDirectory = NULL;
LPWSTR CurrentDirectoryPart;
PROCESS_BASIC_INFORMATION ProcessBasicInfo;
STARTUPINFOW StartupInfo;
ULONG Dummy;
LPWSTR BatchCommandLine;
ULONG CmdLineLength;
UNICODE_STRING CommandLineString;
PWCHAR Extension;
LPWSTR QuotedCmdLine = NULL;
LPWSTR ScanString;
LPWSTR NullBuffer = NULL;
LPWSTR NameBuffer = NULL;
WCHAR SaveChar = 0;
ULONG RetVal;
UINT Error = 0;
BOOLEAN SearchDone = FALSE;
BOOLEAN Escape = FALSE;
CLIENT_ID ClientId;
PPEB OurPeb = NtCurrentPeb();
PPEB RemotePeb;
SIZE_T EnvSize = 0;

DPRINT("CreateProcessW: lpApplicationName: %S lpCommandLine: %S"
" lpEnvironment: %p lpCurrentDirectory: %S dwCreationFlags: %lx/n",
lpApplicationName, lpCommandLine, lpEnvironment, lpCurrentDirectory,
dwCreationFlags);

/* Flags we don't handle yet */
if (dwCreationFlags & CREATE_SEPARATE_WOW_VDM)
{
DPRINT1("CREATE_SEPARATE_WOW_VDM not handled/n");
}
if (dwCreationFlags & CREATE_SHARED_WOW_VDM)
{
DPRINT1("CREATE_SHARED_WOW_VDM not handled/n");
}
if (dwCreationFlags & CREATE_FORCEDOS)
{
DPRINT1("CREATE_FORCEDOS not handled/n");
}

/* Fail on this flag, it's only valid with the WithLogonW function */
if (dwCreationFlags & CREATE_PRESERVE_CODE_AUTHZ_LEVEL)
{
DPRINT1("Invalid flag used/n");
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}

/* This combination is illegal (see MSDN) */
if ((dwCreationFlags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)) ==
(DETACHED_PROCESS | CREATE_NEW_CONSOLE))
{
DPRINT1("Invalid flag combo used/n");
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}

/* Another illegal combo */
if ((dwCreationFlags & (CREATE_SEPARATE_WOW_VDM | CREATE_SHARED_WOW_VDM)) ==
(CREATE_SEPARATE_WOW_VDM | CREATE_SHARED_WOW_VDM))
{
DPRINT1("Invalid flag combo used/n");
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}

/*
* We're going to modify and mask out flags and stuff in lpStartupInfo,
* so we'll use our own local copy for that.
*/
StartupInfo = *lpStartupInfo;

/* FIXME: Use default Separate/Shared VDM Flag */

/* If we are inside a Job, use Separate VDM so it won't escape the Job */
if (!(dwCreationFlags & CREATE_SEPARATE_WOW_VDM))
{
if (NtIsProcessInJob(NtCurrentProcess(), NULL))
{
/* Remove the shared flag and add the separate flag. */
dwCreationFlags = (dwCreationFlags &~ CREATE_SHARED_WOW_VDM) |
CREATE_SEPARATE_WOW_VDM;
}
}

/*
* According to some sites, ShellExecuteEx uses an undocumented flag to
* send private handle data (such as HMONITOR or HICON). See:
* www.catch22.net/tuts/undoc01.asp. This implies that we can't use the
* standard handles anymore since we'd be overwriting this private data
*/
if ((StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
(StartupInfo.dwFlags & (STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
{
StartupInfo.dwFlags &= ~STARTF_USESTDHANDLES;
}

/* Start by zeroing out the fields */
RtlZeroMemory(lpProcessInformation, sizeof(PROCESS_INFORMATION));

/* Easy stuff first, convert the process priority class */
PriorityClass.Foreground = FALSE;
PriorityClass.PriorityClass = BasepConvertPriorityClass(dwCreationFlags);

if (lpCommandLine)
{
/* Serach for escape sequences */
ScanString = lpCommandLine;
while (NULL != (ScanString = wcschr(ScanString, L'^')))
{
ScanString++;
if (*ScanString == L'/"' || *ScanString == L'^' || *ScanString == L'/"')
{
Escape = TRUE;
break;
}
}
}

/* Get the application name and do all the proper formating necessary */
GetAppName:
/* See if we have an application name (oh please let us have one!) */
if (!lpApplicationName)
{
/* The fun begins */
NameBuffer = RtlAllocateHeap(GetProcessHeap(),
0,
MAX_PATH * sizeof(WCHAR));

/* This is all we have to work with :( */
lpApplicationName = lpCommandLine;

/* Initialize our friends at the beginning */
NullBuffer = (LPWSTR)lpApplicationName;
ScanString = (LPWSTR)lpApplicationName;

/* We will start by looking for a quote */
if (*ScanString == L'/"')
{
/* That was quick */
SearchDone = TRUE;

/* Advance past quote */
ScanString++;
lpApplicationName = ScanString;

/* Find the closing quote */
while (*ScanString)
{
if (*ScanString == L'/"' && *(ScanString - 1) != L'^')
{
/* Found it */
NullBuffer = ScanString;
FoundQuotes = TRUE;
break;
}

/* Keep looking */
ScanString++;
NullBuffer = ScanString;
}
}
else
{
/* No quotes, so we'll be looking for white space */
WhiteScan:
/* Reset the pointer */
lpApplicationName = lpCommandLine;

/* Find whitespace of Tab */
while (*ScanString)
{
if (*ScanString == ' ' || *ScanString == '/t')
{
/* Found it */
NullBuffer = ScanString;
break;
}

/* Keep looking */
ScanString++;
NullBuffer = ScanString;
}
}

/* Set the Null Buffer */
SaveChar = *NullBuffer;
*NullBuffer = UNICODE_NULL;

/* Do a search for the file */
DPRINT("Ready for SearchPathW: %S/n", lpApplicationName);
RetVal = SearchPathW(NULL,
lpApplicationName,
L".exe",
MAX_PATH,
NameBuffer,
NULL) * sizeof(WCHAR);

/* Did it find something? */
if (RetVal)
{
/* Get file attributes */
ULONG Attributes = GetFileAttributesW(NameBuffer);
if (Attributes & FILE_ATTRIBUTE_DIRECTORY)
{
/* Give it a length of 0 to fail, this was a directory. */
RetVal = 0;
}
else
{
/* It's a file! */
RetVal += sizeof(WCHAR);
}
}

/* Now check if we have a file, and if the path size is OK */
if (!RetVal || RetVal >= (MAX_PATH * sizeof(WCHAR)))
{
ULONG PathType;
HANDLE hFile;

/* We failed, try to get the Path Type */
DPRINT("SearchPathW failed. Retval: %ld/n", RetVal);
PathType = RtlDetermineDosPathNameType_U(lpApplicationName);

/* If it's not relative, try to get the error */
if (PathType != RELATIVE_PATH)
{
/* This should fail, and give us a detailed LastError */
hFile = CreateFileW(lpApplicationName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

/* Did it actually NOT fail? */
if (hFile != INVALID_HANDLE_VALUE)
{
/* Fake the error */
CloseHandle(hFile);
SetLastErrorByStatus(STATUS_OBJECT_NAME_NOT_FOUND);
}
}
else
{
/* Immediately set the error */
SetLastErrorByStatus(STATUS_OBJECT_NAME_NOT_FOUND);
}

/* Did we already fail once? */
if (Error)
{
SetLastError(Error);
}
else
{
/* Not yet, cache it */
Error = GetLastError();
}

/* Put back the command line */
*NullBuffer = SaveChar;
lpApplicationName = NameBuffer;

/*
* If the search isn't done and we still have cmdline
* then start over. Ex: c:/ha ha ha/haha.exe
*/
if (*ScanString && !SearchDone)
{
/* Move in the buffer */
ScanString++;
NullBuffer = ScanString;

/* We will have to add a quote, since there is a space*/
QuotesNeeded = TRUE;

/* And we will also fake the fact we found one */
FoundQuotes = TRUE;

/* Start over */
goto WhiteScan;
}

/* We totally failed */
return FALSE;
}

/* Put back the command line */
*NullBuffer = SaveChar;
lpApplicationName = NameBuffer;
DPRINT("SearchPathW suceeded (%ld): %S/n", RetVal, NameBuffer);
}
else if (!lpCommandLine || *lpCommandLine == UNICODE_NULL)
{
/* We have an app name (good!) but no command line */
CmdLineIsAppName = TRUE;
lpCommandLine = (LPWSTR)lpApplicationName;
}

/* At this point the name has been toyed with enough to be openable */
Status = BasepMapFile(lpApplicationName, &hSection, &ApplicationName);

/* Check for failure */
if (!NT_SUCCESS(Status))
{
/* Could be a non-PE File */
switch (Status)
{
/* Check if the Kernel tells us it's not even valid MZ */
case STATUS_INVALID_IMAGE_NE_FORMAT:
case STATUS_INVALID_IMAGE_PROTECT:
case STATUS_INVALID_IMAGE_NOT_MZ:

#if 0
/* If it's a DOS app, use VDM */
if ((BasepCheckDosApp(&ApplicationName)))
{
DPRINT1("Launching VDM.../n");
RtlFreeHeap(GetProcessHeap(), 0, NameBuffer);
RtlFreeHeap(GetProcessHeap(), 0, ApplicationName.Buffer);
return CreateProcessW(L"ntvdm.exe",
(LPWSTR)lpApplicationName,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
}
#endif
/* It's a batch file */
Extension = &ApplicationName.Buffer[ApplicationName.Length /
sizeof(WCHAR) - 4];

/* Make sure the extensions are correct */
if (_wcsnicmp(Extension, L".bat", 4) && _wcsnicmp(Extension, L".cmd", 4))
{
SetLastError(ERROR_BAD_EXE_FORMAT);
return FALSE;
}

/* Calculate the length of the command line */
CmdLineLength = wcslen(CMD_STRING) + wcslen(lpCommandLine) + 1;

/* If we found quotes, then add them into the length size */
if (CmdLineIsAppName || FoundQuotes) CmdLineLength += 2;
CmdLineLength *= sizeof(WCHAR);

/* Allocate space for the new command line */
BatchCommandLine = RtlAllocateHeap(GetProcessHeap(),
0,
CmdLineLength);

/* Build it */
wcscpy(BatchCommandLine, CMD_STRING);
if (CmdLineIsAppName || FoundQuotes)
{
wcscat(BatchCommandLine, L"/"");
}
wcscat(BatchCommandLine, lpCommandLine);
if (CmdLineIsAppName || FoundQuotes)
{
wcscat(BatchCommandLine, L"/"");
}

/* Create it as a Unicode String */
RtlInitUnicodeString(&CommandLineString, BatchCommandLine);

/* Set the command line to this */
lpCommandLine = CommandLineString.Buffer;
lpApplicationName = NULL;

/* Free memory */
RtlFreeHeap(GetProcessHeap(), 0, ApplicationName.Buffer);
ApplicationName.Buffer = NULL;
goto GetAppName;
break;

case STATUS_INVALID_IMAGE_WIN_16:

/* It's a Win16 Image, use VDM */
DPRINT1("Launching VDM.../n");
RtlFreeHeap(GetProcessHeap(), 0, NameBuffer);
RtlFreeHeap(GetProcessHeap(), 0, ApplicationName.Buffer);
return CreateProcessW(L"ntvdm.exe",
(LPWSTR)lpApplicationName,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);

default:
/* Invalid Image Type */
SetLastError(ERROR_BAD_EXE_FORMAT);
return FALSE;
}
}

/* Use our desktop if we didn't get any */
if (!StartupInfo.lpDesktop)
{
StartupInfo.lpDesktop = OurPeb->ProcessParameters->DesktopInfo.Buffer;
}

/* FIXME: Check if Application is allowed to run */

/* FIXME: Allow CREATE_SEPARATE only for WOW Apps, once we have that. */

/* Get some information about the executable */
Status = ZwQuerySection(hSection,
SectionImageInformation,
&SectionImageInfo,
sizeof(SectionImageInfo),
NULL);
if(!NT_SUCCESS(Status))
{
NtClose(hSection);
DPRINT1("Unable to get SectionImageInformation, status 0x%x/n", Status);
SetLastErrorByStatus(Status);
return FALSE;
}

/* Don't execute DLLs */
if (SectionImageInfo.ImageCharacteristics & IMAGE_FILE_DLL)
{
NtClose(hSection);
DPRINT1("Can't execute a DLL/n");
SetLastError(ERROR_BAD_EXE_FORMAT);
return FALSE;
}

/* FIXME: Check for Debugger */

/* FIXME: Check if Machine Type and SubSys Version Match */

/* We don't support POSIX or anything else for now */
if (IMAGE_SUBSYSTEM_WINDOWS_GUI != SectionImageInfo.SubsystemType &&
IMAGE_SUBSYSTEM_WINDOWS_CUI != SectionImageInfo.SubsystemType)
{
NtClose(hSection);
DPRINT1("Invalid subsystem %d/n", SectionImageInfo.SubsystemType);
SetLastError(ERROR_BAD_EXE_FORMAT);
return FALSE;
}

/* Initialize the process object attributes */
ObjectAttributes = BasepConvertObjectAttributes(&LocalObjectAttributes,
lpProcessAttributes,
NULL);

/* Create the Process */
Status = NtCreateProcess(&hProcess,
PROCESS_ALL_ACCESS,
ObjectAttributes,
NtCurrentProcess(),
bInheritHandles,
hSection,
NULL,
NULL);
if(!NT_SUCCESS(Status))
{
NtClose(hSection);
DPRINT1("Unable to create process, status 0x%x/n", Status);
SetLastErrorByStatus(Status);
return FALSE;
}

/* Set new class */
Status = NtSetInformationProcess(hProcess,
ProcessPriorityClass,
&PriorityClass,
sizeof(PROCESS_PRIORITY_CLASS));
if(!NT_SUCCESS(Status))
{
NtClose(hProcess);
NtClose(hSection);
DPRINT1("Unable to set new process priority, status 0x%x/n", Status);
SetLastErrorByStatus(Status);
return FALSE;
}

/* Set Error Mode */
if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE)
{
ULONG ErrorMode = SEM_FAILCRITICALERRORS;
NtSetInformationProcess(hProcess,
ProcessDefaultHardErrorMode,
&ErrorMode,
sizeof(ULONG));
}

/* Convert the directory to a full path */
if (lpCurrentDirectory)
{
/* Allocate a buffer */
CurrentDirectory = RtlAllocateHeap(GetProcessHeap(),
0,
MAX_PATH * sizeof(WCHAR) + 2);

/* Get the length */
if (GetFullPathNameW(lpCurrentDirectory,
MAX_PATH,
CurrentDirectory,
&CurrentDirectoryPart) > MAX_PATH)
{
DPRINT1("Directory name too long/n");
SetLastError(ERROR_DIRECTORY);
return FALSE;
}
}

/* Insert quotes if needed */
if (QuotesNeeded || CmdLineIsAppName)
{
/* Allocate a buffer */
QuotedCmdLine = RtlAllocateHeap(GetProcessHeap(),
0,
(wcslen(lpCommandLine) + 2 + 1) *
sizeof(WCHAR));

/* Copy the first quote */
wcscpy(QuotedCmdLine, L"/"");

/* Save a null char */
if (QuotesNeeded)
{
SaveChar = *NullBuffer;
*NullBuffer = UNICODE_NULL;
}

/* Add the command line and the finishing quote */
wcscat(QuotedCmdLine, lpCommandLine);
wcscat(QuotedCmdLine, L"/"");

/* Add the null char */
if (QuotesNeeded)
{
*NullBuffer = SaveChar;
wcscat(QuotedCmdLine, NullBuffer);
}

DPRINT("Quoted CmdLine: %S/n", QuotedCmdLine);
}

if (Escape)
{
if (QuotedCmdLine == NULL)
{
QuotedCmdLine = RtlAllocateHeap(GetProcessHeap(),
0,
(wcslen(lpCommandLine) + 1) * sizeof(WCHAR));
wcscpy(QuotedCmdLine, lpCommandLine);
}

ScanString = QuotedCmdLine;
while (NULL != (ScanString = wcschr(ScanString, L'^')))
{
ScanString++;
if (*ScanString == L'/"' || *ScanString == L'^' || *ScanString == L'//')
{
memmove(ScanString-1, ScanString, wcslen(ScanString) * sizeof(WCHAR) + sizeof(WCHAR));
}
}
}

/* Get the Process Information */
Status = NtQueryInformationProcess(hProcess,
ProcessBasicInformation,
&ProcessBasicInfo,
sizeof(ProcessBasicInfo),
NULL);

/* Convert the environment */
if(lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
{
lpEnvironment = BasepConvertUnicodeEnvironment(&EnvSize, lpEnvironment);
if (!lpEnvironment) return FALSE;
}

/* Create Process Environment */
RemotePeb = ProcessBasicInfo.PebBaseAddress;
Status = BasepInitializeEnvironment(hProcess,
RemotePeb,
(LPWSTR)lpApplicationName,
CurrentDirectory,
(QuotesNeeded || CmdLineIsAppName || Escape) ?
QuotedCmdLine : lpCommandLine,
lpEnvironment,
EnvSize,
lpStartupInfo,
dwCreationFlags,
bInheritHandles);

/* Cleanup Environment */
if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
{
RtlDestroyEnvironment(lpEnvironment);
}

if (!NT_SUCCESS(Status))
{
DPRINT1("Could not initialize Process Environment/n");
SetLastErrorByStatus(Status);
return FALSE;
}

/* Close the section */
NtClose(hSection);
hSection = NULL;

/* Duplicate the handles if needed */
if (!bInheritHandles && !(StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
SectionImageInfo.SubsystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI)
{
PRTL_USER_PROCESS_PARAMETERS RemoteParameters;

/* Get the remote parameters */
Status = NtReadVirtualMemory(hProcess,
&RemotePeb->ProcessParameters,
&RemoteParameters,
sizeof(PVOID),
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to read memory/n");
return FALSE;
}

/* Duplicate and write the handles */
BasepDuplicateAndWriteHandle(hProcess,
OurPeb->ProcessParameters->StandardInput,
&RemoteParameters->StandardInput);
BasepDuplicateAndWriteHandle(hProcess,
OurPeb->ProcessParameters->StandardOutput,
&RemoteParameters->StandardOutput);
BasepDuplicateAndWriteHandle(hProcess,
OurPeb->ProcessParameters->StandardError,
&RemoteParameters->StandardError);
}

/* Create the first thread */
DPRINT("Creating thread for process (EntryPoint = 0x%.08x)/n",
SectionImageInfo.TransferAddress);
hThread = BasepCreateFirstThread(hProcess,
lpThreadAttributes,
&SectionImageInfo,
&ClientId);

if (hThread == NULL)
{
DPRINT1("Could not create Initial Thread/n");
return FALSE;
}


/* Notify CSRSS */
Status = BasepNotifyCsrOfCreation(dwCreationFlags,
(HANDLE)ProcessBasicInfo.UniqueProcessId,
bInheritHandles);

if (!NT_SUCCESS(Status))
{
DPRINT1("CSR Notification Failed");
SetLastErrorByStatus(Status);
return FALSE;
}

if (!(dwCreationFlags & CREATE_SUSPENDED))
{
NtResumeThread(hThread, &Dummy);
}

/* Return Data */
lpProcessInformation->dwProcessId = (DWORD)ClientId.UniqueProcess;
lpProcessInformation->dwThreadId = (DWORD)ClientId.UniqueThread;
lpProcessInformation->hProcess = hProcess;
lpProcessInformation->hThread = hThread;
DPRINT("hThread[%lx]: %lx inside hProcess[%lx]: %lx/n", hThread,
ClientId.UniqueThread, ClientId.UniqueProcess, hProcess);
hProcess = hThread = NULL;

/* De-allocate heap strings */
if (NameBuffer) RtlFreeHeap(GetProcessHeap(), 0, NameBuffer);
if (ApplicationName.Buffer)
RtlFreeHeap(GetProcessHeap(), 0, ApplicationName.Buffer);
if (CurrentDirectory) RtlFreeHeap(GetProcessHeap(), 0, CurrentDirectory);
if (QuotedCmdLine) RtlFreeHeap(GetProcessHeap(), 0, QuotedCmdLine);

/* Kill any handles still alive */
if (hSection) NtClose(hSection);
if (hThread)
{
/* We don't know any more details then this */
NtTerminateProcess(hProcess, STATUS_UNSUCCESSFUL);
NtClose(hThread);
}
if (hProcess) NtClose(hProcess);

/* Return Success */
return TRUE;
}
 
NtCreateProcess就是ZwCreateProcess在Ring3层的映射
 
[:D]要是能转化为Delphi代码就好了。
 
如果需要免费的这方面的软件,请到:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3681128
谢谢!
 
to WR960204:
呵呵,这个说法是错误的:ZwCreateProcess分别有两套,一个给ring0调用的,一个是ring3调用的,所以不能说“NtCreateProcess就是ZwCreateProcess在Ring3层的映射”。

这里是NtCreateProcess的代码,这个函数NtCreateProcess它实际上调用了PspCreateProcess,以Ps开头的函数,才是真正进程管理函数,所以你hook ZwCreateProcess根本拦截不了复杂一点的木马,进程真正的执行核心在于它的线程,一个进程只是一个壳子,这个你可以继续分析内核代码。

另外我觉得做安全产品,如果用Hook这么弱的技术,呵呵,有些过于简单了,很多国外的杀毒软件在系统启动start=0时,就备份系统函数的system table引出表,然后定时检测地址有没有被修改,Hook技术是很容易被误查为病毒的。

NTSTATUS
NtCreateProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL
)

/*++

Routine Description:

This routine creates a process object.

Arguments:

ProcessHandle - Returns the handle for the new process.

DesiredAccess - Supplies the desired access modes to the new process.

ObjectAttributes - Supplies the object attributes of the new process.
.
.
.

Return Value:

TBD

--*/

{
NTSTATUS st;

PAGED_CODE();

if ( KeGetPreviousMode() != KernelMode ) {

//
// Probe all arguments
//

try {
ProbeForWriteHandle(ProcessHandle);
} except(EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode();
}
}

if ( ARGUMENT_PRESENT(ParentProcess) ) {
st = PspCreateProcess(
ProcessHandle,
DesiredAccess,
ObjectAttributes,
ParentProcess,
InheritObjectTable,
SectionHandle,
DebugPort,
ExceptionPort
);
} else {
st = STATUS_INVALID_PARAMETER;
}

return st;
}

我建议在IFS过滤驱动里面,检测IRP_Create,如果IRP栈的Parameters.Create.SecurityContext->DesiredAccess属性为FILE_EXECUTE,则进行拦截和判断。
 
说得对,做安全仅仅用HOOK是太弱了,所以我们有文件系统配合.
这里我仅仅是就这个问题讨论.
我知道PS开头的才是更核心进程创建.
如果我在驱动里拦截了ZwCreateProcess/Ex.那么它根本都到不了调用PS开头的函数的机会.而且我说的也是进程本身是空壳主要还是线程.ZwCreateProcess就是创建进程这个空壳,而这个时候压根还没到创建线程那一步,也没有到PS开头的那些函数那一步.所以是安全的.

同理在创建主线程的时候拦截同样是安全的.
最安全的还是文件系统的拦截.
但仅仅通过文件系统还不能确认文件是否是被执行.还要根据后面的一系列动作才能知道.很麻烦.得不偿失
 
谢谢大家的热烈响应。。我的意思是比如我想禁止用户浏览网页。。。软件就禁止用户打开所有的浏览软件。。。看了大家的讨论我还是有点无从下手。。水平不高,惭愧惭愧!!
 
ok,禁止浏览,不如从封堵80,8080等http端口下手[:)]
 
后退
顶部