首页
社区
课程
招聘
[原创]发一个完全禁止 ring3 访问网络的代码
2012-2-18 23:51 8536

[原创]发一个完全禁止 ring3 访问网络的代码

2012-2-18 23:51
8536
在 ring3 调用的那些 WSASend 、WSARecv 等 socket 的函数,他们最终都是调用 ZwDeviceIoControlFile 来和驱动程序通讯的,所以只要 hook 了这个函数,判断一下句柄的类型,如果和网络有关的就直接返回,这样 ring3 的程序就不能访问网络了,本例子中还 hook 了 ZwCreateFile ZwOpenFile 等函数,因为之前只是想禁止打开这些对象,但比如 qq 等程序会一直打开着 socket ,这样只 hook ZwCreateFile ,ZwOpenFile 就不能完全的禁止 qq 这类程序访问网络了,所以把 ZwDeviceIoControlFile 都 hook 了`

代码写的很烂,可以在 windows 7 运行

///////////////////////////////////////////////////////////////////////////////
///
/// Copyright (c) 2012 - <company name here>
///
/// Original filename: hookZwCreateFilefilter.cpp
/// Project          : hookZwCreateFilefilter
/// Date of creation : 2012-02-07
/// Author(s)        : 
///
/// Purpose          : <description>
///
/// Revisions:
///  0000 [2012-02-07] Initial revision.
///
///////////////////////////////////////////////////////////////////////////////

// $Id$

#ifdef __cplusplus
extern "C" {
#endif
#include <ntddk.h>
#include <string.h>
#include <ntifs.h>
#ifdef __cplusplus
}; // extern "C"
#endif

#include "hookZwCreateFilefilter.h"

#ifdef __cplusplus
namespace { // anonymous namespace to limit the scope of this global variable!
#endif
PDRIVER_OBJECT pdoGlobalDrvObj = 0;
#ifdef __cplusplus
}; // anonymous namespace
#endif

unsigned long old_ZwCreateFile = 0;
unsigned long old_ZwOpenFile = 0;
unsigned long old_ZwDeleteFile = 0;
unsigned long old_ZwDeviceIoControlFile = 0;

unsigned char *copyknbase = 0;
unsigned char *sysknbase = 0;

void *hookfun_ld = 0;

void *hookssdt(unsigned char callid, void *afun);

void * __stdcall my_filter_ObjectName(unsigned long unicode_string);
void * __stdcall my_query_Object_string(void *handle);

void close_cr0_wp();
void open_cr0_wp();

////switch function
void __declspec(naked) switch_my_hook_ZwCreateFile()
{
    __asm
    {
        push eax;
        mov eax, [esp+12+4]; //eax 指向 ObjectAttributes
        pushad;
        pushfd;

        mov eax, [eax+8];//eax 指向 ObjectAttributes->ObjectName 类型是 UNICODE_STRING
        push eax;
        call my_filter_ObjectName;
        cmp eax, 0;
        jne nocallold;

        popfd;
        popad;
        pop eax;

        jmp old_ZwCreateFile;

nocallold:
        popfd;
        popad;
        pop eax;

        ret 11*4;
    }
}

void __declspec(naked) switch_my_hook_ZwOpenFile()
{
    __asm
    {
        push eax;
        mov eax, [esp+12+4]; //eax 指向 ObjectAttributes
        pushad;
        pushfd;

        mov eax, [eax+8];//eax 指向 ObjectAttributes->ObjectName 类型是 UNICODE_STRING
        push eax;
        call my_filter_ObjectName;
        cmp eax, 0;
        jne nocallold;

        popfd;
        popad;
        pop eax;

        jmp old_ZwOpenFile;

nocallold:
        popfd;
        popad;
        pop eax;

        ret 6*4;
    }
}

void __declspec(naked) switch_my_hook_ZwDeleteFile()
{
    __asm
    {
        push eax;
        mov eax, [esp+4+4]; //eax 指向 UNICODE_STRING
        pushad;
        pushfd;

        push eax;
        call my_filter_ObjectName;
        cmp eax, 0;
        jne nocallold;

        popfd;
        popad;
        pop eax;

        jmp old_ZwDeleteFile;

nocallold:
        popfd;
        popad;
        pop eax;

        ret 4;
    }
}

void __declspec(naked) switch_my_hook_ZwDeviceIoControlFile()
{
    __asm
    {
        push eax;
        mov eax, [esp+8];
        pushad;
        pushfd;

        push eax;
        call my_query_Object_string;
        cmp eax, 0;
        jne nocallold;

        popfd;
        popad;
        pop eax;

        jmp old_ZwDeviceIoControlFile;

nocallold:
        popfd;
        popad;
        pop eax;

        ret 10*4;
    }
}

void __declspec(naked) switch_my_hook_ZwLoadDriver()
{
    __asm
    {
        //ret 4;
        mov eax, hookfun_ld;
        sub eax, sysknbase;
        add eax, copyknbase;

        jmp eax;
    }
}

NTSTATUS HOOKZWCREATEFILEFILTER_DispatchCreateClose(
    IN PDEVICE_OBJECT        DeviceObject,
    IN PIRP                    Irp
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}

NTSTATUS HOOKZWCREATEFILEFILTER_DispatchDeviceControl(
    IN PDEVICE_OBJECT        DeviceObject,
    IN PIRP                    Irp
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);

    switch(irpSp->Parameters.DeviceIoControl.IoControlCode)
    {
    case IOCTL_HOOKZWCREATEFILEFILTER_OPERATION:
        // status = SomeHandlerFunction(irpSp);
        break;
    default:
        Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
        Irp->IoStatus.Information = 0;
        break;
    }

    status = Irp->IoStatus.Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}

VOID HOOKZWCREATEFILEFILTER_DriverUnload(
    IN PDRIVER_OBJECT        DriverObject
    )
{
    PDEVICE_OBJECT pdoNextDeviceObj = pdoGlobalDrvObj->DeviceObject;
    IoDeleteSymbolicLink(&usSymlinkName);

    // Delete all the device objects
    while(pdoNextDeviceObj)
    {
        PDEVICE_OBJECT pdoThisDeviceObj = pdoNextDeviceObj;
        pdoNextDeviceObj = pdoThisDeviceObj->NextDevice;
        IoDeleteDevice(pdoThisDeviceObj);
    }
}

#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(
    IN OUT PDRIVER_OBJECT   DriverObject,
    IN PUNICODE_STRING      RegistryPath
    )
{
    PDEVICE_OBJECT pdoDeviceObj = 0;
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    pdoGlobalDrvObj = DriverObject;

    // Create the device object.
    if(!NT_SUCCESS(status = IoCreateDevice(
        DriverObject,
        0,
        &usDeviceName,
        FILE_DEVICE_UNKNOWN,
        FILE_DEVICE_SECURE_OPEN,
        FALSE,
        &pdoDeviceObj
        )))
    {
        // Bail out (implicitly forces the driver to unload).
        return status;
    };

    // Now create the respective symbolic link object
    if(!NT_SUCCESS(status = IoCreateSymbolicLink(
        &usSymlinkName,
        &usDeviceName
        )))
    {
        IoDeleteDevice(pdoDeviceObj);
        return status;
    }

    // NOTE: You need not provide your own implementation for any major function that
    //       you do not want to handle. I have seen code using DDKWizard that left the
    //       *empty* dispatch routines intact. This is not necessary at all!
    DriverObject->MajorFunction[IRP_MJ_CREATE] =
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = HOOKZWCREATEFILEFILTER_DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HOOKZWCREATEFILEFILTER_DispatchDeviceControl;
    DriverObject->DriverUnload = HOOKZWCREATEFILEFILTER_DriverUnload;

    UNICODE_STRING ZwCreateFile_string_name = {0};
    UNICODE_STRING ZwOpenFile_string_name = {0};
    UNICODE_STRING ZwDeleteFile_string_name = {0};
    UNICODE_STRING ZwDeviceIoControlFile_string_name = {0};
    UNICODE_STRING NtLoadDriver_string_name = {0};

    ::RtlInitUnicodeString(&ZwCreateFile_string_name, L"ZwCreateFile");
    ::RtlInitUnicodeString(&ZwOpenFile_string_name, L"ZwOpenFile");
    ::RtlInitUnicodeString(&ZwDeleteFile_string_name, L"ZwDeleteFile");
    ::RtlInitUnicodeString(&ZwDeviceIoControlFile_string_name, L"ZwDeviceIoControlFile");
    ::RtlInitUnicodeString(&NtLoadDriver_string_name, L"ZwLoadDriver");

    void *paddr_1 = ::MmGetSystemRoutineAddress(&ZwCreateFile_string_name);
    void *paddr_2 = ::MmGetSystemRoutineAddress(&ZwOpenFile_string_name);
    void *paddr_3 = ::MmGetSystemRoutineAddress(&ZwDeleteFile_string_name);
    void *paddr_4 = ::MmGetSystemRoutineAddress(&ZwDeviceIoControlFile_string_name);
    void *paddr_5 = ::MmGetSystemRoutineAddress(&NtLoadDriver_string_name);

    //__asm int 3;

    old_ZwCreateFile = (unsigned long)::hookssdt(*(char*)((unsigned long)(paddr_1)+1), switch_my_hook_ZwCreateFile);
    old_ZwOpenFile = (unsigned long)::hookssdt(*(char*)((unsigned long)(paddr_2)+1), switch_my_hook_ZwOpenFile);
    old_ZwDeleteFile = (unsigned long)::hookssdt(*(char*)((unsigned long)(paddr_3)+1), switch_my_hook_ZwDeleteFile);
    old_ZwDeviceIoControlFile = (unsigned long)::hookssdt(*(char*)((unsigned long)(paddr_4)+1), switch_my_hook_ZwDeviceIoControlFile);

    

    unsigned long sysfunadr = 0;
    void *ke_ssdt_ = ::KeServiceDescriptorTable;
    ke_ssdt_ = (void*)*(unsigned long*)ke_ssdt_;

    unsigned char callid = 0;
    callid = (*(unsigned char*)((unsigned long)(paddr_5)+1));
    sysfunadr = (unsigned long)ke_ssdt_+callid*(unsigned char)4;
    

    
    
    //不会有羡慕、不会有嫉妒、只会有那种最真至的关心

    hookfun_ld = (void*)*(ULONG*)sysfunadr;

    //::DbgPrint("%x callid=%x\r\n", hookfun_ld, *(char*)((unsigned long)(paddr_5)+1));

    ULONG retsize = 0;
    SYSTEM_MODULE_INFORMATION *sys_mod = 0;
    char *buf = 0;

    ::ZwQuerySystemInformation((SYSTEM_INFORMATION_CLASS)11, 0, 0, &retsize);
    buf = (char*)ExAllocatePool(NonPagedPool, retsize);

    ::ZwQuerySystemInformation((SYSTEM_INFORMATION_CLASS)11, (void*)buf, retsize, &retsize);

    sys_mod = (SYSTEM_MODULE_INFORMATION*)(buf+sizeof(ULONG));
    sysknbase = (unsigned char*)sys_mod[0].Base;
    copyknbase = (unsigned char*)ExAllocatePool(NonPagedPool, sys_mod[0].Size);

    unsigned char rtmp = *(unsigned char*)sys_mod[0].Base;
    //__asm int 3;

    //::close_cr0_wp();

    //::RtlCopyMemory(copyknbase, sys_mod[0].Base, sys_mod[0].Size);

    MDL *kmdl = MmCreateMdl(0, sys_mod[0].Base, sys_mod[0].Size);
    MmBuildMdlForNonPagedPool(kmdl);
    kmdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
    unsigned char *sysknbase_mdl = (unsigned char*)::MmMapLockedPages(kmdl, KernelMode);

    for(unsigned long i = 0; i < sys_mod[0].Size; i++) 
        *(unsigned char*)(copyknbase+i) = *(unsigned char*)(((unsigned long)(sysknbase_mdl))+i);
        //rtmp = *(unsigned char*)(((unsigned long)(sys_mod[i].Base))+i);
    //::open_cr0_wp();
    /////::RtlCopyMemory((void*)copyknbase, (void*)copyknbase, sys_mod[0].Size);

    //::MmUnmapLockedPages((unsigned char*)sysknbase_mdl, kmdl);
    //::MmUnlockPages(kmdl);

    //*(int*)sys_mod[0].Base = 0;

    ::DbgPrint("new kernel address = %x\r\n", copyknbase);

    ::close_cr0_wp();

    *(char*)hookfun_ld = (char)0x68;
    *(ULONG*)((ULONG)(hookfun_ld)+1) = (ULONG)switch_my_hook_ZwLoadDriver;
    *(char*)((ULONG)(hookfun_ld)+1+4) = (char)0xc3;

    ::open_cr0_wp();

    ::ExFreePool(buf);

    return STATUS_SUCCESS;
}


#ifdef __cplusplus
}; // extern "C"
#endif

void *hookssdt(unsigned char callid, void *afun)
{
    ///__asm int 3;
    ///::DbgPrint("hook ssdt callid:%d\r\n", callid);

    unsigned long sysfunadr = 0;
    unsigned long oldsysfunadr = 0;
    void *ke_ssdt_ = ::KeServiceDescriptorTable;
    ke_ssdt_ = (void*)*(unsigned long*)ke_ssdt_;
    sysfunadr = (unsigned long)ke_ssdt_;
    //ke_ssdt_ = (void*)*(unsigned long*)ke_ssdt_;
    sysfunadr += (unsigned long)(callid*(unsigned char)4);

    oldsysfunadr = *(unsigned long*)sysfunadr;

    ::close_cr0_wp();

    *(unsigned long*)sysfunadr = (unsigned long)afun;

    ::open_cr0_wp();


    return (void*)oldsysfunadr;
}

void close_cr0_wp()
{
    __asm {
        cli;
        mov eax,cr0;
        and eax, 0xfffeffff;
        mov cr0,eax;
    }
}

void open_cr0_wp()
{
    __asm {
        mov  eax,cr0;
        or   eax, 0x10000
        mov  cr0,eax;
        sti;
    }
}

void * __stdcall my_filter_ObjectName(unsigned long unicode_string)
{
#define dn 6

    UNICODE_STRING *us;
    ANSI_STRING ansistring_objname = {0};
    char filtertxt[dn][20] = {"\\Device\\Afd", "\\Device\\Ip", "\\Device\\Tcp6", "\\Device\\Tcp", "\\Device\\Tcpip", "\\Nsi"};
    //int fl = ::strlen(filtertxt);
    us = (UNICODE_STRING*)unicode_string;
    int i_retd = 0;

    ::RtlUnicodeStringToAnsiString(&ansistring_objname, us, 1);

    //::DbgPrint("%s\r\n", ansistring_objname.Buffer);

    for(int j = 0; j < dn; j++ ) {
        for(int i = 0; i < ansistring_objname.Length; i++) {
            if( *(ansistring_objname.Buffer+i) == filtertxt[j][0]) {
                if(::RtlCompareMemory(filtertxt[j], ansistring_objname.Buffer+i, strlen(filtertxt[j])) == strlen(filtertxt[j])) {
                    //::DbgPrint("rj....%s\r\n", ansistring_objname.Buffer);
                    i_retd = 1;
                }
            }
        }
    }

    ::RtlFreeAnsiString(&ansistring_objname);

    return (void*)i_retd;
}

void * __stdcall my_query_Object_string(void *handle)
{
#define t_1 100

    char wstr[t_1] = {0};
    UNICODE_STRING *usObjectName = (UNICODE_STRING*)wstr;
    ANSI_STRING anObjectName = {0};
    unsigned long rl = 0;
    unsigned long filter_retval = 0;

    if(!NT_SUCCESS(ZwQueryObject(handle, (OBJECT_INFO_CLASS)1, (void*)wstr, t_1, &rl))) return 0;

    ::RtlUnicodeStringToAnsiString(&anObjectName, usObjectName, 1);
    ///DbgPrint("ZwDeviceIoControlFile handle type_string = %s\r\n", anObjectName.Buffer);

    filter_retval = (unsigned long)::my_filter_ObjectName((unsigned long)usObjectName);

    if(filter_retval != 0) ::ZwClose(handle);

    ::RtlFreeAnsiString(&anObjectName);


    return (void*)filter_retval;
}


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞5
打赏
分享
最新回复 (12)
雪    币: 585
活跃值: (568)
能力值: ( LV13,RANK:290 )
在线值:
发帖
回帖
粉丝
guxinyi 5 2012-2-19 00:23
2
0
支持,呵呵 。。。。。。。。。。。。
雪    币: 1905
活跃值: (1427)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
z许 2012-2-19 01:03
3
0
mark一份。
雪    币: 602
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
kangcin 2012-2-19 07:51
4
0
biaoji,,,,,,,,,,,,
雪    币: 258
活跃值: (84)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
hellotong 1 2012-2-19 08:30
5
0
过来学习一下!!!!!!!!!!!!!!!!!!
雪    币: 22
活跃值: (423)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
靴子 2012-2-19 09:59
6
0
mark
雪    币: 4565
活跃值: (927)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
b23526 2012-2-19 12:47
7
0
不错,收藏
雪    币: 208
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
justlovemm 2012-2-19 13:44
8
0
不错,收藏了。
多谢!
雪    币: 220
活跃值: (626)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dayang 2012-2-19 13:52
9
0
驱动,又 是驱动,不能干坏事了
雪    币: 2321
活跃值: (4028)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
熊猫正正 9 2012-2-19 15:31
10
0
学习一下~~
雪    币: 243
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jero 2012-2-19 23:40
11
0
学习并收藏了
雪    币: 589
活跃值: (119)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
promsied 4 2012-2-20 13:59
12
0
学习一下
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jerrynpc 2012-2-20 14:26
13
0
C++的驱动,我哭了
游客
登录 | 注册 方可回帖
返回