首页
社区
课程
招聘
[求助]驱动编程——ZwAllocateVirtualMemory和ZwProtectVirtualMemory调用均不成功
发表于: 2013-1-30 15:03 27017

[求助]驱动编程——ZwAllocateVirtualMemory和ZwProtectVirtualMemory调用均不成功

2013-1-30 15:03
27017
写注入驱动,hook了NtMapViewOfSection,在其内进行动态分配内存的操作,如下:
ULONG uExtraMem = 0x1000;
ns =NtAllocateVirtualMemory(ProcessHandle,BaseAddress,0,&uExtraMem,MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,PAGE_EXECUTE_READWRITE);
其中,ProcessHanle为-1,改为PsGetCurrentProcess()之后仍然不成功。
地址BaseAddress是有值的,不成功,改为NULL之后仍然也是不成功。
其他参数也试着变过,但仍然不成功。
返回C0000005,即Memory_VIOLATION。

而调用ZwProtectVirtualMemory,也不能成功,只有最开始成功过一次,后来调用均返回失败。调用格式如下:
ZwProtectVirtualMemory(ProcessHandle,&uBeginAddr,&uSize,PAGE_EXECUTE_READWRITE,&OldProtect);
各种参数也类似上面进行变过,但均不成功。
而返回的错误为C000004E,即STATUS_SECTION_PROTECTION,解释为"区域的视图指定了和初始视图的保护不兼容的保护"。

非常郁闷,调试两天了,都不知道问题出在哪儿。
还尝试过提升中断级,修改CR0寄存器,但均不能使这两个函数调用成功。
所以只好在这儿请教各位大牛了~拜托了~

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

收藏
免费 0
支持
分享
最新回复 (20)
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
2
内核中NTAPI和ZWAPI是不一样的东西,请自己巩固一下基础知识吧~~~~吐槽无力啊~
2013-1-30 16:13
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
你究竟是调用NtAllocateVirtualMemory还是ZwAllocateVirtualMemory啊?
在ntdll,这两个函数没有区别,但在内核这两个函数有区别的,NtAllocateVirtualMemory是实现函数,ZwAllocateVirtualMemory是把PreviousMode转化为kernelmode后,调用NtAllocateVirtualMemory。

你HOOK NtMapViewOfSection后,如果应用层调用这个函数,那么PreviousMode就是usermode,这个时候你调用NtAllocateVirtualMemory就会遭到该函数的参数检查,ProbeForWrite(***),ProbeForRead(***),这类函数就是检查传入的地址参数是否合法,什么叫合法,第一,如果是只读地址,地址指向必须可读,如果是可写地址,可写的地址必须可写。第二,也是最重要,地址必须是应用层地址,原因很简单,如果我调用NtAllocateVirtualMemory里的&uExtraMem是内核地址,还让我调用成功,那我应用层就可以修改内核数据了!!!!

这也就是为什么在内核要调用Zw(***)系列函数的原因。如果由于某些原因,必须传入内核地址,要不呢,使用Zw(***)函数,要不呢,自己切换PreviousMode为kernelmode。
另外BaseAddress必须是个PVOID*,不知道你有没有弄错

不知道你的问题是不是这个原因,你的Zw和Nt不分,我就随便猜了
2013-1-30 16:13
0
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
2013-1-30 17:20
0
雪    币: 18
活跃值: (12)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
谢谢ITSailor的回复,由于ZwAllocateVirtualMemory没有导出,我就用的网上最常用的一种方法,获取的地址。不过确如你所说,是通过sysenter进入了内核,然后传递给NtAllocateVirtualMemory完成。看来是我这里没有注意,应该直接通过SSDT表获取API地址的。

2013-1-30 18:00
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
SSDT里都是Nt系列函数!
ZwAllocateVirtualMemory没有导出?你看看WDK文档吧,都有详细说明,怎么会没导出呢。
2013-1-30 18:07
0
雪    币: 18
活跃值: (12)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
我又仔细看了下,我调用的确实是NtAllocateVirtualMemory,而且传入的地址确实为用户态地址,参数没有问题。而修改内存属性的则调用的ZwProtectVirtualMemory。
extern "C" NTSTATUS NTAPI NtAllocateVirtualMemory (
        __in HANDLE ProcessHandle,
        __inout PVOID *BaseAddress,
        __in ULONG_PTR ZeroBits,
        __inout PSIZE_T RegionSize,
        __in ULONG AllocationType,
        __in ULONG Protect
        );

2013-1-30 18:09
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
ULONG uExtraMem = 0x1000;

NtAllocateVirtualMemory(ProcessHandle,BaseAddress,0,&uExtraMem,MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,PAGE_EXECUTE_READWRITE);

参数里的&uExtraMem也是应用层的?
2013-1-30 18:11
0
雪    币: 18
活跃值: (12)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
9
这个是size啊

