能力值:
( LV12,RANK:760 )
|
-
-
2 楼
内核中NTAPI和ZWAPI是不一样的东西,请自己巩固一下基础知识吧~~~~吐槽无力啊~
|
能力值:
( 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不分,我就随便猜了
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
|
能力值:
( LV3,RANK:30 )
|
-
-
5 楼
谢谢ITSailor的回复,由于ZwAllocateVirtualMemory没有导出,我就用的网上最常用的一种方法,获取的地址。不过确如你所说,是通过sysenter进入了内核,然后传递给NtAllocateVirtualMemory完成。看来是我这里没有注意,应该直接通过SSDT表获取API地址的。
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
SSDT里都是Nt系列函数!
ZwAllocateVirtualMemory没有导出?你看看WDK文档吧,都有详细说明,怎么会没导出呢。
|
能力值:
( 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
);
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
ULONG uExtraMem = 0x1000;
NtAllocateVirtualMemory(ProcessHandle,BaseAddress,0,&uExtraMem,MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,PAGE_EXECUTE_READWRITE);
参数里的&uExtraMem也是应用层的?
|
能力值:
( LV3,RANK:30 )
|
-
-
9 楼
这个是size啊
|
能力值:
( LV3,RANK:30 )
|
-
-
10 楼
现在修改内存属性的,我通过SSDT表获取了NtProtectVirtualMemory的地址,但是调用了仍然是返回那个错误值。可以确定不是Zw和Nt的问题。
我是拦截了IE主模块的加载,然后想修改这个模块映射到内存之后的section的属性,但是总是不成功。只有最开始时奇迹的成功过一次。我有个疑问,当.exe模块映射入内存后,由于映射时已经指定了权限,那我们到底有没有权限再去修改呢?我试着在映射时将Win32Protect参数修改为PAGE_EXECUTE_READWRITE,但是不能加载成功的、
|
能力值:
( 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,应用层能修改内核数据,这是多大的隐患啊!!!
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
刚才告诉过你了,SSDT都是Nt系列函数,内核你要用Zw系列函数
内存页面属性可以改,这个不用质疑,我就经常申请一块PAGE_EXECUTE_READWRITE的内存,写入代码,然后执行,就是你这个时机能不能改,我没测试过,不能下结论
|
能力值:
( LV3,RANK:30 )
|
-
-
13 楼
“SSDT都是Nt系列函数,内核你要用Zw系列函数”
可是Zw系列都是通过sysenter进入内核调用的Nt系列函数啊??
|
能力值:
( LV3,RANK:30 )
|
-
-
14 楼
既然ITSailor大牛对这个运用很熟悉,可不可以贴一段比较完整的可以调用成功的实例代码出来,我好研究对比下,看是我调用存在错误,还是时机不对。谢谢大牛了~
|
能力值:
( 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就不会做参数检查。
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
能贴代码我早就贴出来了,用代码说话是最好的,但是抱歉,都是公司代码,我无法提供。
你这样吧,ZwAllocateVirtualMemory是导出的,也是归档的,WDK文档有详细的说明,你用这个试试,就不用用应用层变量,直接全是内核变量就行,如果这个成功了,那就是调用Nt系列函数导致的。
|
能力值:
( LV9,RANK:160 )
|
-
-
17 楼
好像都是在讨论怎么得到地址,ZwAllocateVirtualMemory没有啥限制,直接导出了,需要注意的只是NtProtectVirtualMemory里面的几个需要指针的参数需要一个用户态的指针,如果传递内核地址会失败
|
能力值:
( LV3,RANK:30 )
|
-
-
18 楼
好吧,是我不够仔细,研究的也不够深入。。
等明天去搞定了,再来回帖。
向大牛致敬~感谢各位的回复~
|
能力值:
( LV4,RANK:50 )
|
-
-
19 楼
一句话说明白吧
NT函数直接调用是r3的特权.
内核需要从zw间接调用nt函数
而ntdll中实现的zw系列函数只是个封装.仍然直接调用内核的nt函数
NT函数中有检测 如果是usermode则执行一系列检查,所以内核地址+usermode是无法通过校验的.导致失败
不过我还是没明白楼主遇到的问题的原因
|
能力值:
( LV3,RANK:30 )
|
-
-
20 楼
ZwAllocateVirtualMemory调用可以成功了,可是ZwProtectVirtualMemory调用还是失败啊!并且NtProtectVirtualMemory调用也是失败的,虽然两者的NTSTATUS返回错误码不同,但都不能成功!
继续请教大牛,为什么出现这种情况呢?
|
能力值:
( LV3,RANK:30 )
|
-
-
21 楼
能不能有大牛贴一个在驱动中可以成功调用ZwProtectVirtualMemory的例子?
或者给出如何获得该API地址,如何调用的代码片段。
相信这个问题是很多新手都会遇到的,网上能搜到的资料中,偏理论和思路的多,给出实例的少,但理论和思路并不一定能帮助解决问题,希望会的人不吝赐教!
|
|
|