首页
社区
课程
招聘
[讨论]进程保护
发表于: 2012-5-2 11:59 3893

[讨论]进程保护

2012-5-2 11:59
3893
#include <NTDDK.h>
#include <windef.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 INITDATA data_seg("INIT")

typedef struct _ssdt
{
        PVOID base;
        PVOID Count;
        LONG nums;
        PVOID param;
}*PSsdt;

extern  PSsdt  KeServiceDescriptorTable;
//                          KeServiceDescriptorTable;
ULONG *oldaddress;                //服务函数的原始地址
ULONG *ADDR;                        //原始存放服务函数的地址

PEPROCESS pEpro;

//他们之间的关系就是在ADDR处存放了oldaddress, *ADDR = oldaddress

NTSTATUS ddkunload(IN PDRIVER_OBJECT pd);

typedef NTSTATUS
          (* NTTERMINATEPROCESS )(
         __in_opt HANDLE ProcessHandle,
         __in NTSTATUS ExitStatus
         );
NTTERMINATEPROCESS oldnt = NULL;
       
NTSTATUS
MyNtTerminateProcess(
                                         __in_opt HANDLE ProcessHandle,
                                         __in NTSTATUS ExitStatus
                                         );

#pragma  INITCODE
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriver,
                                                                IN PUNICODE_STRING pRegPath)
{
       
        //_asm int 3;

        ULONG *addr,*tablebase;
       
        //_asm int 3
       
        tablebase = (PLONG)KeServiceDescriptorTable->base;
        KdPrint(("当前ServiceTableBase地址为%x \n",tablebase));

        addr = (PLONG)((CHAR *)tablebase + 4*0x101);
        ADDR = addr;
        KdPrint(("当前序号NtTerminateProcess地址为%x \n", *addr ));

        oldaddress = *addr;

                __asm //去掉页面保护
                {
                        cli
                                mov eax,cr0
                                and eax,not 10000h //and eax,0FFFEFFFFh
                                mov cr0,eax
                }
                *addr = MyNtTerminateProcess;        //替换为自己的函数地址,
                //addr存放服务函数的地址,*addr服务函数的地址。

                __asm //恢复页保护
                {
                        mov eax,cr0
                                or  eax,10000h //or eax,not 0FFFEFFFFh
                                mov cr0,eax
                                sti
                }

        pDriver->DriverUnload = ddkunload;
        return 1;
}

#pragma PAGECODE
//NTSTATUS ddkunload(IN PDRIVER_OBJECT pDriverObject)
NTSTATUS ddkunload(IN PDRIVER_OBJECT pd)
{
        KdPrint(("驱动成功被卸载...OK-----------")); //需要这样一个宏 相当于sprintf,printf  
//pd->DeviceObject;
        __asm //去掉页面保护
        {
                cli
                        mov eax,cr0
                        and eax,not 10000h //and eax,0FFFEFFFFh
                        mov cr0,eax
        }
        //memset(ADDR,oldaddress,4);
        *ADDR = (ULONG)oldaddress;
        __asm //恢复页保护
        {
                mov eax,cr0
                        or  eax,10000h //or eax,not 0FFFEFFFFh
                        mov cr0,eax
                        sti
        }
        return 1;
}

