• X86 下的SSDT HOOK


    SSDTHOOK

    1.SSDTHOOK 原理.

    x32下,直接获取系统描述符表.以及调用号.就可以进行HOOK了.

    x64下可以设置回调来进行过滤我们想要的功能.当然如果你简单的过一下PatchGuard也可以设置SSDT HOOK.

    1.x32下的SSDT HOOK

    首先SSDT 我们是可以在windbg下看到的

    SSDT表的结构如下:

    
    typedef struct _KSERVICE_TABLE_DESCRIPTOR {
        PULONG_PTR Base;
        PULONG Count;
        ULONG Limit;
        PUCHAR Number;
    } KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
    
    

    在WRK中的 ke.h中可以看到.

    查看定义

    在wrk中也可以看到定义的地方. 所以我们只需要在我们的函数中引用这个全局变量即可.

    其中这个结构第一项是表的首地址 第二项是表的个数. *表 + n = 第某个函数的地址
    也就是 base[10]就是第十项的地址.

    KeServiceDescriptorTable

    对应PCHunter查看.

    所以我们想要HOOK就很简单了.

    1. 导入全局变量. 则获得SSDT表的地址
    2. 获取你想HOOK函数的位置
    3. 进行HOOK
    4. HOOK之前关闭一下CR0得写保护

    代码如下:

    2.SSDT HOOK代码

    
    #include "Driver.h"
    
    NTKERNELAPI UCHAR* PsGetProcessImageFileName(IN PEPROCESS Process);
    
    void UnHook();
    void DriverUnLoad(PDRIVER_OBJECT pDriverObj)
    {
    	UnHook();
    	KdPrint(("驱动卸载成功"));
    }
    
    typedef struct _KSERVICE_TABLE_DESCRIPTOR {
    	PULONG_PTR Base;
    	PULONG Count;
    	ULONG Limit;
    	PUCHAR Number;
    } KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
    
    __declspec(dllimport) KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable; //导入全局变量
    
    // sizeof(base) + 370 * 4 = NtTerMinateProcess
    
    //extern KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable
    typedef NTSTATUS(*PfnZwTerminateProcess)(
    	IN HANDLE              ProcessHandle OPTIONAL,
    	IN NTSTATUS            ExitStatus);
    
    PfnZwTerminateProcess OldZwTerminateProcess;
    NTSTATUS Hook_ZwTerminateProcess(
    	IN HANDLE              ProcessHandle OPTIONAL,
    	IN NTSTATUS            ExitStatus)
    {
    	NTSTATUS rc;
    	PEPROCESS pRocess;
    	UCHAR *pszProcessName;
    	//UCHAR *pszProcessName = PsGetProcessImageFileName();
    	rc = ObReferenceObjectByHandle(ProcessHandle, GENERIC_ALL, *PsProcessType, KernelMode, &pRocess, NULL);
    	if (!NT_SUCCESS(rc))
    	{
    		
    		return OldZwTerminateProcess(ProcessHandle, ExitStatus);
    	}
    	pszProcessName = PsGetProcessImageFileName(pRocess);
    	if (strstr(pszProcessName, "calc"))
    	{
    		return STATUS_ACCESS_DENIED;
    		ObDereferenceObject(pRocess);
    	}
    	ObDereferenceObject(pRocess);
    	rc = OldZwTerminateProcess(ProcessHandle, ExitStatus);
    	return rc;
    }
    //关闭写保护 1111 1111 1111 1110 1111 1111 1111 1111 
    VOID _CloseWriteProtected()
    {
    	__asm
    	{
    		push eax
    		mov eax, cr0
    		and eax, 0xFFFEFFFF
    		mov cr0,eax
    		pop eax
    	}
    	return;
    }
    VOID _OpenTheWriteProtected()
    {
    	__asm
    	{
    		push    eax
    		mov        eax, cr0
    		or eax, NOT 0xFFFEFFFF
    		mov        cr0, eax
    		pop        eax
    	}
    	return;
    }
    void HOOK()
    {
    	//370是ntTerminateProcess 也可以写成 base + sizeof(type) *n = *(KeServiceDescriptorTable.Base) + 4 * 370 = NtTinminateProcess的地址
    	/*
    	OldZwTerminateProcess = (PfnZwTerminateProcess)(*(KeServiceDescriptorTable.Base) + 370 * 4);
    	*/
    	OldZwTerminateProcess = (PfnZwTerminateProcess)KeServiceDescriptorTable.Base[370];
    	_CloseWriteProtected();
    	//
    	KeServiceDescriptorTable.Base[370] = (int)Hook_ZwTerminateProcess;
    
    	_OpenTheWriteProtected();
    }
    void UnHook()
    {
    	_CloseWriteProtected();
    	//
    	KeServiceDescriptorTable.Base[370] = (int)OldZwTerminateProcess;
    
    	_OpenTheWriteProtected();
    }
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath)
    {
    	
    	pDriverObj->DriverUnload = DriverUnLoad;
    	
    	HOOK();
    	return STATUS_SUCCESS;
    }
    
    
    
    
    

    3.结果

    4.总结

    总的来说如果按照服务号来HOOK是很简单的.如果没有服务号你怎么HOOK?
    其实在32位下.你调用的函数.里面就有调用号.内核也跟应用层的调用号是息息相关的.我们可以取得函数调用号进行HOOK也可以.

    如:

    未测试.
    KeServiceDescriptorTable.Base[*(PULONG)((PUCHAR)_FUNCTION +1)];
    

    其中_FUNCTION用名字修改即可.

  • 相关阅读:
    nginx优化:使用expires在浏览器端缓存静态文件
    nginx优化:worker_processes/worker_connections/worker_rlimit_nofile
    centos8平台使用ulimit做系统资源限制
    centos8平台nginx服务配置打开文件限制max open files limits
    nginx安全:配置allow/deny控制ip访问(ngx_http_access_module)
    python 菜鸟入门
    正则表达式预查询
    selenium 关键字驱动部分设计思路
    Idea安装Python插件并配置Python SDK
    ORACLE LOG的管理
  • 原文地址:https://www.cnblogs.com/iBinary/p/11223324.html
Copyright © 2020-2023  润新知