查看SSDTHOOK其修改

#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
typedef unsigned long DWORD;
typedef unsigned long *PDWORD;
typedef unsigned short WORD;
typedef unsigned char BYTE;

typedef struct _MOUDULE_INFO {
DWORD d_Reserved1;
DWORD d_Reserved2;
PVOID p_Base; //基地址
DWORD d_Size; //大小
DWORD d_Flags;
WORD w_Index;
WORD w_Rank;
WORD w_LoadCount;
WORD w_NameOffset;//名字偏移
BYTE a_bPath[MAXIMUM_FILENAME_LENGTH];//保存模块路径

} MODULE_INFO, *PMODULE_INFO, **PPMODULE_INFO;
typedef struct _MODULE_LIST
{
int   d_Modules;
MODULE_INFO a_Modules[];
} MODULE_LIST, *PMODULE_LIST, **PPMODULE_LIST;

typedef struct _NTOSKRNL {
DWORD Base;
DWORD End;
} NTOSKRNL, *PNTOSKRNL;

#define SystemModuleInformation 11
/***************************************
声明全局变量PMODULE_LIST g_pml;
NTOSKRNL g_noskrnl;
***************************************/
PMODULE_LIST g_pml;
NTOSKRNL g_noskrnl;

#pragma pack(1)

typedef struct ServiceDescriptorEntry
{
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

PServiceDescriptorTableEntry_t KeServiceDescriptorTableShadow = NULL;

typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT pDevice;
UNICODE_STRING ustrDeviceName; //设备名称
UNICODE_STRING ustrSymLinkName; //符号链接名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;


PMDL g_pmdlSystemCall;
PVOID *MappedSystemCallTable;
int *g_aSSDT;
NTSYSAPI
NTSTATUS
NTAPI ZwQuerySystemInformation(
          IN ULONG SystemInformationClass,
          IN PVOID SystemInformation,
          IN ULONG SystemInformationLength,
                        OUT PULONG ReturnLength);
typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
            ULONG SystemInformationCLass,
            PVOID SystemInformation,
            ULONG SystemInformationLength,
            PULONG ReturnLength
            );

ZWQUERYSYSTEMINFORMATION        NtQuerySystemInformation;

NTKERNELAPI
NTSTATUS
KeAddSystemServiceTable(
       IN PULONG Base,
       IN PULONG Count OPTIONAL,
       IN ULONG Limit,
       IN PUCHAR Number,
       IN ULONG Index
);
NTSTATUS DispathCreateClose(PDEVICE_OBJECT pDevObj,PIRP pIrp);
NTSTATUS CreateDevice (
        IN PDRIVER_OBJECT pDriverObject);

VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);

NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);

/*************************************************
*函数名称:GetListOfModules
*功能:分配内存,取得指向内核模块的指针
*返回:指向(MODULE_LIST)指针
***********************************************/
PMODULE_LIST GetListOfModules(PNTSTATUS pns)
{
ULONG ul_Size;
ULONG *pul_MListAddr = NULL;
NTSTATUS ns;
PMODULE_LIST pml = NULL;

//先获取所需的缓冲区大小
DbgPrint("Begin to GetModuleList!\n");
NtQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)SYSTEMSERVICE(ZwQuerySystemInformation);
NtQuerySystemInformation(SystemModuleInformation,
        &ul_Size,
        0,
        &ul_Size);
//分配内存
pul_MListAddr = (ULONG *)ExAllocatePool(PagedPool,ul_Size);
if(!pul_MListAddr)
{
   DbgPrint("pul_MListAddr NULL!\n");
   if(pns != NULL)
    *pns = STATUS_INSUFFICIENT_RESOURCES;
   return (PMODULE_LIST)pul_MListAddr;
}

ns = NtQuerySystemInformation(SystemModuleInformation,
          pul_MListAddr,
          ul_Size,
          0);
//判断是否失败
if(ns != STATUS_SUCCESS)
{
   DbgPrint("NtQuerySystemInformation Failes!\n");
   //释放分配的内存
   ExFreePool((PVOID)pul_MListAddr);
   if(pns != NULL)
    *pns = ns;
   return NULL;

}

pml = (PMODULE_LIST)pul_MListAddr;
if(pns != NULL)
   *pns = ns;
