Rootkit Tool----Kal-el 界面

from:http://blog.sina.com.cn/s/blog_61d65e360100tofn.html

Rootkit Tool----Kal-el 界面

(2011-04-04 15:40:26)
标签:

杂谈

 

Kal-el

真是好久好久没有写博客了,自从换了新公司,5个月没有再添加新的文章。最近的确相当的忙!

Kal-el是我最近一段时间编写的反Rootkit工具,当然啦,还没有完成。此软件编写的初衷完全是为了方便自己的工作,因此很多功能都是围绕着自己的需求来编写。

就个人而言,笔者比较喜欢对抗,因此一些对抗性的功能几乎做到了极致。今天是清明节小长假的第二天,稍微放松放松,于是乎就截写图来发发~~~ 也是对最近一段辛苦工作的总结和回顾。

1,先是进程管理界面:

Rootkit <wbr>Tool----Kal-el <wbr> <wbr>界面
2,内核模块界面:

Rootkit <wbr>Tool----Kal-el <wbr> <wbr>界面

3,SSDT 界面

Rootkit <wbr>Tool----Kal-el <wbr> <wbr>界面

4, IDT界面

Rootkit <wbr>Tool----Kal-el <wbr> <wbr>界面

不可否认,理论到实践这条路还是比较艰难的。驱动层,动态库,VB窗口代码都是自己个人完成,总之非常的累。不过呢,还是很有成就感滴。中途也积累了相对多的经验。

当然啦,也要感谢我们公司的强哥。谢谢他的指点。

驱动学习---Kalel 自保护源码公开

(2011-06-13 23:14:47)

KalProtect

///

好久好久没有写博客了,实在是太忙了,最近研究网络过滤,磁盘过滤还真没闲过,今天刚吃饭回来,都晚上11点半了。前几天有个朋友问我驱动级保护如何去写,我就把源码给他了,正好,我今天想起来了,也发到博客里面大家一起研究。当然,更多的也是方便初学者~~~

此驱动为进程保护驱动,比较的底层,使用的inline hook。 当然,和微点主防比起来,还不够变态!人家EAT钩子也用上了。而我就不必那么的折腾了,毕竟我写了是自己来用。

此驱动程序还是相当的完整的,不过是有依赖性的,因此编译通过后是无法加载成功!

此驱动我没有过多的讲解,遇到不懂的就百度谷歌吧,自己能够全部领悟了,也就能写出自己的自保驱动呢~~~

#include <ntddk.h>
#include <ntstrsafe.h>

#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")

#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define ININDATA data_seg("INIT")

typedef struct _SSDT_ENTRY
{
PULONG ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
PULONG ParamTableBase;
}SSDT_ENTRY;

NTSTATUS ObOpenObjectByPointer(
__in PVOID Object,
__in ULONG HandleAttributes,
__in_opt PACCESS_STATE PassedAccessState,
__in ACCESS_MASK DesiredAccess,
__in_opt POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__out PHANDLE Handle
);

#define IOCTL_KALPROTECT_PROCESS CTL_CODE(FILE_DEVICE_UNKNOWN,0x885,METHOD_BUFFERED,FILE_ANY_ACCESS) //发给SSDTSEARCH驱动 1100006驱动 来获得PsTerminateSystemThread的首地址。
#define IOCTL_FOUR CTL_CODE(FILE_DEVICE_UNKNOWN,0x844,METHOD_BUFFERED,FILE_ANY_ACCESS) //此控制码对应着SSDT设备的控制。是本驱动发给SSDT驱动的控制码。
///
#define IOCTL_ONE CTL_CODE(FILE_DEVICE_UNKNOWN,0x871,METHOD_BUFFERED,FILE_ANY_ACCESS) //用户层要求进程保护 自保护
#define IOCTL_TWO CTL_CODE(FILE_DEVICE_UNKNOWN,0x872,METHOD_BUFFERED,FILE_ANY_ACCESS) //用户层要求取消进程保护 自保护

