//方式1:MSR Hook

#include <ntifs.h>

UINT32 oldaddr = 0;
UINT32 pidtoprotect = 3792;
PCLIENT_ID pid = 0;
PUINT32 accessmask = 0;
UINT32 ssdtindex = 0;



VOID MyKiFastCallEntry();
//#pragma alloc_text(NONE_PAGE,MyKiFastCallEntry)

VOID OnHook()
{

    __asm
    {
            pushad
            pushfd

            mov ecx, 0x176
            rdmsr
            mov oldaddr, eax

            mov ecx, 0x176
            xor edx, edx
            mov eax, MyKiFastCallEntry
            wrmsr

            popfd
            popad
    }



}

VOID OffHook()
{
    __asm
    {
        pushad
        pushfd

        mov ecx,0x176
        xor edx,edx
        mov eax,oldaddr
        wrmsr

        popfd
        popad
    }
}

VOID UnloadMe(PDRIVER_OBJECT pdo)
{
    OffHook();
}

__declspec(naked) VOID MyKiFastCallEntry()  //原来裸函数内不能使用auto或register变量的
{
    __asm
    {
        mov ssdtindex, eax;
    }
    
    if (ssdtindex == 0xbe)
    {
        _asm
        {
            push dword ptr[edx + 4 * 5];
            pop  pid;
            push edx;
            add dword ptr[esp], 12;
            pop accessmask;                        //这里得注意,这种方式,得到的是accessmask的地址..太阴险了
            pushad;
        }
        if ((pid->UniqueProcess == pidtoprotect) && (*accessmask&0x0001))
        {
            KdPrint(("I'm Here2!\n"));
            *accessmask &= ~0x0001;
        }
        _asm popad;
    }
    __asm
    {
        
        jmp oldaddr;
    }
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pdo, PUNICODE_STRING ppath)
{
    OnHook();

    pdo->DriverUnload = UnloadMe;
    return STATUS_SUCCESS;
}

//不知为何,虽然保护成功了,但是在任务管理器多次结束任务,那么那个进程还是被结束了..
//方式2:SSDT Hook

#include <ntifs.h>

#pragma pack(1)
typedef struct _ServiceDescriptorEntry
{
    ULONG *ServiceTableBase;
    ULONG *ServiceCounterTableBase;
    ULONG NumberOfServices;
    UCHAR *ParamTableBase;
}SSDTEntry, *PSSDTEntry;
#pragma pack()

NTSYSAPI SSDTEntry KeServiceDescriptorTable;
VOID OnHook();
VOID OffHook();

VOID OffMemProtect()
{
    __asm
    {
        push eax;
        mov eax, CR0;
        and eax, ~0x10000;
        mov CR0, eax;
        pop eax;
    }
}

VOID OnMemProtect()
{
    __asm
    {
        push eax;
        mov eax, CR0;
        or eax, 0x10000;
        mov CR0, eax;
        pop eax;
    }
}

VOID UnloadMe(PDRIVER_OBJECT pdo)
{
    OffHook();
}

ULONG pidtoprotect = 1796;


typedef NTSTATUS(NTAPI *NTOPENPROCESS)(__out PHANDLE  ProcessHandle,
    __in ACCESS_MASK  DesiredAccess,
    __in POBJECT_ATTRIBUTES  ObjectAttributes,
    __in_opt PCLIENT_ID  ClientId
    );
NTOPENPROCESS oldaddr;


NTSTATUS MyZwOpenProcess(
    _Out_    PHANDLE            ProcessHandle,
    _In_     ACCESS_MASK        DesiredAccess,
    _In_     POBJECT_ATTRIBUTES ObjectAttributes,
    _In_opt_ PCLIENT_ID         ClientId
    );


NTSTATUS MyZwOpenProcess(
    _Out_    PHANDLE            ProcessHandle,
    _In_     ACCESS_MASK        DesiredAccess,
    _In_     POBJECT_ATTRIBUTES ObjectAttributes,
    _In_opt_ PCLIENT_ID         ClientId
    )
{
    if ((ClientId->UniqueProcess == pidtoprotect) && (DesiredAccess & 0x0001))
    {
        KdPrint(("IM in"));
        return STATUS_ACCESS_DENIED;
    }
    else
        return oldaddr(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}



VOID OnHook()
{
    DbgBreakPoint();
    OffMemProtect();

    PULONG pssdtbase = KeServiceDescriptorTable.ServiceTableBase;

    ULONG uIndex = 0xbe;

    oldaddr = pssdtbase[uIndex];
    pssdtbase[uIndex] = MyZwOpenProcess;
    OnMemProtect();

}

VOID OffHook()
{
    OffMemProtect();
    PULONG pssdtbase = KeServiceDescriptorTable.ServiceTableBase;
    ULONG uIndex = 0xbe;
    pssdtbase[uIndex] = oldaddr;
    OnMemProtect();
}



NTSTATUS DriverEntry(PDRIVER_OBJECT pdo, PUNICODE_STRING ppath)
{
    OnHook();

    pdo->DriverUnload = UnloadMe;
    return STATUS_SUCCESS;
}

 

posted on 2017-03-20 11:09  fuckitup123  阅读(1176)  评论(0编辑  收藏  举报