学习自建调试体系(四)

这部分ring3和ring0通信,感觉也是实用的套路,先总结大致思路:

  1. hook NtTerminateProcess函数
  2. 有TerminateProcess请求到来时,判断参数二是否为固定常数(密钥),不是的话走原函数调用
  3. 如果参数二是约定好的密钥,参数一作为约定好的结构指针
  4. 读取ring3传来的数据,读取数据,执行约定函数

SSDT hook

NTSTATUS DbgObjHookNtTerminateProcess()
{
    PULONG  Address;
    PVOID Temp;

    if ((ULONG)OldNtTerminateProcess)       //static变量初始化0 
    {
        return STATUS_UNSUCCESSFUL;
    }

    //
    // 在SSDT表中获取到NtTerminateProcess的地址
    //

    Address = (PULONG)((ULONG)KeServiceDescriptorTable->ntoskrnl.ServiceTable +
        257 * 4);

    //原函数 and 替换函数
    OldNtTerminateProcess = (PZWTERMINATEPROCESS)* Address;
    Temp = &NewNtTerminateProcess;

    //
    // 改写SSDT表中NtTerminateProcess的地址
    //

    //自己封装的MoveMemory函数
    SafeCopyMemory(Address, &Temp, sizeof(PVOID));

    KdPrint(("Ddvp-> 旧NtTerminateProcess地址: %p, 新的NtTerminateProcess地址: %p \n",
        OldNtTerminateProcess, &NewNtTerminateProcess));

    return STATUS_SUCCESS;

}

钩子函数

NTSTATUS
NewNtTerminateProcess(
HANDLE   hProcess,
NTSTATUS ExitStatus
)
{
    NTSTATUS Status;
    BUFFER_LOCK InBufferLock;
    BUFFER_LOCK OutBufferLock;
    SYSTEM_CALL  SysCall;

    //typedef struct tagSystemCall
    //{
    //  int Number;
    //  PVOID lpInBuffer;
    //  ULONG ulInBufferSize;
    //  PVOID lpOutBuffer;
    //  ULONG ulOutBufferSize;
    //}SYSTEM_CALL, *PSYSTEM_CALL;

    PEPROCESS Process = PsGetCurrentProcess();

    //
    // 如果调用过来的是用户态, 并且Key也相同
    //
    if ((ExGetPreviousMode() == UserMode) && (ExitStatus == 0x750C530D))
    {
        Status = STATUS_UNSUCCESSFUL;
        InBufferLock.lpData = NULL;
        OutBufferLock.lpData = NULL;

        do
        {
            __try
            {
                //
                // 检查用户模式缓冲区是否正确对齐.注意是用户模式缓冲区
                //
              
              /hProcess作为pSysCall解释
                ProbeForRead(hProcess, sizeof(SYSTEM_CALL), 1);

                //
                // 复制 一个 syscall结构过来
                //
                fastcpy(&SysCall, hProcess, sizeof(SYSTEM_CALL));
            }
            __except (EXCEPTION_EXECUTE_HANDLER)
            {
                Status = GetExceptionCode();
                break;
            }

            //
            // 参数判断
            //
            if ((SysCall.Number > SC_MAX) ||
                (SysCall.ulInBufferSize  > SC_DAT_LIMIT) ||
                (SysCall.ulOutBufferSize > SC_DAT_LIMIT))
            {
                KdPrint(("Ddvp-> NewNtTerminateProcess Buffer 有问题 \n"));
                break;
            }

            //
            // 如果输入缓冲区不为NULL, 那么锁定输入缓冲区
            //
            if (SysCall.lpInBuffer != NULL)
            {
                if (DbgLockBuffer(&InBufferLock, SysCall.lpInBuffer, SysCall.ulInBufferSize) == 0)
                {
                    KdPrint(("Ddvp-> NewNtTerminateProcess In Buffer Lock Error! \n"));
                    break;
                }

                SysCall.lpInBuffer = InBufferLock.lpData;
            }

            //
            // 如果输出缓冲区不为NULL, 那么锁定输入缓冲区
            //
            if (SysCall.lpOutBuffer != NULL)
            {
                if (DbgLockBuffer(&OutBufferLock, SysCall.lpOutBuffer, SysCall.ulOutBufferSize) == 0)
                {
                    KdPrint(("Ddvp-> NewNtTerminateProcess Out Buffer Lock Error! \n"));
                    break;
                }

                SysCall.lpOutBuffer = OutBufferLock.lpData;
            }

            //
            // 执行约定的函数,哪个函数,什么通信数据都在SysCall结构中
            //
            if (NT_SUCCESS(SysCallTable[SysCall.Number](&SysCall)))
            {
                Status = STATUS_SUCCESS;
            }
        } while (0);

        if (InBufferLock.lpData != NULL)
        {
            DbgUnLockBuffer(&InBufferLock);
        }

        if (OutBufferLock.lpData != NULL)
        {
            DbgUnLockBuffer(&OutBufferLock);
        }
    }
    //---------------------------------------------------------------------------
    else
    {
            Status = OldNtTerminateProcess(hProcess, ExitStatus);
    }

    return Status;
}

转载于:https://www.cnblogs.com/Lnju/p/5414231.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值