2013-1-30 18:26
0
雪    币: 18
活跃值: (12)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
10
现在修改内存属性的,我通过SSDT表获取了NtProtectVirtualMemory的地址,但是调用了仍然是返回那个错误值。可以确定不是Zw和Nt的问题。
我是拦截了IE主模块的加载,然后想修改这个模块映射到内存之后的section的属性,但是总是不成功。只有最开始时奇迹的成功过一次。我有个疑问,当.exe模块映射入内存后,由于映射时已经指定了权限,那我们到底有没有权限再去修改呢?我试着在映射时将Win32Protect参数修改为PAGE_EXECUTE_READWRITE,但是不能加载成功的、
2013-1-30 18:31
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
是啊,但你传入的是地址,不要忘了,NtAllocateVirtualMemory需要往地址写入申请成功的大小,所以属于地址类的,一样需要检查

如果是个size就不用检查。那我就在应用层计算内核NtCreateFile地址,然后NtAllocateVirtualMemory(-1, BaseAddress, 0, (PSIZE_T)NtCreateFile, MEM_COMMIT, PAGE_READWRITE);
NtAllocateVirtualMemory就会根据*(PSIZE_T)NtCreateFile的大小值申请内存,假如*(PSIZE_T)NtCreateFile是0x999,那么申请完后*(PSIZE_T)NtCreateFile就会被改成0x1000,应用层能修改内核数据,这是多大的隐患啊!!!
2013-1-30 18:49
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
刚才告诉过你了,SSDT都是Nt系列函数,内核你要用Zw系列函数

内存页面属性可以改,这个不用质疑,我就经常申请一块PAGE_EXECUTE_READWRITE的内存,写入代码,然后执行,就是你这个时机能不能改,我没测试过,不能下结论
2013-1-30 18:50
0
雪    币: 18
活跃值: (12)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
13
“SSDT都是Nt系列函数,内核你要用Zw系列函数”
可是Zw系列都是通过sysenter进入内核调用的Nt系列函数啊??

2013-1-30 19:04
0
雪    币: 18
活跃值: (12)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
14
既然ITSailor大牛对这个运用很熟悉,可不可以贴一段比较完整的可以调用成功的实例代码出来,我好研究对比下,看是我调用存在错误,还是时机不对。谢谢大牛了~

2013-1-30 19:10
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
内核的Zw系列函数本来就是内核的,不用通过sysenter,ntdll的Zw才需要通过sysenter进入内核。

让你看看的内核实现:

kd> uf ZwAllocateVirtualMemory
nt!ZwAllocateVirtualMemory:
804feeec b811000000      mov     eax,11h
804feef1 8d542404          lea     edx,[esp+4]
804feef5 9c                      pushfd
804feef6 6a08                  push    8
804feef8 e884f50300       call    nt!KiSystemService (8053e481)
804feefd c21800              ret     18h

通过KiSystemService 实现的,不是sysenter。第一行代码的11h,就是NtAllocateVirtualMemory在SSDT的序号。
KiSystemService 最后也是调用NtAllocateVirtualMemory来实现。
但区别是,KiSystemService 会把PreviousMode改为KernelMode,这样NtAllocateVirtualMemory就不会做参数检查。
2013-1-30 19:11
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
能贴代码我早就贴出来了,用代码说话是最好的,但是抱歉,都是公司代码,我无法提供。

你这样吧,ZwAllocateVirtualMemory是导出的,也是归档的,WDK文档有详细的说明,你用这个试试,就不用用应用层变量,直接全是内核变量就行,如果这个成功了,那就是调用Nt系列函数导致的。
2013-1-30 19:13
0
雪    币: 284
活跃值: (106)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
17
好像都是在讨论怎么得到地址,ZwAllocateVirtualMemory没有啥限制,直接导出了,需要注意的只是NtProtectVirtualMemory里面的几个需要指针的参数需要一个用户态的指针,如果传递内核地址会失败
2013-1-30 20:09
0
雪    币: 18
活跃值: (12)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
18
好吧,是我不够仔细,研究的也不够深入。。
等明天去搞定了,再来回帖。
向大牛致敬~感谢各位的回复~

2013-1-30 22:20
0
雪    币: 220
活跃值: (117)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
19
一句话说明白吧
NT函数直接调用是r3的特权.
内核需要从zw间接调用nt函数

而ntdll中实现的zw系列函数只是个封装.仍然直接调用内核的nt函数

NT函数中有检测 如果是usermode则执行一系列检查,所以内核地址+usermode是无法通过校验的.导致失败

不过我还是没明白楼主遇到的问题的原因
2013-1-31 17:15
0
雪    币: 18
活跃值: (12)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
20
ZwAllocateVirtualMemory调用可以成功了,可是ZwProtectVirtualMemory调用还是失败啊!并且NtProtectVirtualMemory调用也是失败的,虽然两者的NTSTATUS返回错误码不同,但都不能成功!
继续请教大牛,为什么出现这种情况呢?
2013-2-27 12:08
0
雪    币: 18
活跃值: (12)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
21
能不能有大牛贴一个在驱动中可以成功调用ZwProtectVirtualMemory的例子?
或者给出如何获得该API地址,如何调用的代码片段。
相信这个问题是很多新手都会遇到的,网上能搜到的资料中,偏理论和思路的多,给出实例的少,但理论和思路并不一定能帮助解决问题,希望会的人不吝赐教!
2013-2-27 17:21
0
游客
登录 | 注册 方可回帖
返回
//