Windows-Rootkits/SSDT-SSSDT-Manager/EnumSSSDTManagerRing0/SSSDTManager.c
LycorisGuard eae3805066 update
update
2018-08-14 22:22:43 +08:00

598 lines
17 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef CXX_SSSDTMANAGER_H
# include "SSSDTManager.h"
#include "common.h"
#include "GetService.h"
#include "SSDT.h"
#include "SSSDT.h"
#endif
KIRQL Irql;
WIN_VERSION WinVersion = WINDOWS_UNKNOW;
ULONG_PTR SSDTDescriptor = 0;
ULONG_PTR SSSDTDescriptor = 0;
PDRIVER_OBJECT CurrentDriverObject = NULL;
PVOID SysModuleBsse = NULL;
ULONG_PTR ulSysModuleSize = 0;
PVOID SysSSDTModuleBase = NULL;
ULONG_PTR ulSSDTSysModuleSize = 0;
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryString)
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG i;
UNICODE_STRING uniDeviceName;
UNICODE_STRING uniLinkName;
PDEVICE_OBJECT DeviceObject;
RtlInitUnicodeString(&uniDeviceName,DEVICE_NAME);
RtlInitUnicodeString(&uniLinkName,LINK_NAME);
//创建设备对象;
Status = IoCreateDevice(DriverObject,0,&uniDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&DeviceObject);
if (!NT_SUCCESS(Status))
{
return Status;
}
//创建符号链接;
Status = IoCreateSymbolicLink(&uniLinkName,&uniDeviceName);
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(DeviceObject);
return Status;
}
for (i = 0; i<IRP_MJ_MAXIMUM_FUNCTION; i ++)
{
DriverObject->MajorFunction[i] = DefaultPassThrough;
}
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ControlPassThrough;
DriverObject->DriverUnload = UnloadDriver;
CurrentDriverObject = DriverObject;
WinVersion = GetWindowsVersion();
return Status;
}
NTSTATUS
DefaultPassThrough(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
ControlPassThrough(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION IrpSp;
PVOID InputBuffer = NULL;
PVOID OutputBuffer = NULL;
ULONG_PTR InputSize = 0;
ULONG_PTR OutputSize = 0;
ULONG_PTR IoControlCode = 0;
PVOID SSSDTFunctionAddress = NULL;
PVOID SSDTFunctionAddress = NULL;
WCHAR wzModuleName[30] = {0};
WCHAR wzModuleName2[60] = {0};
WCHAR wzModuleName3[60] = {0};
#ifdef _WIN64
PSYSTEM_SERVICE_TABLE64 SSSDTServiceTable = NULL;
PSYSTEM_SERVICE_TABLE64 SSDTServiceTable = NULL;
#else
PSYSTEM_SERVICE_TABLE32 SSSDTServiceTable = NULL;
PSYSTEM_SERVICE_TABLE32 SSDTServiceTable = NULL;
#endif
IrpSp = IoGetCurrentIrpStackLocation(Irp);
IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
switch(IoControlCode)
{
case IOCTL_GET_SSSDTSERVERICE://获得SSSDT表通过msr寄存器对应的标志位4c8d1d找到之后在越过32(win7)字节就是win7下的SSSDT
{ //XP找到wzKeAddSystemServiceTable的地址然后标示为8d88的位置越过16字节即为XP下的SSSDT
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
#ifdef _WIN64
SSSDTDescriptor = (ULONG_PTR)GetKeShadowServiceDescriptorTable64();
#else
SSSDTDescriptor = (ULONG_PTR)GetKeShadowServiceDescriptorTable32();
#endif
if (SSSDTDescriptor == 0)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
case IOCTL_GET_SSSDT_FUNCTIONADDRESS:
{
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (SSSDTDescriptor == 0)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
else
{
#ifdef _WIN64
SSSDTFunctionAddress = GetSSSDTFunctionAddress64(*(ULONG*)InputBuffer);
#else
SSSDTFunctionAddress = GetSSSDTFunctionAddress32(*(ULONG*)InputBuffer);
#endif
if (SSSDTFunctionAddress!=NULL)
{
memcpy(OutputBuffer, &SSSDTFunctionAddress,sizeof(PVOID));
Irp->IoStatus.Information = sizeof(PVOID);
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
else
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
}
}
case IOCTL_GET_MODULENAME: //SSSDT Current FuncAddress Of Module
{
Data2 Data = {0};
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (InputBuffer!=NULL)
{
Data.OriginalFunctionAddress = ((pData2)InputBuffer)->OriginalFunctionAddress;
//通过当前驱动对象的DriverSection里面枚举模块获得模块名称
if(GetSysModuleByLdrDataTable1((PVOID)Data.OriginalFunctionAddress,(WCHAR*)wzModuleName2)==TRUE)
{
memcpy((WCHAR*)OutputBuffer,wzModuleName2,OutputSize);
Irp->IoStatus.Information = OutputSize;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
}
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
case IOCTL_GET_SSSDT_SERVERICE_BASE://Ring3在重定向的时候需要当前模块基址和SSSDT算出偏移
{
/*
#ifdef _WIN64
SSSDTDescriptor = GetKeShadowServiceDescriptorTable64();
SSSDTServiceTable = (PSYSTEM_SERVICE_TABLE64)SSSDTDescriptor;
#else
SSSDTDescriptor = GetKeShadowServiceDescriptorTable32();
SSSDTServiceTable = (PSYSTEM_SERVICE_TABLE32)SSSDTDescriptor;
#endif
*/
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (SSSDTDescriptor == 0)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
#ifdef _WIN64
SSSDTServiceTable = (PSYSTEM_SERVICE_TABLE64)SSSDTDescriptor;
#else
SSSDTServiceTable = (PSYSTEM_SERVICE_TABLE32)SSSDTDescriptor;
#endif
memcpy(OutputBuffer,&(SSSDTServiceTable->ServiceTableBase),sizeof(PVOID));
Irp->IoStatus.Information = sizeof(PVOID);
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
case CTL_GET_SYS_MODULE_INFOR:
{
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (InputBuffer!=NULL)
{
memcpy(wzModuleName,(WCHAR*)InputBuffer,InputSize);
if(GetSysModuleByLdrDataTable((WCHAR*)wzModuleName)==TRUE)
{
DbgPrint("%x\r\n",SysModuleBsse);
memcpy((PVOID)OutputBuffer,&SysModuleBsse,sizeof(PVOID));
memcpy(((PULONG_PTR)OutputBuffer)+1,&ulSysModuleSize,sizeof(ULONG_PTR));
Irp->IoStatus.Information = sizeof(PVOID)+sizeof(ULONG_PTR);
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
}
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
case IOCTL_GET_SSSDT_CURRENT_FUNC_CODE:
{
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (SSSDTDescriptor == 0)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
else
{
#ifdef _WIN64
SSSDTFunctionAddress = GetSSSDTFunctionAddress64(*(ULONG*)InputBuffer);
#else
SSSDTFunctionAddress = GetSSSDTFunctionAddress32(*(ULONG*)InputBuffer);
#endif
if (SSSDTFunctionAddress!=NULL)
{
WPOFF();
if(SafeCopyMemory(OutputBuffer,(VOID*)SSSDTFunctionAddress,(SIZE_T)OutputSize)==FALSE)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
WPON();
break;
}
WPON();
Irp->IoStatus.Information = OutputSize;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
}
case IOCTL_RESUME_SSSDT_INLINEHOOK:
{
Data0 Data = {0};
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
Data.ulIndex = ((pData0)InputBuffer)->ulIndex;
memcpy(Data.szOriginalFunctionCode,((pData0)InputBuffer)->szOriginalFunctionCode,CODE_LENGTH);
if (SSSDTDescriptor == 0)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
ResumeSSSDTInlineHook(Data.ulIndex,Data.szOriginalFunctionCode);
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
case IOCTL_UNHOOK_SSSDT:
{
Data1 Data={0};
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
Data.Index = ((pData1)InputBuffer)->Index;
Data.OriginalAddress = ((pData1)InputBuffer)->OriginalAddress;
if (SSSDTDescriptor == 0)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
else
{
#ifdef _WIN64
UnHookSSSDTWin7(Data.Index,Data.OriginalAddress);
#else
UnHookSSSDTWinXP(Data.Index,Data.OriginalAddress);
#endif
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
break;
}
case IOCTL_GET_SSDTSERVERICE:
{
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
#ifdef _WIN64
SSDTDescriptor = (ULONG_PTR)GetKeServiceDescriptorTable64(); //获取SSDT表
#else
SSDTDescriptor = (ULONG_PTR)GetFunctionAddressByNameFromNtosExport(L"KeServiceDescriptorTable");
#endif
if (SSDTDescriptor == 0)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
case IOCTL_GET_SDT_FUNCTIONADDRESS://通过索引获得函数地址
{
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (SSDTDescriptor == 0)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
else
{
#ifdef _WIN64
//win7在SSDT基地址+4*Index里面存放着偏移偏移右移4位即是SSDT对应函数地址
SSDTFunctionAddress = GetSSDTFunctionAddress64(*(ULONG*)InputBuffer,SSDTDescriptor);
#else
//XP在SSDT基地址+4*Index里面存放的即是SSDT对应函数地址
SSDTFunctionAddress = GetSSDTFunctionAddress32(*(ULONG*)InputBuffer,SSDTDescriptor);
#endif
if (SSDTFunctionAddress!=NULL)
{
memcpy(OutputBuffer, &SSDTFunctionAddress,sizeof(PVOID));
Irp->IoStatus.Information = sizeof(PVOID);
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
else
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
}
}
case IOCTL_GET_SSDT_MODULENAME:
{
Data2 Data1 = {0};
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (InputBuffer!=NULL)
{
Data1.OriginalFunctionAddress = ((pData2)InputBuffer)->OriginalFunctionAddress;
if(GetSysModuleByLdrDataTable2((PVOID)Data1.OriginalFunctionAddress,(WCHAR*)wzModuleName3)==TRUE)
{
memcpy((WCHAR*)OutputBuffer,wzModuleName3,OutputSize);
Irp->IoStatus.Information = OutputSize;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
}
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
case IOCTL_GET_SSDT_SERVERICE_BASE:
{
#ifdef _WIN64
// SSDTDescriptor = GetKeServiceDescriptorTable64();
SSDTServiceTable = (PSYSTEM_SERVICE_TABLE64)SSDTDescriptor;
#else
// SSDTDescriptor = (ULONG_PTR)GetFunctionAddressByNameFromNtosExport(L"KeServiceDescriptorTable");
SSDTServiceTable = (PSYSTEM_SERVICE_TABLE32)SSDTDescriptor;
#endif
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (SSDTDescriptor == 0)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
memcpy(OutputBuffer,&(SSDTServiceTable->ServiceTableBase),sizeof(PVOID));
Irp->IoStatus.Information = sizeof(PVOID);
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
case CTL_GET_SSDT_SYS_MODULE_INFOR:
{
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (InputBuffer!=NULL)
{
memcpy(wzModuleName,(WCHAR*)InputBuffer,InputSize);
if(GetSysModuleByLdrDataTableSSDT((WCHAR*)wzModuleName)==TRUE)
{
memcpy((PVOID)OutputBuffer,&SysSSDTModuleBase,sizeof(PVOID));
memcpy(((PULONG_PTR)OutputBuffer)+1,&ulSSDTSysModuleSize,sizeof(ULONG_PTR));
Irp->IoStatus.Information = sizeof(PVOID)+sizeof(ULONG_PTR);
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
}
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
case IOCTL_GET_SSDT_CURRENT_FUNC_CODE:
{
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (SSDTDescriptor == 0)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
else
{
#ifdef _WIN64
SSDTFunctionAddress = GetSSDTFunctionAddress64(*(ULONG*)InputBuffer,SSDTDescriptor);
#else
SSDTFunctionAddress = GetSSDTFunctionAddress32(*(ULONG*)InputBuffer,SSDTDescriptor);
#endif
if (SSDTFunctionAddress!=NULL)
{
WPOFF();
if(SafeCopyMemory(OutputBuffer,(VOID*)SSDTFunctionAddress,(SIZE_T)OutputSize)==FALSE)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
WPON();
break;
}
WPON();
Irp->IoStatus.Information = OutputSize;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
}
case IOCTL_RESUME_SSDT_INLINEHOOK:
{
Data0 Data = {0};
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
Data.ulIndex = ((pData0)InputBuffer)->ulIndex;
memcpy(Data.szOriginalFunctionCode,((pData0)InputBuffer)->szOriginalFunctionCode,CODE_LENGTH);
if (SSDTDescriptor == 0)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
ResumeSSDTInlineHook(Data.ulIndex,Data.szOriginalFunctionCode);
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
case IOCTL_UNHOOK_SSDT:
{
Data1 Data={0};
InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
Data.Index = ((pData1)InputBuffer)->Index;
Data.OriginalAddress = ((pData1)InputBuffer)->OriginalAddress;
if (SSDTDescriptor == 0)
{
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
break;
}
else
{
UnHookSSDT(Data.Index,Data.OriginalAddress);
Irp->IoStatus.Information = 0;
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
break;
}
default:
{
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
break;
}
}
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return Status;
}
VOID
UnloadDriver(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING uniLinkName;
PDEVICE_OBJECT CurrentDeviceObject;
PDEVICE_OBJECT NextDeviceObject;
RtlInitUnicodeString(&uniLinkName,LINK_NAME);
IoDeleteSymbolicLink(&uniLinkName);
if (DriverObject->DeviceObject!=NULL)
{
CurrentDeviceObject = DriverObject->DeviceObject;
while(CurrentDeviceObject!=NULL)
{
NextDeviceObject = CurrentDeviceObject->NextDevice;
IoDeleteDevice(CurrentDeviceObject);
CurrentDeviceObject = NextDeviceObject;
}
}
DbgPrint("UnloadDriver\r\n");
}