NTSTATUS
MyNtTerminateProcess(
                                         __in_opt HANDLE ProcessHandle,
                                         __in NTSTATUS ExitStatus
                                         )
{
        char name[50];
        //UNICODE_STRING orl;
        //DWORD PID;
        //ULONG *orladdr;
        NTSTATUS     rc; //返回的值
        PEPROCESS pEProcess;
        //DWORD dwcal;
//_asm int 3;
        KdPrint(("MyNtTerminateProcess\n"));
        //dwcal = *ADDR;
        oldnt = oldaddress;
       

        //RtlInitUnicodeString(&orl, L"NtTerminateProcess");
        //orladdr = (ULONG*)MmGetSystemRoutineAddress(&orl);
        //oldaddress = orladdr;                        //存放了原来的服务函数地址,然后再call原来的服务函数地址
        //KdPrint(("当前ServiceTableBase地址为MyNtTerminateProcess  :  %x \n",orladdr));

        //ObReferenceObjectByHandle (
        //        __in HANDLE Handle,                                                //传入对象句柄
        //        __in ACCESS_MASK DesiredAccess,
        //        __in_opt POBJECT_TYPE ObjectType,                                //对象类型
        //        __in KPROCESSOR_MODE AccessMode,
        //        __out PVOID *Object,                                        //返回对象体指针
        //        __out_opt POBJECT_HANDLE_INFORMATION HandleInformation
        //        )
                ObReferenceObjectByHandle(ProcessHandle,
                                                                        GENERIC_READ,
                                                                        0,
                                                                        KernelMode,
                                                                        &pEProcess,
                                                                        NULL);
        //        ObReferenceObjectByHandle(Handle,DesiredAccess,ObjectType,AccessMode,&Process,NULL);
                //status = ObReferenceObjectByHandle(ProcessHandle,
                //        FILE_READ_DATA,0,KernelMode,&process,NULL);    //获取进程

                KdPrint(("be termited process is %s \n",(char*)pEProcess+0x174));

                //strcpy(name, (char *)pEProcess+0x174);
        //        name = (char *)pEProcess+0x174;

                if (strcmp(((char*)pEProcess+0x174),"try.exe") == 0)
                {
                        _asm int 3;
                        KdPrint(("try.exe"));
                }

        //if (1)
        //{
        //        //ProcessHandle = NULL; //这个是关键
        //        rc = STATUS_ACCESS_DENIED; //这个返回值表示拒绝访问
        //        ObDereferenceObject(pEProcess);
        //        return rc;
        //}

                if (pEProcess == PsGetCurrentProcess())
                {
                        KdPrint(("the same\n"));
                        oldnt(ProcessHandle,ExitStatus);
                }
                //{//情况一:当前进程不是我们所保护的进程
                //        //换句话说也就是其他进程试图结束我们所保护的进程,当然不能让他结束
                //        KdPrint(("[-]进程保护,外部程序试图关闭保护进程\n"));
                        //rc = STATUS_ACCESS_DENIED;
                //        return rc;

        //ObDereferenceObject(pEProcess);
        //_asm call oldaddress                //调用原来的函数

        oldnt(ProcessHandle,ExitStatus);

}

帮忙看下怎么总是蓝或者异常。。
另外还有几点疑惑
        //ObReferenceObjectByHandle (
        //        __in HANDLE Handle,                                                //传入对象句柄
        //        __in ACCESS_MASK DesiredAccess,
        //        __in_opt POBJECT_TYPE ObjectType,                                //对象类型
        //        __in KPROCESSOR_MODE AccessMode,
        //        __out PVOID *Object,                                        //返回对象体指针
        //        __out_opt POBJECT_HANDLE_INFORMATION HandleInformation
        //        )
这个函数的第4个参数如果要获得进程的EPROCESS 是不是一定要 *PsProcessType,还是赋值0,我测试了貌似2者都能获取到正确的EPROCESS地址,

2.
//RtlInitUnicodeString(&orl, L"NtTerminateProcess");
        //orladdr = (ULONG*)MmGetSystemRoutineAddress(&orl);
        //oldaddress = orladdr;                        //存放了原来的服务函数地址,然后再call原来的服务函数地址
        //KdPrint(("当前ServiceTableBase地址为MyNtTerminateProcess  :  %x \n",orladdr));

这种方式能获取到原始的NtTerminateProcess地址?我测试出来怎么得到的是EPROCESS地址是0,帮忙看看那里有错误

3.如果拒绝结束要保护的进程,那么MYNtTerminateProcess是不用调用原始的NtTerminateProcess,那返回值怎么处理,返回值可以更改,然后传递进来的句柄ProcessHandle这个怎么处理,它是IN OUT,是需要返回的吧,怎么写这一块

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//