首页
社区
课程
招聘
开源内核中调用ZwQueryVirtualMemory查询目标内存地址保护属性源码
发表于: 2021-7-10 14:23 8846

开源内核中调用ZwQueryVirtualMemory查询目标内存地址保护属性源码

2021-7-10 14:23
8846

看到大手子们都在分享自己的学习成果,我也分享一个叭,是在内核中调用ZwQueryVirtualMemory查询目标内存地址的保护属性或者Type,你想查什么直接改即可,欢迎大家多多交流,已测试没有毛病,废话不多说直接上代码。

========================================================
附上内存属性具体信息:
PAGE_NOACCESS =1 任何访问该区域的操作将被拒绝(无权限)
PAGE_READONLY =2 试图写入或执行页面中的代码将引发访问违规(只读)
PAGE_READWRITE =4 试图执行页面中的代码将引发访问违规(可读可写)
PAGE_WRITECOPY =8 写时复制
PAGE_EXECUTE=16 试图读取或写入页面将引发访问违规
PAGE_EXECUTE_READ =32 试图写入页面将引发访问违规
PAGE_EXECUTE_READWRITE =64 对页面执行任何操作都不会引发访问违规
PAGE_EXECUTE_WRITECOPY =128试图执行页面中的代码将引发访问违规。试图写入页面将使系统为进程单独创建一份该页面的私有副本(以页交换文件为后备存储器)

========================================================

下面随意取了一个受某AC保护的程序,可以看到取出属性是32,对照表看是PAGE_EXECUTE_READ,禁止写入。

// 此为主要操作代码且全部在内核,应用层直接调用DevIoc函数通讯即可//
ULONG MyQueryVirtualMemoryBasicInfo(IN HANDLE ProcessHandle, IN PVOID DesiredAddress) //传入目标进程PID,和内存地址
{
    MEMORY_BASIC_INFORMATION mbi; //内存属性结构
    ULONG Protect; //初始化保护类型
    if ((ULONG_PTR)DesiredAddress >= 0x70000000 && (ULONG_PTR)DesiredAddress < 0x80000000)
        DesiredAddress = (PVOID)0x70000000;
 
    HANDLE hProcess = NULL;
    CLIENT_ID stClientId = { 0 };
    OBJECT_ATTRIBUTES objectAttributs = { 0 };
    stClientId.UniqueProcess = ProcessHandle;
    stClientId.UniqueThread = 0;
    InitializeObjectAttributes(&objectAttributs, 0, 0, 0, 0);
    // 打开进程,获取进程句柄
    NTSTATUS status = ZwOpenProcess(&hProcess, 1, &objectAttributs, &stClientId);
    if (!NT_SUCCESS(status))
    {
        return -32767;//自己看的,没打开成功
    }
    if (NULL != hProcess)
    {
 
        if (!NT_SUCCESS(ZwQueryVirtualMemory(hProcess, DesiredAddress, MemoryBasicInformation, &mbi, sizeof(mbi), NULL)))
            return -32768// 查询操作失败自定义返回
 
        Protect = mbi.Protect; //需要返回的信息可以是保护也可以是状态也可以是类型 Protect/State/type
    }
    ZwClose(hProcess);  //关闭打开的句柄
    return Protect;   //返回需要的信息
 
}
 
 
 
//然后下面是驱动IO通讯中的代码//
 
    case IOCTL_IO_QueryVirtualMemory: //自定义
    {
        ULONG PtExw;
 
        PtExw = QueryVirtualMemoryBasicInfo(((PDataStruct)InputData)->Pid, ((PDataStruct)InputData)->VMAddress);//传入的结构体 PID和地址
 
        RtlCopyMemory(OutputData, &PtExw, OutputDataLength);//复制到返回信息,应用层就可以接收到了
 
        Status = STATUS_SUCCESS;
        break;
    }
 
 
//下面是需要用到的结构体等信息//
//可以直接引入这三个常用的就有
//#inculd "ntifs.h"
//#inculd "ntdef.h"
//#inculd "wdm.h"
typedef struct _MEMORY_BASIC_INFORMATION {
    PVOID BaseAddress;
    PVOID AllocationBase;
    ULONG AllocationProtect;
#if defined (_WIN64)
    USHORT PartitionId;
#endif
    SIZE_T RegionSize;
    ULONG State;
    ULONG Protect;
    ULONG Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
 
typedef struct _OBJECT_ATTRIBUTES {
    ULONG Length;
    HANDLE RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
    PVOID SecurityDescriptor;        // Points to type SECURITY_DESCRIPTOR
    PVOID SecurityQualityOfService;  // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
// 此为主要操作代码且全部在内核,应用层直接调用DevIoc函数通讯即可//
ULONG MyQueryVirtualMemoryBasicInfo(IN HANDLE ProcessHandle, IN PVOID DesiredAddress) //传入目标进程PID,和内存地址
{
    MEMORY_BASIC_INFORMATION mbi; //内存属性结构
    ULONG Protect; //初始化保护类型
    if ((ULONG_PTR)DesiredAddress >= 0x70000000 && (ULONG_PTR)DesiredAddress < 0x80000000)
        DesiredAddress = (PVOID)0x70000000;
 
    HANDLE hProcess = NULL;
    CLIENT_ID stClientId = { 0 };
    OBJECT_ATTRIBUTES objectAttributs = { 0 };
    stClientId.UniqueProcess = ProcessHandle;
    stClientId.UniqueThread = 0;
    InitializeObjectAttributes(&objectAttributs, 0, 0, 0, 0);
    // 打开进程,获取进程句柄
    NTSTATUS status = ZwOpenProcess(&hProcess, 1, &objectAttributs, &stClientId);
    if (!NT_SUCCESS(status))
    {
        return -32767;//自己看的,没打开成功
    }
    if (NULL != hProcess)
    {
 
        if (!NT_SUCCESS(ZwQueryVirtualMemory(hProcess, DesiredAddress, MemoryBasicInformation, &mbi, sizeof(mbi), NULL)))
            return -32768// 查询操作失败自定义返回
 
        Protect = mbi.Protect; //需要返回的信息可以是保护也可以是状态也可以是类型 Protect/State/type
    }
    ZwClose(hProcess);  //关闭打开的句柄
    return Protect;   //返回需要的信息
 
}
 
 
 
//然后下面是驱动IO通讯中的代码//
 

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-7-10 20:10 被月生沧海编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (6)
雪    币: 143
活跃值: (780)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
2021-7-10 14:28
0
雪    币: 6977
活跃值: (1786)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2021-7-10 15:12
1
雪    币: 246
活跃值: (4427)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
4
能不能分享一下这个百万读写的源码
2021-7-10 20:16
0
雪    币: 3312
活跃值: (3913)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
啊这,还以为你是自己实现了这个函数,原来只是ZwQueryVirtualMemory包装一下
2021-7-10 21:01
0
雪    币: 143
活跃值: (780)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
Mr.hack 啊这,还以为你是自己实现了这个函数,原来只是ZwQueryVirtualMemory包装一下
标题不是写了嘛就说调用实现呀。。
2021-7-11 08:43
0
雪    币: 1041
活跃值: (733)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
可以推荐下Windows驱动入门教程吗想学学这方面的
2021-7-26 22:43
0
游客
登录 | 注册 方可回帖
返回
//