Re: Hook NtCreateMutant 时OBJECT_ATTRIBUTES 总是有问题
Windows内核调试
Hook NtCreateMutant 时OBJECT_ATTRIBUTES 总是有问题
ala
2008-10-08, 18:35 下午
为什么也总是发现0xc0000005 错误? 但是不用ObjectAttributesNew 而用传进来的原始ObjectAttributes就没问题?
OBJECT_ATTRIBUTES ObjectAttributesNew;
ObjectAttributesNew=*ObjectAttributes;
////
ntStatus = ((TYPE_NtCreateMutant)g_pvOriginNtCreateMutant) (
MutantHandle,DesiredAccess,&ObjectAttributesNew,InitialOwner
);
DbgPrint("[%d] StubNtCreateMutant wsNameNew:%ws ntStatus:0x%x SecurityDescriptor:0x%x RootDirectory:0x%x pObjectName:0x%x",
KMGetCurrentProcessId(),wsNameNew,ntStatus,
ObjectAttributes->SecurityDescriptor,
ObjectAttributes->RootDirectory,
ObjectAttributes->ObjectName
);
纠正描述
ala
2008-10-08, 18:38 下午
为什么也总是发现0xc0000005 错误? 但是不用ObjectAttributesNew 而用传进来的原始ObjectAttributes就没问题?
OBJECT_ATTRIBUTES ObjectAttributesNew;
ObjectAttributesNew=*ObjectAttributes;
////
ntStatus = ((TYPE_NtCreateMutant)g_pvOriginNtCreateMutant) (
MutantHandle,DesiredAccess,&ObjectAttributesNew,InitialOwner
);
DbgPrint("[%d] StubNtCreateMutant wsNameNew:%ws ntStatus:0x%x SecurityDescriptor:0x%x RootDirectory:0x%x pObjectName:0x%x",
KMGetCurrentProcessId(),wsNameNew,ntStatus,
ObjectAttributes->SecurityDescriptor,
ObjectAttributes->RootDirectory,
ObjectAttributes->ObjectName
);
Re: 纠正描述
格蠹老雷
2008-10-08, 22:19 下午
OBJECT_ATTRIBUTES结构是所谓的不透明结构(opaque structure),因此是不可以像你代码里那样直接将一个结构赋给另一个结构的。
Re: 纠正描述
MJ0011
2008-10-09, 01:24 上午
RltCopyMemory(ObjectAttributesNew , &ObjectAttributes , sizeof(ObjectAttributesNew ));
Re: 纠正描述
MJ0011
2008-10-09, 01:28 上午
另外,楼主出现的问题原因是这样的:
你直接调用了原始的g_pvOriginNtCreateMutant,此时你的线程前个模式还是UserMode,而你的ObjectAttributesNew 是在内核空间的堆栈变量,在前个模式是UserMode,Nt*等函数会对传入的参数地址做ProbeForRead 操作,拒绝内核地址,因此会返回0xc0000005
解决方法是调用手动将前个模式该成KernelMode,调用后改回
或者直接调用ZwCreateMutant,让KiSystemService为你做模式转换。
不过前提是你要对所有你传递给函数的,由RING3传递上来的参数做详细检查,因为KernelMode下调用不会对你的参数做任何检查的,如果你不检查,就会引发内核拒绝服务(KERNEL DOS) 攻击漏洞的可能。
Re: Hook NtCreateMutant 时OBJECT_ATTRIBUTES 总是有问题
ala
2008-11-04, 00:28 上午
解决方法是调用手动将前个模式该成KernelMode
----这个怎么做啊?
另:在驱动里面怎么调用ZwCreateMutant?取得ntdll的ZwCreateMutant?要是NtCreateMutant的调用者是驱动会不会有问题?
Re: Hook NtCreateMutant 时OBJECT_ATTRIBUTES 总是有问题
王宇
2008-11-04, 10:29 上午
马甲同学的意思就是在调试器里将Call之前的压栈参数手工由 1 改为 0。
楼主请看看我整理的这篇文章:《Nt vs. Zw - Clearing Confusion on the Native API》(http://advdbg.org/dfstore/zip/Nt%20vs.%20Zw%20-%20Clearing%20Confusion%20on%20the%20Native%20API.pdf)
里面有这么一段:
The NtXxxx version of the native system service is the name of the function
itself. Thus, when a Kernel Mode component calls the NtXxxx version of the
system service, whatever is presently set into previous mode is unchanged.
Thus, it is quite possible that the Kernel component could be running on an
arbitrary User stack, with the requestor mode set to User. The system service
will not know any better, attempt to validate the request parameters, possibly
using the credentials of the arbitrary User Mode thread, and thus possibly fail
the request. Another problem here is that one step in the validation process
for a User Mode request is that all passed in buffers have either ProbeForRead
or ProbeForWrite executed on them, depending on the buffer's usage. These
routines raise exceptions if executed on Kernel Mode addresses. Therefore,
if you pass in Kernel Mode buffers with your request mode set to User, your
calls into the native API return STATUS_ACCESS_VIOLATION.
注意到最后面的错误号:STATUS_ACCESS_VIOLATION,再查一下“ntstatus.h”:
//
// MessageId: STATUS_ACCESS_VIOLATION
//
// MessageText:
//
// The instruction at "0x%08lx" referenced memory at "0x%08lx". The memory could not be "%s".
//
#define STATUS_ACCESS_VIOLATION ((NTSTATUS)0xC0000005L) // winnt
文字很简单,就不多翻译了。关于 Native API 的 Previous Mode 有一段很好的总结如下:
If you are in User Mode, use whatever variant (指 Zw* 或 Nt* 的 Native API) you think makes your code look pretty (呵呵). In Kernel Mode, use the ZwXxx routines and get your previous mode set properly (楼主的问题就在这里了), to Kernel Mode.
Re: Hook NtCreateMutant 时OBJECT_ATTRIBUTES 总是有问题
nightxie
2008-11-05, 18:47 下午
其实就是NtCreateMutant中有这个东西。。。
try {
PreviousMode = KeGetPreviousMode();
if (PreviousMode != KernelMode) {
ProbeForWriteHandle(MutantHandle);
......
} except(ExSystemExceptionFilter()) {
......
MJ前辈是改Kthread->PreviousMode = 0