#define IOCTL_THR CTL_CODE(FILE_DEVICE_UNKNOWN,0x873,METHOD_BUFFERED,FILE_ANY_ACCESS) //用户层要求文件保护 自保护
#define IOCTL_FOU CTL_CODE(FILE_DEVICE_UNKNOWN,0x874,METHOD_BUFFERED,FILE_ANY_ACCESS) //用户层要求取消文件保护 自保护

#define NtTerminateProcessID 0x101
#define NtOpenProcessID 0x7A //这里保护自己进程不被打开。

typedef NTSTATUS (*XXPspTerminateThreadByPointer)(PULONG,NTSTATUS); //和WRK不同的是,这个函数原本就是2个参数,而不是3个。千万注意。不然就会导致堆栈不平衡啦

KTIMER timer;
KDPC mydpc;
LARGE_INTEGER largeint;
PULONG InsertAddress;
LONG RootkitAddress;
BOOLEAN PROCESSHOOK;

PULONG OpenProcessInsertAddress;
LONG OpenProcessRootkitAddress;
BOOLEAN OPENPROCESSHOOK;

ULONG PspTerminateThreadByPointerAddressXX=NULL;

char* ProtectNameOne="Kal-el.exe";
char* ProtectNameTwo="KalelSVC1.exe";
char* ProtectNameThr="KalSVC2.exe";
char* ProtectNameFou="KalSVC3.exe";

typedef struct _device_ext //设备扩展
{
PDEVICE_OBJECT pdeviceobj; //设备对象指针
UNICODE_STRING devicename; //设备对象名
UNICODE_STRING sylinkname; //设备链接名
PULONG NativeSSDTBuffer; //将来这里缓冲区将会放入内核地址。而这些地址是从SSDT驱动获得。
ULONG NtTerminateProcessAddress;
ULONG PsTerminateSystemThreadAddress;
BOOLEAN PROCESSHOOKORNOT; //挂钩状态。 进程钩子的状态 进程保护就1个钩子 会运用DPC钩子保护技术
PULONG PsTerminateSystemThreadInsertAddress;
PULONG PsTerminateSystemThreadNativeAddressToRecover;
PULONG NtTerminateProcessInsertAddress;
PULONG NtTerminateProcessNativeAddressToRecover;

///上面一堆和防结束进程有关。现在开始防打开进程
ULONG NtOpenProcessAddress;
ULONG ObOpenObjectByPointerAddress;
BOOLEAN OPENPROCESSHOOKORNOT;

ObOpenObjectByPointer

PULONG NtOpenProcessInsertAddress;
PULONG NtOpenProcessNativeAddressToRecover;


}DEVICE_EXT,*PDEVICE_EXT;


VOID DPCFUN()
{
ULONG xxx;
_asm
{
cli
push eax;
mov eax,CR0;
mov xxx,eax;
and eax,0x0FFFEFFFF;
mov CR0,eax;
pop eax;
sti
};

if(PROCESSHOOK==TRUE)
{
*InsertAddress=(ULONG)RootkitAddress;
}
if(OPENPROCESSHOOK==TRUE)
{
*OpenProcessInsertAddress=(ULONG)OpenProcessRootkitAddress;
}
_asm
{
push eax;
mov eax,xxx;
mov CR0,eax;
pop eax;
};

KeSetTimer(&timer,largeint,&mydpc);
}