DbgPrint("NtQuerySystemInformation SucessFul!\n");
return pml;
}
/**************************************************************
*函数名:GetntoskrnlBase
*功能:通过搜索内核模块找到ntoskrl.exe,取得其开始地址其结尾地址
*报存在全局变量结构中
*参数:模块名称

**************************************************************/
NTSTATUS GetntoskrnlBase(char *szModuleName)
{
int count;

NTSTATUS pns;
g_pml = NULL;
g_noskrnl.Base = 0;
g_noskrnl.End = 0;

g_pml = GetListOfModules(&pns);
if(!NT_SUCCESS(pns))
{
   DbgPrint("获取内核模块有误!\n");
   return pns;
}
if(!g_pml)
{
   DbgPrint("g_pml = GetListOfModules(&pns)Failes!\n");
   return STATUS_UNSUCCESSFUL;
}
for(count = 0; count < g_pml->d_Modules; count++)
{
   DbgPrint("%s\n",g_pml->a_Modules[count].a_bPath+g_pml->a_Modules[count].w_NameOffset);
   //查找noskrnl.exe
   //模块名称==模块路径指针+ 名字偏移
   if(_stricmp(szModuleName,g_pml->a_Modules[count].a_bPath +
    g_pml->a_Modules[count].w_NameOffset) == 0)
   {
    g_noskrnl.Base = (DWORD)(g_pml->a_Modules[count].p_Base);
    g_noskrnl.End = ((DWORD)g_pml->a_Modules[count].p_Base +
     g_pml->a_Modules[count].d_Size);
    DbgPrint("找到内核地址%08x,END:%08x\n",g_noskrnl.Base,g_noskrnl.End);
    break;
   }
}
ExFreePool(g_pml);
if(g_noskrnl.Base != 0)
{
   return STATUS_SUCCESS;
   DbgPrint("成功取得地址!\n");
}
else
{
   DbgPrint("取地址fail!\n");
   return STATUS_UNSUCCESSFUL;
}
}

