|
|
|
|
|
|
|
Windows内核调试
帖子发起人: ala 发起时间: 2008-10-08 18:35 下午 回复: 7
|
帖子排序:
|
|
|
|
2008-10-08, 18:35 下午
|
ala
注册: 2008-10-08
发 贴: 3
|
Hook NtCreateMutant 时OBJECT_ATTRIBUTES 总是有问题
|
|
|
|
为什么也总是发现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
);
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-10-08, 18:38 下午
|
ala
注册: 2008-10-08
发 贴: 3
|
|
|
为什么也总是发现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
);
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-10-08, 22:19 下午
|
格蠹老雷
注册: 2005-12-19
发 贴: 1,303
|
|
|
OBJECT_ATTRIBUTES结构是所谓的不透明结构(opaque structure),因此是不可以像你代码里那样直接将一个结构赋给另一个结构的。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-10-09, 01:24 上午
|
MJ0011
注册: 2008-04-24
发 贴: 112
|
|
|
RltCopyMemory(ObjectAttributesNew , &ObjectAttributes , sizeof(ObjectAttributesNew ));
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-10-09, 01:28 上午
|
MJ0011
注册: 2008-04-24
发 贴: 112
|
|
|
另外,楼主出现的问题原因是这样的:
你直接调用了原始的g_pvOriginNtCreateMutant,此时你的线程前个模式还是UserMode,而你的ObjectAttributesNew 是在内核空间的堆栈变量,在前个模式是UserMode,Nt*等函数会对传入的参数地址做ProbeForRead 操作,拒绝内核地址,因此会返回0xc0000005
解决方法是调用手动将前个模式该成KernelMode,调用后改回
或者直接调用ZwCreateMutant,让KiSystemService为你做模式转换。
不过前提是你要对所有你传递给函数的,由RING3传递上来的参数做详细检查,因为KernelMode下调用不会对你的参数做任何检查的,如果你不检查,就会引发内核拒绝服务(KERNEL DOS) 攻击漏洞的可能。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-11-04, 00:28 上午
|
ala
注册: 2008-10-08
发 贴: 3
|
Re: Hook NtCreateMutant 时OBJECT_ATTRIBUTES 总是有问题
|
|
|
|
解决方法是调用手动将前个模式该成KernelMode
----这个怎么做啊?
另:在驱动里面怎么调用ZwCreateMutant?取得ntdll的ZwCreateMutant?要是NtCreateMutant的调用者是驱动会不会有问题?
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-11-04, 10:29 上午
|
王宇
注册: 2007-05-08
发 贴: 306
|
Re: Hook NtCreateMutant 时OBJECT_ATTRIBUTES 总是有问题
|
|
|
|
马甲同学的意思就是在调试器里将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.
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-11-05, 18:47 下午
|
nightxie
注册: 2008-06-09
发 贴: 43
|
Re: Hook NtCreateMutant 时OBJECT_ATTRIBUTES 总是有问题
|
|
|
|
其实就是NtCreateMutant中有这个东西。。。
try {
PreviousMode = KeGetPreviousMode();
if (PreviousMode != KernelMode) {
ProbeForWriteHandle(MutantHandle);
......
} except(ExSystemExceptionFilter()) {
......
MJ前辈是改Kthread->PreviousMode = 0
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
高端调试 » 软件调试 » Windows内核调试 » Re: 纠正描述
|
|
|
|
|
|