NTSTATUS
MyPspTerminateThreadByPointer(
IN PULONG Thread, //强制改变指针类型。毕竟PETHREAD结构很烦。还必须加入头什么的。之后一个套一个的结构,可以去死了
IN NTSTATUS ExitStatus
)
{
PULONG ProcessE=NULL; //本来是EPROCESS结构的
char* ProcessName;
XXPspTerminateThreadByPointer YKPspTerminateThreadByPointer;
YKPspTerminateThreadByPointer=(XXPspTerminateThreadByPointer)PspTerminateThreadByPointerAddressXX;

ProcessE=*(PULONG)((char*)Thread+0x220);
ProcessName=((char*)ProcessE+0x174);

if ((_stricmp(ProcessName, ProtectNameOne) == 0 )|| (_stricmp(ProcessName, ProtectNameTwo) == 0 )|| (_stricmp(ProcessName, ProtectNameThr) == 0) || (_stricmp(ProcessName, ProtectNameFou) == 0)) //如果为我的4个进程那么决绝访问。
{
return;
}

YKPspTerminateThreadByPointer(Thread,ExitStatus);
return ;

}

NTSTATUS MyObOpenObjectByPointer(
__in PVOID Object,
__in ULONG HandleAttributes,
__in_opt PACCESS_STATE PassedAccessState,
__in ACCESS_MASK DesiredAccess,
__in_opt POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__out PHANDLE Handle
)
{
NTSTATUS status=STATUS_SUCCESS;
char* ProcessName;
ProcessName=((char*)Object+0x174);

if ((_stricmp(ProcessName, ProtectNameOne) == 0 )|| (_stricmp(ProcessName, ProtectNameTwo) == 0 )|| (_stricmp(ProcessName, ProtectNameThr) == 0) || (_stricmp(ProcessName, ProtectNameFou) == 0)) //如果为我的4个进程那么决绝访问。
{
return STATUS_ACCESS_DENIED;
}

status=ObOpenObjectByPointer(Object,HandleAttributes,PassedAccessState,DesiredAccess,ObjectType,AccessMode,Handle);

return status;

}


_declspec(naked)RootkitNtTerminateProcess() //和PsTerminateSystemThread有关 涉及到文件的删除
{
_asm
{
push ebp;
mov ebp,esp;
sub esp,0x10;
mov ebp,MyPspTerminateThreadByPointer;
mov dword ptr [esp],ebp;
mov ebp,dword ptr [esp+10h];
ret 10h;
};

}

_declspec(naked)RootkitNtOpenProcess()
{
_asm
{
push ebp;
mov ebp,esp;
sub esp,0x10;
mov ebp,MyObOpenObjectByPointer;
mov dword ptr [esp],ebp;
mov ebp,dword ptr [esp+10h];
ret 10h;
};

}

NTSTATUS DispatchGeneral(PDEVICE_OBJECT pdevice_obj,PIRP pirp) //默认的IRP处理函数
{
NTSTATUS status;
status=STATUS_SUCCESS;
pirp->IoStatus.Status=status;
pirp->IoStatus.Information=0;
IoCompleteRequest(pirp,IO_NO_INCREMENT);
return status;

}

VOID MyUnload(PDRIVER_OBJECT pdriverobj) //卸载函数
{

PDEVICE_EXT pdeviceext;
PDEVICE_OBJECT pdeviceobj;
UNICODE_STRING sylinkname;
LONG uAttr=0;
KIRQL oldirql;

pdeviceobj=pdriverobj->DeviceObject;
pdeviceext=(PDEVICE_EXT)pdeviceobj->DeviceExtension;

KeCancelTimer(&timer);

oldirql=KeRaiseIrqlToDpcLevel();
_asm
{
cli
push eax;
mov eax,CR0;
mov uAttr,eax;
and eax,0x0FFFEFFFF;
mov CR0,eax;
pop eax;
sti
};

if(pdeviceext->PROCESSHOOKORNOT==TRUE)
{
*(pdeviceext->NtTerminateProcessInsertAddress)=(ULONG)(pdeviceext->NtTerminateProcessNativeAddressToRecover);
}
if(pdeviceext->OPENPROCESSHOOKORNOT==TRUE)
{
*(pdeviceext->NtOpenProcessInsertAddress)=(ULONG)(pdeviceext->NtOpenProcessNativeAddressToRecover);
}

_asm
{
push eax;
mov eax,uAttr;
mov CR0,eax;
pop eax;
};
KeLowerIrql(oldirql);

RtlInitUnicodeString(&sylinkname,L"\\??\\KalProtectDeviceSymLink");
if (pdeviceext->pdeviceobj)
{
IoDeleteDevice(pdeviceext->pdeviceobj); //删除设备
}

IoDeleteSymbolicLink(&sylinkname);
}

