📄 ildriver.c
字号:
}
else
{
if ( dwNtBuildNumber == 3790 )
{
ThreadListEntryOffsetInEThread = 0x224; // Win2003
ThreadListHeadOffstInEprocess = 0x180;
}
else
{
if ( dwNtBuildNumber > 5999 ) // Vista
{
if ( dwNtBuildNumber <= 6001 )
{
ThreadListEntryOffsetInEThread = 0x248;
ThreadListHeadOffstInEprocess = 0x168;
}
}
}
}
return result;
}
ULONG IceKillThread(PKTHREAD ethread)
{
PKAPC kAPC;
PKKERNEL_ROUTINE KernelRoutine;
PKRUNDOWN_ROUTINE RundownRoutine;
PKNORMAL_ROUTINE NormalRoutine;
if ( MmIsAddressValid((PVOID)ethread) )
{
kAPC = ExAllocatePool(NonPagedPool, 0x30);
if ( ApcKernelRoutine )
{
//用原装的三个Routine
NormalRoutine = (PKNORMAL_ROUTINE)ApcNormalRoutine;
RundownRoutine = (PKRUNDOWN_ROUTINE)ApcRundownRoutine;
KernelRoutine = (PKKERNEL_ROUTINE)ApcKernelRoutine;
}
else
{
//原装的获取失败就用自己的
NormalRoutine = NULL;
RundownRoutine = NULL;
KernelRoutine = (PKKERNEL_ROUTINE)TerminateThreadApcRoutine;
}
KeInitializeApc(kAPC, ethread, 0, KernelRoutine, RundownRoutine, NormalRoutine, 0, 0);
KeInsertQueueApc(kAPC, (PVOID)kAPC, 0, 2);
}
return (ULONG)kAPC;
}
PKTHREAD IceGetNextProcessThread(PVOID eProess, PVOID eThread)
{
ULONG pThread;
PLIST_ENTRY pListEntry;
PLIST_ENTRY pListHead;
pThread = 0;
if ( eThread ) // 不为0表示不是第一次调用
pListEntry = (PLIST_ENTRY)((char *)eThread + ThreadListEntryOffsetInEThread);
else // 第一次调用时为0
pListEntry = (PLIST_ENTRY)((char*)eProess + ThreadListHeadOffstInEprocess);
pListHead = (PLIST_ENTRY)((char*)eProess + ThreadListHeadOffstInEprocess) ;
while ( pListHead != pListEntry )
{
pThread = (ULONG)pListEntry->Flink - ThreadListEntryOffsetInEThread;
if ( ObReferenceObject((PVOID)pThread))
break;
pListEntry = pListEntry->Flink;
pThread = 0;
}
if ( eThread )
ObDereferenceObject(eThread);
return (PKTHREAD)pThread;
}
void DriverUnload(PDRIVER_OBJECT pDriverObject)
{
UNICODE_STRING SymLinkString;
RtlInitUnicodeString(&SymLinkString, L"\\DosDevices\\ILDriver");
IoDeleteSymbolicLink(&SymLinkString);
UnHookSSDT();
if ( dwNtBuildNumber == 2600 || dwNtBuildNumber == 3790 )
{
UnHookPspTerminateThread();
if ( PsLookupProcessByProcessId(GetCsrssPid(), &csrssEPROCESS) >= 0 )
{
KeAttachProcess(csrssEPROCESS);
WPOFF();
if ( pKeServiceDescriptorTableShadow
&&IdNtUserFindWindowEx
&&IdNtUserGetForcegroundWindow
&&IdNtUserBuildHwndList
&&IdNtUserQueryWindow)
{
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserFindWindowEx]=oldNtUserFindWindowEx;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserQueryWindow]=oldNtUserQueryWindow;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserBuildHwndList]=oldNtUserBuildHwndList;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserGetForcegroundWindow]= oldNtUserGetForcegroundWindow;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserWindowFromPoint]= oldNtUserWindowFromPoint;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserPostThreadMessage]=oldNtUserPostThreadMessage;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserPostMessage]=oldNtUserPostMessage;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserSetParent]=oldNtUserSetParent;
}
WPON();
KeDetachProcess();
IceSleep(50);
}
else
{
DbgPrint("PsLookupProcessByProcessId() error\n");
}
}
IoDeleteDevice(pDriverObject->DeviceObject);
DbgPrint("IceLight Driver Unloaded.");
}
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, 0);
return STATUS_SUCCESS;
}
ULONG GetFakeCodeLengthForKeInsertQueueApc()
{
ULONG tmplen;
ULONG theoplen;
tmplen = 0;
g_FakeProcLen = 0;
do
{
theoplen = GetOpLen((char *)myKeInsertQueueApc + tmplen);
if ( !theoplen )
{
g_FakeProcLen = 0;
return theoplen;
}
if ( theoplen == 1 && *((BYTE *)myKeInsertQueueApc + g_FakeProcLen) == 0xCC )
break;
tmplen = theoplen + g_FakeProcLen;
g_FakeProcLen = tmplen;
}
while ( tmplen < 0x80 );
if ( tmplen >= 0x80 )
{
tmplen = 0;
g_FakeProcLen = 0;
}
if ( *((BYTE *)myKeInsertQueueApc + tmplen) != 0xCC )
g_FakeProcLen = 0;
return theoplen;
}
__declspec( naked ) void myKeInsertQueueApc(void)
{
_asm
{
mov eax,dword ptr [esp+4]
push dword ptr [eax+0x1C]
push dword ptr [eax+0x18]
push dword ptr [eax+0x14]
push dword ptr [eax+0x8]
call CheckSepcialApcRoute
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
_emit 0xCC
}
}
BOOL InlineHookKeInsertQueueApc(void)
{
char *pFnKeInsertApc;
char *pFakeProc;
int templen;
KIRQL oldIRQL;
pFakeProc=(char*)myKeInsertQueueApc;
pFnKeInsertApc = (char *)KeInsertQueueApc;
if ( g_FakeProcLen || (GetFakeCodeLengthForKeInsertQueueApc(), g_FakeProcLen) )
{
//第一次调用,只是修改KeInsertQueueApc的函数头
CheckAndHookorUnHookKeInsertQueueApc();
if ( MmIsAddressValid(pFnKeInsertApc) )
{
if ( *(WORD*)pFnKeInsertApc != 0xFF8B ) //若函数头匹配,则认为未Hook过
{
bIsKeInsertQueueApcNeverModifyed = 1; // 一个标志,表明KeInsertQueueApc是否干净(未被Hook过)
pFnKeInsertApc = (char *)KeInsertQueueApc + 2;
}
else
{
bIsKeInsertQueueApcNeverModifyed = 0;
}
g_oplen = 0;
while ( 1 )
{
templen = GetOpLen(pFnKeInsertApc + g_oplen);
if ( !templen )
break;
g_oplen += templen;
if ( g_oplen >= 5 ) //实际上,若KeInsetQueueApc是干净的,那么这里的条件是opcnt等于5
{
WPOFF();
if ( g_oplen != 5 || *pFnKeInsertApc != 0xE9 )//后一个条件成立
{
//到这里,表明函数尚未被Hook,将其函数头拷到myKeInsertQueueApc的后面
memcpy(pFakeProc + g_FakeProcLen, pFnKeInsertApc, g_oplen);//opcnt=5,拷贝五字节
}
else
{
//条件成立,则KeInsertQueueApc函数头已被Hook,因此执行拷贝工作,构造myKeInsertQueueApc
*(pFakeProc + g_FakeProcLen) = 0xE9;
*(DWORD *)(pFakeProc + g_FakeProcLen + 1) =
(DWORD)&pFnKeInsertApc[*(DWORD *)(pFnKeInsertApc + 1)- (DWORD)myKeInsertQueueApc - g_FakeProcLen];
}
//在myKeInsertQueueApc的后面构造jmp,跳回到原始的KeInsertQueueApc
*(pFakeProc + g_oplen + g_FakeProcLen) = 0xE9;
*(DWORD *)(pFakeProc + g_oplen + g_FakeProcLen + 1) = pFnKeInsertApc - pFakeProc - g_FakeProcLen - 5;
oldIRQL = KeRaiseIrqlToDpcLevel();
*pFnKeInsertApc = 0xE9;
*(DWORD *)(pFnKeInsertApc + 1) = pFakeProc - pFnKeInsertApc - 5;
KeLowerIrql(oldIRQL);
WPON();
return TRUE;
}
}
}
}
return FALSE;
}
NTSTATUS
DeviceControlProduce(
PFILE_OBJECT FileObject,
ULONG Unknow2,
PVOID SystemBuffer,
ULONG InputBufferLen,
PVOID UserBuffer,
ULONG OutputBufferLength,
ULONG ControlCode,
PIO_STATUS_BLOCK pIoStatusBlock)
{
HANDLE hFile;
PVOID NextThread;
PKTHREAD targetETHREAD;
ULONG sthEprocess;
ULONG IceEproess;
HANDLE ThreadId;
PETHREAD ethread;
PEPROCESS eProess;
HANDLE Handle;
CLIENT_ID ClientId;
OBJECT_ATTRIBUTES ObjectAttributes;
pIoStatusBlock->Status=STATUS_SUCCESS;
pIoStatusBlock->Pointer=NULL;
switch(ControlCode)
{
case 0x221804:
{
// 传入参数为IceLight.exe的pid
IceEproess = (ULONG)IceGetEprocessByPid(*(DWORD *)SystemBuffer);
StoreEPROCESS(IceEproess);
g_IcePid = (HANDLE)*(ULONG*)SystemBuffer;
break;
}
case 0x221808:
{
//传入参数为pid,尚不知何用
sthEprocess = (ULONG)IceGetEprocessByPid(*(DWORD *)SystemBuffer);
SomeThingAboutEprocess(sthEprocess);
break;
}
case 0x22180C:
{
// 强制删除文件,传入参数为文件路径
hFile = IceCreateFile(*(PCWSTR*)SystemBuffer, 0x80, 4);
if ( hFile )
{
IceForceDeleteFile(hFile);
ZwClose(hFile);
DbgPrint("Force delete file succesful.");
}
return pIoStatusBlock->Status;
}
case 0x221810:
{
//强制杀线程,传入参数为线程ID
PsLookupThreadByThreadId((PVOID)*(ULONG*)SystemBuffer, ðread);
pIoStatusBlock->Status = IceKillThread((PKTHREAD)ethread);
return pIoStatusBlock->Status;
}
case 0x221814:
{
// 传入参数为IceLight.exe的MainThread的tid,用于几个Hook函数中做比较
g_IceTid =(HANDLE)*(ULONG*)SystemBuffer;
break;
}
case 0x221818:
{
//强制杀进程,传入参数为目标进程的pid
PsLookupProcessByProcessId((PVOID)*(ULONG*)SystemBuffer, &eProess);
NextThread = 0;
while ( 1 )
{
targetETHREAD = IceGetNextProcessThread(eProess, NextThread);
if ( !targetETHREAD )
break;
IceKillThread(targetETHREAD);
NextThread = (PVOID)targetETHREAD;
}
pIoStatusBlock->Status=1;
return pIoStatusBlock->Status;
}
case 0x22181C:
{
//传入参数为Icelight自己的一个无用线程的tid,此线程存在的目的就是为了被杀
Handle = 0;
ClientId.UniqueProcess = 0;
ClientId.UniqueThread = 0;
RtlZeroMemory(&ObjectAttributes,sizeof(OBJECT_ATTRIBUTES));
ThreadId = (HANDLE)*(ULONG*)SystemBuffer;
ClientId.UniqueThread = ThreadId;
PsLookupThreadByThreadId(ThreadId, &g_IceThread);
if ( ZwOpenThread(&Handle, THREAD_ALL_ACCESS, &ObjectAttributes, &ClientId) >= 0 && Handle )
{
if ( InlineHookKeInsertQueueApc() )
{
//终止自己的一个线程,此时Hook是成功的,因此可以得到PspExitThreadApc等三个ApcRoutine
myZwTerminateThread(Handle, 0);
//这一次调用是为了UnHook KeInsertQueueApc
CheckAndHookorUnHookKeInsertQueueApc();
}
ZwClose(Handle);
}
else
{
pIoStatusBlock->Status=STATUS_SUCCESS;
}
if ( !ApcKernelRoutine )
break;
else
return pIoStatusBlock->Status;
}
case 0x221820:
{
//数据拷贝,从内核内存到用户内存,在获取SSDT时用到了
*(DWORD*)UserBuffer = **(DWORD**)SystemBuffer;
return pIoStatusBlock->Status;
}
case 0x221824:
{
//数据拷贝,从用户内存到内核内存
WPOFF();
**(DWORD**)SystemBuffer = *(DWORD*)UserBuffer;
WPON();
return 1;
}
case 0x221828:
{
//取SSDT Shadow的相关参数
if ( *(DWORD *)SystemBuffer == 1 )
{
//传入参数为1,取SSDT Shadow的基址
*(DWORD *)UserBuffer= (DWORD)(pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable);// ShadowSSDT的基址
}
else if ( *(DWORD *)SystemBuffer ==2 )
{
//传入参数为2,取SSDT Shadow中总的函数个数
*(DWORD *)UserBuffer= pKeServiceDescriptorTableShadow->SSDTShadow.TableSize;// ShdowSSDT中函数的个数
}
else
{
return pIoStatusBlock->Status;
}
// 回传给用户缓冲区
return pIoStatusBlock->Status;
}
}//end of swich
pIoStatusBlock->Status=STATUS_SUCCESS;
return pIoStatusBlock->Status;
}
NTSTATUS DispatchIoControl(PDEVICE_OBJECT pDeviceObject,PIRP pIRP)
{
NTSTATUS status;
PIO_STACK_LOCATION pCurIrpStack;
pCurIrpStack = IoGetCurrentIrpStackLocation(pIRP);
pIRP->IoStatus.Information = 0;
pIRP->IoStatus.Status = STATUS_SUCCESS;
if (pCurIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL )
status = DeviceControlProduce(
pCurIrpStack->FileObject,
1,
pIRP->AssociatedIrp.SystemBuffer,
pCurIrpStack->Parameters.DeviceIoControl.InputBufferLength,
pIRP->UserBuffer,
pCurIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
pCurIrpStack->Parameters.DeviceIoControl.IoControlCode,
&(pIRP->IoStatus)
);
IoCompleteRequest(pIRP, 0);
return pIRP->IoStatus.Status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
UNICODE_STRING DestinationString;
PDEVICE_OBJECT pDeviceObject;
UNICODE_STRING SymbolicLinkName;
PsGetVersion(0, 0, &dwNtBuildNumber, 0);
GetZwTerminateThreadAddr();
GetShdowSSDTAddr();
SetShdowSSDTFunID();
SetThreadListOffset();
pDriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoControl;
pDriverObject->DriverUnload = DriverUnload;
RtlInitUnicodeString(&DestinationString, L"\\Device\\ILDriver");
status = IoCreateDevice(pDriverObject, 0, &DestinationString, FILE_DEVICE_UNKNOWN, 0, 0, &pDeviceObject);
if (NT_SUCCESS(status))
{
RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\ILDriver");
status = IoCreateSymbolicLink(&SymbolicLinkName, &DestinationString);
if (NT_SUCCESS(status))
{
HookNtOpenProcessAndThread();
if ( dwNtBuildNumber == 2600 || dwNtBuildNumber == 3790 )
{
SetOneByteHookOnPspTerminateThreadByPointer();
if ( PsLookupProcessByProcessId(GetCsrssPid(), &csrssEPROCESS) >= 0 )
{
KeAttachProcess(csrssEPROCESS);
if ( pKeServiceDescriptorTableShadow
&& IdNtUserFindWindowEx
&& IdNtUserGetForcegroundWindow
&& IdNtUserBuildHwndList
&& IdNtUserQueryWindow
&& IdNtUserPostMessage
&& IdNtUserPostThreadMessage
&& IdNtUserSetParent
&& IdNtUserWindowFromPoint )
{
oldNtUserFindWindowEx =(pfnNtUserFindWindowEx) pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserFindWindowEx];
oldNtUserQueryWindow = (pfnNtUserQueryWindow) pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserQueryWindow];
oldNtUserBuildHwndList = (pfnNtUserBuildHwndList)pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserBuildHwndList];
oldNtUserGetForcegroundWindow =(pfnNtUserGetForegroundWindow)pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserGetForcegroundWindow];
oldNtUserWindowFromPoint = (pfnNtUserWindowFromPoint)pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserWindowFromPoint];
oldNtUserPostThreadMessage = (pfnNtUserPostThreadMessage)pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserPostThreadMessage];
oldNtUserPostMessage = (pfnNtUserPostMessage)pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserPostMessage];
oldNtUserSetParent = (pfnNtUserSetParent)pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserSetParent];
}
else
{
pKeServiceDescriptorTableShadow = 0;
}
WPOFF();
if ( pKeServiceDescriptorTableShadow
&&IdNtUserFindWindowEx
&&IdNtUserGetForcegroundWindow
&&IdNtUserBuildHwndList
&&IdNtUserQueryWindow)
{
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserFindWindowEx]=newNtUserFindWindowEx;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserQueryWindow]=newNtUserQueryWindow;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserBuildHwndList]=newNtUserBuildHwndList;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserGetForcegroundWindow]= newNtUserGetForegroundWindow;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserWindowFromPoint]= newNtUserWindowFromPoint;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserPostThreadMessage]=newNtUserPostThreadMessage;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserPostMessage]=newNtUserPostMessage;
pKeServiceDescriptorTableShadow->SSDTShadow.ServiceTable[IdNtUserSetParent]=newNtUserSetParent;
}
WPON();
KeDetachProcess();
}
else
{
DbgPrint("PsLookupProcessByProcessId() error\n");
}
}
DbgPrint("IceLight Driver Load Complete.");
status = STATUS_SUCCESS;
}
else
{
IoDeleteDevice(pDeviceObject);
}
}
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -