首页
社区
课程
招聘
[旧帖] [求助]去掉windows内存保护 0.00雪花
发表于: 2009-7-2 17:22 1788

[旧帖] [求助]去掉windows内存保护 0.00雪花

2009-7-2 17:22
1788
/*
演示HOOK系统服务调用表中的NtOpenProcess函数,保护需要保护的进程被,防止被杀掉
*/

#include<ntddk.h>

/*
KeServiceDescriptorTable仅有ntoskrnel一项,没有包含win32k,而且后面的两个字段都没有使用,所

以为了简便直接把SystemServiceDescriptorTable定义成SYSTEM_SERVICE_TABLE,免得访问多个结构体的

字段,麻烦。这里明白就行了。
*/
typedef struct _SystemServiceDescriptorTable
{
    PVOID    ServiceTableBase;
    PULONG    ServiceCounterTableBase;
    ULONG    NumberOfService;
    ULONG    ParamTableBase;
}SystemServiceDescriptorTable,*PSystemServiceDescriptorTable;

// KeServiceDescriptorTable为ntoskrnl.exe导出
extern    PSystemServiceDescriptorTable    KeServiceDescriptorTable;

// 定义一下NtOpenProcess的原型,下面如果用汇编调用就不用定义了,但是我想尽量不用汇编
typedef    NTSTATUS    (__stdcall *NTOPENPROCESS)( OUT PHANDLE ProcessHandle,
                                                

IN ACCESS_MASK AccessMask,
                                                

IN POBJECT_ATTRIBUTES ObjectAttributes,
                                                

IN PCLIENT_ID ClientId
                                                

);

NTOPENPROCESS    RealNtOpenProcess;

// 定义函数原型
VOID Hook();
VOID Unhook();
VOID OnUnload(IN PDRIVER_OBJECT DriverObject);

// 真实的函数地址,我们会在自定义的函数中调用
ULONG    RealServiceAddress;

// 需要被驱动保护的进程ID
HANDLE    MyPID;

// 自定义的NtOpenProcess函数
NTSTATUS __stdcall MyNtOpenProcess( OUT    PHANDLE ProcessHandle,
                    IN    ACCESS_MASK DesiredAccess,
                    IN    POBJECT_ATTRIBUTES ObjectAttributes,
                    IN    PCLIENT_ID ClientId )
{
    NTSTATUS    rc;
    ULONG        PID;
     
    //DbgPrint( "NtOpenProcess() called.\n" );
     
    rc = (NTSTATUS)(NTOPENPROCESS)RealNtOpenProcess( ProcessHandle, DesiredAccess,

ObjectAttributes, ClientId );
     
    if( (ClientId != NULL) )
    {
        PID = (ULONG)ClientId->UniqueProcess;
        //DbgPrint( "%d was opened,Handle is %d.\n", PID, (ULONG)ProcessHandle );
         
        // 如果进程PID是1520,直接返回权限不足,并将句柄设置为空
        if( PID == 1520 )
        {
            DbgPrint( "Some want to open pid 1520!\n" );
            
            ProcessHandle = NULL;
                        
            rc = STATUS_ACCESS_DENIED;
        }
    }
     
    return rc;
}

// 驱动入口
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath )
{
    DriverObject->DriverUnload = OnUnload;

    Hook();
     
    return STATUS_SUCCESS;
}

// 驱动卸载
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
    Unhook( );
}

//  此处修改SSDT中的NtOpenProcess服务地址
VOID Hook()
{
    ULONG            Address;
     
    // 0x7A为Winxp+SP2下NtOpenProcess服务ID号
    // Adress是个地址A,这个地址的数据还是一个地址B,这个地址B就是NtOpenProcess的地址了
    // (ULONG)KeServiceDescriptorTable->ServiceTableBase就是温家堡的第一个房间
    // Address是第7A个房间。
    Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;

    // 取得地址A的值,也就是NtOpenProcess服务的地址了,保存原来NtOpenProcess的地址以后恢

复用
    RealServiceAddress = *(ULONG*)Address;
     
    RealNtOpenProcess = (NTOPENPROCESS)RealServiceAddress;
     
    DbgPrint( "Address of Real NtOpenProcess: 0x%08X\n", RealServiceAddress );

    DbgPrint(" Address of MyNtOpenProcess: 0x%08X\n", MyNtOpenProcess );

    // 去掉内存保护,为什么这样就去掉了呢?
    __asm
    {
        cli
        mov    eax, cr0
        and    eax, not 10000h
        mov    cr0, eax
    }
     
    // 修改SSDT中NtOpenProcess服务的地址
   *((ULONG*)Address) = (ULONG)MyNtOpenProcess;

    // 恢复内存保护
    __asm
    {
        mov    eax, cr0
        or    eax, 10000h
        mov    cr0, eax
        sti
    }
}

//////////////////////////////////////////////////////
VOID Unhook()
{
   ULONG   Address;
   Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;

    __asm
    {
        cli
        mov    eax, cr0
        and    eax, not 10000h
        mov    cr0, eax
    }

    // 还原SSDT
    *((ULONG*)Address) = (ULONG)RealServiceAddress;
     
    __asm
    {
        mov    eax, cr0
        or    eax, 10000h
        mov    cr0, eax
        sti
    }

    DbgPrint("Unhook");
}
看了别人的一段代码,请问为什么
__asm
    {
        cli
        mov    eax, cr0
        and    eax, not 10000h
        mov    cr0, eax
    }
就可以去掉windows内存保护了呢····

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

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
知道了···谢谢···
2009-7-2 17:27
0
雪    币: 45
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
cr0寄存器中有内存保护信息的。不过这寄存器可以自己改写么……真没试过……
2009-7-3 00:13
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
把cr0寄存器的16位改为0,就可以读写了····这段代码可能只对纯净的SSDT环境有用吧
2009-7-3 08:05
0
游客
登录 | 注册 方可回帖
返回
//