NTSTATUS MyControl(PDEVICE_OBJECT pdevice_obj,PIRP pirp)
{
NTSTATUS status=STATUS_SUCCESS;
PDEVICE_EXT pdeviceext=NULL;
ULONG i=0; //循环用的变量

UCHAR CheckPspTerminateThreadByPointer[]={0x00,0xFF,0x75,0x08,0x50,0xE8};//PsTerminateSystemThread搜索PspTerminateThreadByPointer用到的特征。第一个特征不要比对~~
UCHAR NtCheckPspTerminateThreadByPointer[]={0x00,0xFF,0x75,0x0C,0x56,0xE8};//NtTerminateProcess搜索PspTerminateThreadByPointer用到的特征。第一个特征同样不要比对~~

UCHAR NtCheckObOpenObjectByPointer[]={0x75,0xC8,0xFF,0x75,0xDC,0xE8};//NtOpenProcess搜索PspTerminateThreadByPointer用到的特征。


PULONG PsTerminateSystemThreadAddr;
PULONG NtTerminateProcessAddr;
PULONG NtOpenProcessAddr;

ULONG PsTerminateSystemThreadOffset;

ULONG NtTerminateProcessOffset;
ULONG NtTerminateProcessRootkitOffset;

ULONG NtOpenProcessOffset;
ULONG NtOpenProcessRootkitOffset;

UCHAR* PointYK=NULL;
LONG uAttr=0;
KIRQL oldirql;
BOOLEAN SearchedOrNot=FALSE;
BOOLEAN SearchedOrNotTwo=FALSE;
BOOLEAN SearchedOrNotThr=FALSE;

PIO_STACK_LOCATION stack=IoGetCurrentIrpStackLocation(pirp);
ULONG inputlength=stack->Parameters.DeviceIoControl.InputBufferLength;
ULONG outputlength=stack->Parameters.DeviceIoControl.OutputBufferLength;
ULONG ControlCode=stack->Parameters.DeviceIoControl.IoControlCode;

pdeviceext=(PDEVICE_EXT)pdevice_obj->DeviceExtension;

switch (ControlCode)
{

case IOCTL_ONE: //开始挂钩 进程保护

pdeviceext->PROCESSHOOKORNOT=FALSE;
PROCESSHOOK=FALSE;

PsTerminateSystemThreadAddr=pdeviceext->PsTerminateSystemThreadAddress; //得到 PsTerminateSystemThread的地址。
PointYK=(char*)PsTerminateSystemThreadAddr;
for (i=0;i<100;i++)
{
if (PointYK[i+1]==CheckPspTerminateThreadByPointer[1] && PointYK[i+2]==CheckPspTerminateThreadByPointer[2] && PointYK[i+3]==CheckPspTerminateThreadByPointer[3] && PointYK[i+4]==CheckPspTerminateThreadByPointer[4] && PointYK[i+5]==CheckPspTerminateThreadByPointer[5])
{
pdeviceext->PsTerminateSystemThreadInsertAddress=(PULONG)(PointYK+i+6);
pdeviceext->PsTerminateSystemThreadNativeAddressToRecover=(ULONG)*(pdeviceext->PsTerminateSystemThreadInsertAddress);
PsTerminateSystemThreadOffset=(ULONG)(pdeviceext->PsTerminateSystemThreadInsertAddress)+4;
PspTerminateThreadByPointerAddressXX=(LONG)(pdeviceext->PsTerminateSystemThreadNativeAddressToRecover)+PsTerminateSystemThreadOffset; //PspTerminateThreadByPointer 的真实地址。请重视下LONG值 千万别是ULONG 毕竟这个偏移值有正偏也会有负偏
SearchedOrNot=TRUE; //表示搜索PspTerminateThreadByPointer地址成功。
break;
}

}

if(SearchedOrNot==FALSE)// 如果搜索PspTerminateThreadByPointer地址失败,那么就直接返回
{
status=STATUS_UNSUCCESSFUL;
break;
}
以上唯一的目的就是获得PspTerminateThreadByPointer的地址。下面开始挂钩
NtTerminateProcessAddr=pdeviceext->NtTerminateProcessAddress;
PointYK=(char*)NtTerminateProcessAddr;
for (i=170;i<250;i++)
{
if (PointYK[i+1]==NtCheckPspTerminateThreadByPointer[1] && PointYK[i+2]==NtCheckPspTerminateThreadByPointer[2] && PointYK[i+3]==NtCheckPspTerminateThreadByPointer[3] && PointYK[i+4]==NtCheckPspTerminateThreadByPointer[4] && PointYK[i+5]==NtCheckPspTerminateThreadByPointer[5])
{
pdeviceext->NtTerminateProcessInsertAddress=(PULONG)(PointYK+i+6);
pdeviceext->NtTerminateProcessNativeAddressToRecover=(ULONG)*(pdeviceext->NtTerminateProcessInsertAddress);
NtTerminateProcessOffset=(ULONG)(pdeviceext->NtTerminateProcessInsertAddress)+4;
NtTerminateProcessRootkitOffset=(ULONG)RootkitNtTerminateProcess-NtTerminateProcessOffset;
InsertAddress=pdeviceext->NtTerminateProcessInsertAddress; //涉及到DPC例程,所以必须使用全局变量
RootkitAddress=NtTerminateProcessRootkitOffset; //涉及到DPC例程,所以必须使用全局变量
SearchedOrNotTwo=TRUE; //表示搜索PspTerminateThreadByPointer地址成功。
break;
}

}
if(SearchedOrNotTwo==FALSE)// 如果搜索PspTerminateThreadByPointer的插入位置失败,那么就直接返回失败
{
status=STATUS_UNSUCCESSFUL;
break;
}
上面是关于结束进程钩子的全部前期准备工具。只差挂钩这个动作了

NtOpenProcessAddr=pdeviceext->NtOpenProcessAddress;
PointYK=(char*)NtOpenProcessAddr;
for (i=500;i<600;i++)
{
if (PointYK[i]==NtCheckObOpenObjectByPointer[0] && PointYK[i+1]==NtCheckObOpenObjectByPointer[1] && PointYK[i+2]==NtCheckObOpenObjectByPointer[2] && PointYK[i+3]==NtCheckObOpenObjectByPointer[3] && PointYK[i+4]==NtCheckObOpenObjectByPointer[4] && PointYK[i+5]==NtCheckObOpenObjectByPointer[5])
{
pdeviceext->NtOpenProcessInsertAddress=(PULONG)(PointYK+i+6);
pdeviceext->NtOpenProcessNativeAddressToRecover=(ULONG)*(pdeviceext->NtOpenProcessInsertAddress);
NtOpenProcessOffset=(ULONG)(pdeviceext->NtOpenProcessInsertAddress)+4;
NtOpenProcessRootkitOffset=(ULONG)RootkitNtOpenProcess-NtOpenProcessOffset;
OpenProcessInsertAddress=pdeviceext->NtOpenProcessInsertAddress; //涉及到DPC例程,所以必须使用全局变量
OpenProcessRootkitAddress=NtOpenProcessRootkitOffset; //涉及到DPC例程,所以必须使用全局变量
SearchedOrNotThr=TRUE;
break;
}

}
if(SearchedOrNotThr==FALSE)//
{
status=STATUS_UNSUCCESSFUL;
break;
}
上面是关于打开进程钩子的全部前期准备工具。只差挂钩这个动作


oldirql=KeRaiseIrqlToDpcLevel();
_asm
{
cli
push eax;
mov eax,CR0;
mov uAttr,eax;
and eax,0x0FFFEFFFF;
mov CR0,eax;
pop eax;
sti
};

if(SearchedOrNotTwo==TRUE)
{
*(pdeviceext->NtTerminateProcessInsertAddress)=(ULONG)NtTerminateProcessRootkitOffset;
pdeviceext->PROCESSHOOKORNOT=TRUE; //这个东西是必须的。因为将来要恢复钩子。必须判断下。毕竟你挂钩失败的时候再恢复钩子,那么会导致错误的地址。导致蓝屏
PROCESSHOOK=TRUE;
}
if(SearchedOrNotThr==TRUE)
{
*(pdeviceext->NtOpenProcessInsertAddress)=(ULONG)NtOpenProcessRootkitOffset;
pdeviceext->OPENPROCESSHOOKORNOT=TRUE; //这个东西是必须的。因为将来要恢复钩子。必须判断下。毕竟你挂钩失败的时候再恢复钩子,那么会导致错误的地址。导致蓝屏
OPENPROCESSHOOK=TRUE;
}

_asm
{
push eax;
mov eax,uAttr;
mov CR0,eax;
pop eax;
};
KeLowerIrql(oldirql);

KeSetTimer(&timer,largeint,&mydpc); //使用DPC

break;

case IOCTL_TWO: //解除挂钩

KeCancelTimer(&timer); //先关闭DPC 之后再还原。

oldirql=KeRaiseIrqlToDpcLevel();
_asm
{
cli
push eax;
mov eax,CR0;
mov uAttr,eax;
and eax,0x0FFFEFFFF;
mov CR0,eax;
pop eax;
sti
};

if(pdeviceext->PROCESSHOOKORNOT==TRUE)
{
*(pdeviceext->NtTerminateProcessInsertAddress)=(ULONG)(pdeviceext->NtTerminateProcessNativeAddressToRecover);
}
if(pdeviceext->OPENPROCESSHOOKORNOT==TRUE)
{
*(pdeviceext->NtOpenProcessInsertAddress)=(ULONG)(pdeviceext->NtOpenProcessNativeAddressToRecover);
}

_asm
{
push eax;
mov eax,uAttr;
mov CR0,eax;
pop eax;
};
KeLowerIrql(oldirql);
break;

default:
status=STATUS_INVALID_VARIANT;
}
pirp->IoStatus.Status=status;
pirp->IoStatus.Information=0;
IoCompleteRequest(pirp,IO_NO_INCREMENT);
return status;

}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath)
{
NTSTATUS status=STATUS_SUCCESS;

PDEVICE_OBJECT pdeviceobj;
PDEVICE_EXT pdeviceext;
UNICODE_STRING devicename;
UNICODE_STRING sylinkname;

UNICODE_STRING TargetDeviceName; //SSDTSEARCH
HANDLE TargetDeviceHandle;
OBJECT_ATTRIBUTES TargetDeviceObjectAttribute; //SSDTSEARCH
ULONG i;
char* PointYK;
IO_STATUS_BLOCK status_block;

__declspec(dllimport) SSDT_ENTRY KeServiceDescriptorTable;

largeint.QuadPart=-50000;
KeInitializeDpc(&mydpc,(PKDEFERRED_ROUTINE)DPCFUN,NULL);
KeInitializeTimer(&timer);

RtlInitUnicodeString(&devicename,L"\\Device\\KalProtectDevice");
RtlInitUnicodeString(&sylinkname,L"\\??\\KalProtectDeviceSymLink");
RtlInitUnicodeString(&TargetDeviceName,L"\\Device\\SSDTSearchDevice"); //我们这个驱动将会打开SSDT驱动的SSDTSearchDevice设备。来获取SSDT表的所有内容.
InitializeObjectAttributes(&TargetDeviceObjectAttribute,&TargetDeviceName,OBJ_CASE_INSENSITIVE,NULL,NULL);

pDriverObject->DriverUnload=MyUnload;
//
for (i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
{
pDriverObject->MajorFunction[i]=DispatchGeneral;
}
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=MyControl; //注册控制函数。不管设备有多少,控制函数就一个。所以到时候需要判断。


status=IoCreateDevice(pDriverObject,sizeof(DEVICE_EXT),&devicename,FILE_DEVICE_UNKNOWN,0,FALSE,&pdeviceobj); //开始创建设备 为独占设备。 只有VB会控制这个设备
if (!NT_SUCCESS(status))
{
return status;
}

status=IoCreateSymbolicLink(&sylinkname,&devicename);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(pdeviceobj);
return status;
}

pdeviceobj->Flags |= DO_BUFFERED_IO; //我这个设备支持缓冲区方式。
pdeviceext=(PDEVICE_EXT)pdeviceobj->DeviceExtension;
pdeviceext->pdeviceobj=pdeviceobj;
pdeviceext->devicename=devicename;
pdeviceext->sylinkname=sylinkname;
pdeviceext->PsTerminateSystemThreadAddress=NULL; //先赋值为NULL 也就是32位的0

pdeviceext->NativeSSDTBuffer=(PULONG)ExAllocatePool(PagedPool,KeServiceDescriptorTable.NumberOfService*4); //划分一个SSDT表一样大的空间。

status=ZwCreateFile(&TargetDeviceHandle,GENERIC_ALL,&TargetDeviceObjectAttribute,&status_block,NULL,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ,FILE_OPEN,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0);//打开SSDT 设备。
if (!NT_SUCCESS(status)) //如果打开失败,那么返回失败。同时让驱动加载失败。
{
return STATUS_UNSUCCESSFUL;
}
///现在开始发送控制码给SSDT 来获得PsTerminateSystemThread地址
status=ZwDeviceIoControlFile(TargetDeviceHandle,NULL,NULL,NULL,&status_block,IOCTL_KALPROTECT_PROCESS,NULL,0,&(pdeviceext->PsTerminateSystemThreadAddress),sizeof(ULONG)); //如果成功,那么获得PsTerminateSystemThread的地址。
if (!NT_SUCCESS(status)) //如果控制失败,那么返回失败。同时让驱动加载失败。
{
ZwClose(TargetDeviceHandle);
return STATUS_UNSUCCESSFUL;
}

status=ZwDeviceIoControlFile(TargetDeviceHandle,NULL,NULL,NULL,&status_block,IOCTL_FOUR,NULL,0,pdeviceext->NativeSSDTBuffer,KeServiceDescriptorTable.NumberOfService*4); //如果成功,那么原始的SSDT表将会成功获取。
if (!NT_SUCCESS(status)) //如果控制失败,那么返回失败。同时让驱动加载失败。
{
ZwClose(TargetDeviceHandle);
return STATUS_UNSUCCESSFUL;
}

ZwClose(TargetDeviceHandle); //需要的东西已经获得。句柄可以关闭了

if (pdeviceext->PsTerminateSystemThreadAddress==NULL) //如果获得的地址为空,也就是说获取失败,那么返回为失败。
{
status=STATUS_UNSUCCESSFUL;

}
pdeviceext->NtTerminateProcessAddress=(pdeviceext->NativeSSDTBuffer)[NtTerminateProcessID];
pdeviceext->NtOpenProcessAddress=(pdeviceext->NativeSSDTBuffer)[NtOpenProcessID];

if (pdeviceext->NtTerminateProcessAddress==NULL || pdeviceext->NtOpenProcessAddress==NULL ) //如果获得的地址为空,也就是说获取失败,那么返回为失败。
{
status=STATUS_UNSUCCESSFUL;

}
return status;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值