/****************************************************************
*函数名称:void CheckSSDTHooks(PServiceDescriptorTableEntry_t pTable)
*功能查找:SSDT表中的被HOOK的地址也可以用于查找SHADOWSSDT表中的HOOK
*参数:SSDT
*******************************************************************/
void CheckSSDTHooks(PServiceDescriptorTableEntry_t pKeServiceDescriptorTable)
{

unsigned int i;
DbgPrint("begin to check!Base:%08xEnd:%08x\n",g_noskrnl.Base,g_noskrnl.End);
for(i = 0; i< pKeServiceDescriptorTable->NumberOfServices; i++)
{
   g_aSSDT[i] = pKeServiceDescriptorTable->ServiceTableBase[i];
   if(((DWORD)pKeServiceDescriptorTable->ServiceTableBase[i] < g_noskrnl.Base) ||
    ((DWORD)pKeServiceDescriptorTable->ServiceTableBase[i] > g_noskrnl.End))
   {
    DbgPrint("System Call is %x hooked at addr %08x!\n",i,
     pKeServiceDescriptorTable->ServiceTableBase[i]);
   }
}
}
/********************************************************************
*函数名称:RepairSSDTHook()
*功能:和保存在全局数组中的地址比较 如果不相等
进入HOOK地址中JMP回到原来没有HOOK的地址
*
***********************************************************************/
void RepairSSDTHook(PServiceDescriptorTableEntry_t pKeServiceDescriptorTable)
{
unsigned int i;
unsigned int uOffset;
char *pFtion;
unsigned long ul_Fution;
for(i=0; i<pKeServiceDescriptorTable->NumberOfServices; i++)
{
   if(g_aSSDT[i] != (DWORD)pKeServiceDescriptorTable->ServiceTableBase[i])
   {
    DbgPrint("地址%08x已经改变\n",pKeServiceDescriptorTable[i]);
    ul_Fution = pKeServiceDescriptorTable->ServiceTableBase[i];
    uOffset = (DWORD)pKeServiceDescriptorTable->ServiceTableBase[i] - g_aSSDT[i] - 5;

    _asm
    {
      CLI //dissable interrupt
      MOV EAX, CR0 //move CR0 register into EAX
      AND EAX, NOT 10000H //disable WP bit
      MOV CR0, EAX //write register back
    }
    *( (char *)(&((unsigned char *)ul_Fution)[0]) )=0xe9;
    *( (unsigned long *)(&((unsigned char *)ul_Fution)[1]) ) = uOffset;
    _asm
    {
     MOV EAX, CR0 //move CR0 register into EAX
      OR EAX, 10000H //enable WP bit
      MOV CR0, EAX //write register back
      STI //enable interrupt
    }

   }

}
}
VOID GetSSDTShadowBase()
{
__try
{
   UCHAR *cPtr;
   UCHAR *pOpcode;
   ULONG Length;
   for (cPtr = (PUCHAR)KeAddSystemServiceTable;
   cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
   cPtr += Length)
        {
    Length = SizeOfCode(cPtr, &pOpcode);
   
    if (!Length) break;
   
    if ( *(PUSHORT)cPtr == 0x888D )
    {
     KeServiceDescriptorTableShadow = (PServiceDescriptorTableEntry_t)(*(ULONG *)((ULONG)pOpcode + 2));
     break;
    }
   }
} __except(EXCEPTION_EXECUTE_HANDLER)
{
   DbgPrint("GetSSDTShadowBase : Raised exception 0x%X.\n", GetExceptionCode());
}
}
/***********************************************************
*函数名称DbgPrintTheSSDTAndShowSSDT()
*函数功能:打印SSDT表和SSDTSHOW表的地址
*
***********************************************************/
NTSTATUS DbgPrintTheSSDTAndShowSSDT()
{
int i,n;
PVOID pShadowSSDT=NULL;
GetSSDTShadowBase();
if(!KeServiceDescriptorTableShadow)
   return STATUS_UNSUCCESSFUL;
/* g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTableShadow[1].Base,
          KeServiceDescriptorTableShadow[1].Limit*4);
if(!g_pmdlSystemCall)
    return STATUS_UNSUCCESSFUL;
MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
   
/*    // Change the flags of the MDL
g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
   
   MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);
   */
DbgPrint("the system_table:%08x\n",KeServiceDescriptorTableShadow);
DbgPrint("the KeServiceDescriptorTable:%08x\n",KeServiceDescriptorTable.ServiceTableBase);

DbgPrint("the system_table of keservicedecriptortable :%08x\n",KeServiceDescriptorTableShadow[1].ServiceTableBase);
n = (int)KeServiceDescriptorTableShadow[1].NumberOfServices;
__try{
pShadowSSDT = (PVOID)KeServiceDescriptorTableShadow[1].ServiceTableBase;
if(!*((ULONG *)pShadowSSDT))
{
  
   return STATUS_UNSUCCESSFUL;
}
i = 0;
    while(i<n)
{
DbgPrint("%x----------%08x\n",i,KeServiceDescriptorTableShadow[1].ServiceTableBase[i]);
i++;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
   DbgPrint("GetSSDTShadowBase : Raised exception 0x%X.\n", GetExceptionCode());
}
//KeServiceDescriptorTableShadow = system_descriptor_table->win32k.ServiceTableBase;
//DbgPrint("the KeServiceDescriptorTableShadow:%08x",MappedSystemCallTable[0]);
//DbgPrint("&MeppedSystemCallTable[]:%08x\n",&MappedSystemCallTable[0]);
//if(MappedSystemCallTable[1] != NULL)
// DbgPrint("the next is:%08x\n",MappedSystemCallTable[1]);

// DbgPrint("the NumberOfKeServiceDescriptorTableShadow:%x\n",
//   KeServiceDescriptorTableShadow[1].Limit);
// n = KeServiceDescriptorTableShadow[1].Limit;

//for(i=0; i <= n; i++)
// DbgPrint("%x----------->%08x\n",i,KeServiceDescriptorTableShadow.ServiceTableBase[i]);
return STATUS_SUCCESS;
}
/
NTSTATUS RootkitUnload(IN PDRIVER_OBJECT DriverObject)
{
DbgPrint("RootkitUnload");
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(
      IN PDRIVER_OBJECT DriverObject,
      IN PUNICODE_STRING RegistryPath
      )
{
NTSTATUS status=STATUS_SUCCESS;
DbgPrint("DriverEntry Load!\n");
DriverObject->DriverUnload = HelloDDKUnload;
DriverObject->MajorFunction[IRP_MJ_CREATE] =DispathCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispathCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;

//创建驱动设备对象
status = CreateDevice(DriverObject);
g_aSSDT = (int *)ExAllocatePool(PagedPool,0x11c * sizeof(DWORD));
if(STATUS_SUCCESS == GetntoskrnlBase("ntkrnlpa.exe"))
{
   CheckSSDTHooks(&KeServiceDescriptorTable);
   DbgPrint("STATUS_SUCCESS == GetntoskrnlBase sucessful!\n");
}
else
{
   DbgPrint("STATUS_SUCCESS == GetntoskrnlBase faile!\n");
}
//status = DbgPrintTheSSDTAndShowSSDT();
return status;

}

NTSTATUS DispathCreateClose(PDEVICE_OBJECT pDevObj,PIRP pIrp)
{

pIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
DbgPrint("DispathCreateClose\n");
//DbgPrintTheSSDTAndShowSSDT();
return STATUS_SUCCESS;
}
NTSTATUS CreateDevice (
        IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
UNICODE_STRING symLinkName;
//创建设备名称
UNICODE_STRING devName;
RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice");

//创建设备
status = IoCreateDevice( pDriverObject,
   sizeof(DEVICE_EXTENSION),
   &devName,
   FILE_DEVICE_UNKNOWN,
   0, TRUE,
   &pDevObj );
if (!NT_SUCCESS(status))
   return status;

pDevObj->Flags |= DO_BUFFERED_IO;
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice = pDevObj;
pDevExt->ustrDeviceName = devName;
//创建符号链接

RtlInitUnicodeString(&symLinkName,L"\\??\\slShowSSDT");
pDevExt->ustrSymLinkName = symLinkName;
status = IoCreateSymbolicLink( &symLinkName,&devName );
if (!NT_SUCCESS(status))
{
   IoDeleteDevice( pDevObj );
   return status;
}
return STATUS_SUCCESS;
}


VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pNextObj;
KdPrint(("Enter DriverUnload\n"));
pNextObj = pDriverObject->DeviceObject;
while (pNextObj != NULL)
{
   PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
    pNextObj->DeviceExtension;
  
   //删除符号链接
   UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
   IoDeleteSymbolicLink(&pLinkName);
   pNextObj = pNextObj->NextDevice;
   IoDeleteDevice( pDevExt->pDevice );
}
    if(g_pmdlSystemCall)
    {
     MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall);
     IoFreeMdl(g_pmdlSystemCall);
   }
}

NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
// 假设失败
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;

// 取得此IRP(pIrp)的I/O堆栈指针
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

// 取得I/O控制代码
ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
// 取得I/O缓冲区指针和它的长度
//PVOID pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
//ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
   ULONG uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

switch(uIoControlCode)
{
case CHAR_CONVERT:
   {

    RepairSSDTHook(&KeServiceDescriptorTable);



   }
   break;
}






// 完成请求
pIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);


return STATUS_SUCCESS;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vt hook ssdt是一种技术,用于在操作系统内核中拦截和修改系统服务调用。通过Vt(Virtualization Technology)技术,可以在操作系统运行时对系统服务进行动态修改,从而实现对系统行为的控制和修改。 以下是一个Vt hook ssdt的示例代码: ```c #include <ntddk.h> ULONG_PTR OriginalServiceAddress = 0; NTSTATUS HookServiceCall(IN PUNICODE_STRING ServiceName, IN ULONG_PTR NewServiceAddress) { NTSTATUS status = STATUS_SUCCESS; ULONG_PTR serviceAddress = 0; // 获取系统服务地址 status = ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, &serviceAddress); if (status != STATUS_INFO_LENGTH_MISMATCH) { return status; } // 遍历系统服务表 PSYSTEM_MODULE_INFORMATION pModuleInfo = (PSYSTEM_MODULE_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, serviceAddress, 'hook'); if (pModuleInfo == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } status = ZwQuerySystemInformation(SystemModuleInformation, pModuleInfo, serviceAddress, NULL); if (!NT_SUCCESS(status)) { ExFreePoolWithTag(pModuleInfo, 'hook'); return status; } for (ULONG i = 0; i < pModuleInfo->NumberOfModules; i++) { PRTL_PROCESS_MODULES pModule = &pModuleInfo->Modules[i]; // 找到ntoskrnl.exe模块 if (wcsstr(pModule->FullPathName, L"ntoskrnl.exe") != NULL) { // 计算SSDT地址 ULONG_PTR ssdtAddress = (ULONG_PTR)pModule->ImageBase + pModule->OffsetToFileName; // 保存原始的系统服务地址 OriginalServiceAddress = *(ULONG_PTR*)ssdtAddress; // 修改系统服务地址为新的地址 *(ULONG_PTR*)ssdtAddress = NewServiceAddress; break; } } ExFreePoolWithTag(pModuleInfo, 'hook'); return status; } NTSTATUS UnhookServiceCall() { if (OriginalServiceAddress != 0) { // 恢复原始的系统服务地址 *(ULONG_PTR*)ssdtAddress = OriginalServiceAddress; OriginalServiceAddress = 0; } return STATUS_SUCCESS; } ``` 以上代码是一个简单的Vt hook ssdt的示例,通过调用`HookServiceCall`函数可以将指定的系统服务地址替换为新的地址,通过调用`UnhookServiceCall`函数可以恢复原始的系统服务地址。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值