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

📄 ildriver.c

📁 IceLight逆向出来的源代码。 有idb文件和c文件
💻 C
📖 第 1 页 / 共 4 页
字号:
  }
  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, &ethread);
			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 + -