阅读:2134回复:18
为什么我hook ZwOpenProcess失效了
有一个奇怪的程序,看起来似乎只使用了一个简单的用于port IO的driver(如何确信某个程序使用了哪些driver?)。而当我通过KeServiceDescriptorTable->ServiceTable的方式编写driver去hook ZwOpenProcess的时候,一开始工作的还好,一旦这个程序启动后,我的hook马上失效。后来用softice查看KeServiceDescriptorTable->ServiceTable,发现系统服务表已经不知什么时候被改回原样了。我使用bpm KeServiceDescriptorTable->ServiceTable,断点无效。
各位大虾帮忙想想,这个奇怪的程序可能使用了哪些技术?在我的driver先运行的情况下,仍然能够恢复系统服务表,而且不被bpm拦下。难道系统服务表在内核中还有备份? |
|
最新喜欢:![]() |
沙发#
发布于:2005-06-18 05:00
好像已经搞定了,谢谢各位大哥!
|
|
板凳#
发布于:2005-06-17 23:58
[quote大哥,目前我的进展如下: 1.它如果不调用NtOpenProcess,它可以调用PsLookupProcessByProcessId,ObOpenObjectByPointer来达到同样的目的 2.你可以调用ObReferenceObjectByHandle获得EPROCESS的指针,从中获得Pid,这样做就只能硬编码了 [/quote] 原来不使用NtOpenProcess,也还有这么多办法可以打开进程,开眼界了... 应该不会有什么办法,在不使用NtCreateThread的情况下也能创建线程吧?除非他把NtCreateThread的代码自己写一遍,不过那恐怕也太变态了一点... |
|
地板#
发布于:2005-06-17 19:32
[quote大哥,目前我的进展如下:
1.我hook ntosknrl!NtOpenProcess成功了,看到了那个程序在试图打开我的进程,并且被我拦截了,给他返回一个空句柄和一个错误值。 2.我hook ntosknrl!NtCreateThread也成功了,看到了那个程序在试图给我创建远线程,而且它还煞有介事的传入了我的进程句柄,天知道它是怎么得到的。 我想,如果我能够事先判断出它在给我创建远线程,那么只要拦截掉NtCreateThread,应该就大功告成了。可是,在远线程没有创建好的时候,我只知道一个进程handle,并不知道这个handle所指的进程的ID是什么,也就没法判断。 有什么办法能通过进程handle知道进程ID吗? [/quote] 1.它如果不调用NtOpenProcess,它可以调用PsLookupProcessByProcessId,ObOpenObjectByPointer来达到同样的目的 2.你可以调用ObReferenceObjectByHandle获得EPROCESS的指针,从中获得Pid,这样做就只能硬编码了 |
|
地下室#
发布于:2005-06-17 16:57
[quote][quote][quote]我看了一下,ntdll中导出了NtOpenProcess和ZwOpenProcess,而两者实际上是一回事。ntosknrl中也导出了NtOpenProcess和ZwOpenProces,而两者完全不同:ntosknrl!NtOpenProcess实际上是“正常的”SSDT入口,而ntosknrl!ZwOpenProcess,天知道是干什么的,呵呵。 改正常ntosknrl!NtOpenProcess的入口代码,注意不要忘了页面的属性 [/quote] 终于能够修改ntosknrl!NtOpenProcess的入口代码了,呵呵。我从detours中抽取了和ring3无关的代码和必要的功能,做了一个精简版的detours并且成功的hook了NtOpenProcess。可是仍然有问题: 1.前面说的那个奇怪的程序,它Open我的进程,被我成功的拦截了。可是在这种情况下,它仍然在我的进程中创建了一个远线程(通过icesword看到的)。真是奇怪,明明通过debug信息看到它Open我的进程,并且已经被拦截了,可它仍然能创建远线程,它是怎么做到的? 2.我试图再把ntosknrl!NtCreateThread也hook了,但ntddk居然没有NtCreateThread这个symbol。我能想到的办法是在ring3计算出ntosknrl!NtCreateThread的相对地址,然后再传给ring0去hook,但是这样做有点麻烦(不好意思,我是懒人)。有没有什么更直接的方法? 3.更让我担心的是,万一我把ntosknrl!NtCreateThread也hook了以后,那个奇怪的程序还是能创建远线程,那我就真的是撞鬼了...各位大侠仔细考虑一下,如果由你来编写那个奇怪的程序,你能怎么做,在被hook了NtOpenProcess和NtCreateThread依然创建远线程?需要说明的是,我的程序是可以先于它执行的。 bmyyyud,zhaock大侠,帮忙帮到底,讨论一下这几个问题吧。小弟盼求回复! [/quote] 其实既然这个程序能修改SDT,说明它已经在ring 0了,跟你的程序也就在伯仲之间了,NtOpenProcess只不过是打开进程,而它可以不通过这个函数,PsActiveProcess是当前的活动进程链表,可以用这个,而且还可以在内存中搜索PCB来达到目的,所以没有绝对的胜利者。只有针对性的胜利者。 其实你这个修改ntosknrl!NtOpenProcess的入口代码一般就是修改第一条语句,可是我要是略往后移动一点呢,不就绕过去了吗?更别说上面的方法了! 所以只能分析这个怪程序,你可以贴上来,让大家都看看 [/quote] 大哥,目前我的进展如下: 1.我hook ntosknrl!NtOpenProcess成功了,看到了那个程序在试图打开我的进程,并且被我拦截了,给他返回一个空句柄和一个错误值。 2.我hook ntosknrl!NtCreateThread也成功了,看到了那个程序在试图给我创建远线程,而且它还煞有介事的传入了我的进程句柄,天知道它是怎么得到的。 我想,如果我能够事先判断出它在给我创建远线程,那么只要拦截掉NtCreateThread,应该就大功告成了。可是,在远线程没有创建好的时候,我只知道一个进程handle,并不知道这个handle所指的进程的ID是什么,也就没法判断。 有什么办法能通过进程handle知道进程ID吗? |
|
5楼#
发布于:2005-06-17 09:10
[quote][quote]我看了一下,ntdll中导出了NtOpenProcess和ZwOpenProcess,而两者实际上是一回事。ntosknrl中也导出了NtOpenProcess和ZwOpenProces,而两者完全不同:ntosknrl!NtOpenProcess实际上是“正常的”SSDT入口,而ntosknrl!ZwOpenProcess,天知道是干什么的,呵呵。 改正常ntosknrl!NtOpenProcess的入口代码,注意不要忘了页面的属性 [/quote] 终于能够修改ntosknrl!NtOpenProcess的入口代码了,呵呵。我从detours中抽取了和ring3无关的代码和必要的功能,做了一个精简版的detours并且成功的hook了NtOpenProcess。可是仍然有问题: 1.前面说的那个奇怪的程序,它Open我的进程,被我成功的拦截了。可是在这种情况下,它仍然在我的进程中创建了一个远线程(通过icesword看到的)。真是奇怪,明明通过debug信息看到它Open我的进程,并且已经被拦截了,可它仍然能创建远线程,它是怎么做到的? 2.我试图再把ntosknrl!NtCreateThread也hook了,但ntddk居然没有NtCreateThread这个symbol。我能想到的办法是在ring3计算出ntosknrl!NtCreateThread的相对地址,然后再传给ring0去hook,但是这样做有点麻烦(不好意思,我是懒人)。有没有什么更直接的方法? 3.更让我担心的是,万一我把ntosknrl!NtCreateThread也hook了以后,那个奇怪的程序还是能创建远线程,那我就真的是撞鬼了...各位大侠仔细考虑一下,如果由你来编写那个奇怪的程序,你能怎么做,在被hook了NtOpenProcess和NtCreateThread依然创建远线程?需要说明的是,我的程序是可以先于它执行的。 bmyyyud,zhaock大侠,帮忙帮到底,讨论一下这几个问题吧。小弟盼求回复! [/quote] 其实既然这个程序能修改SDT,说明它已经在ring 0了,跟你的程序也就在伯仲之间了,NtOpenProcess只不过是打开进程,而它可以不通过这个函数,PsActiveProcess是当前的活动进程链表,可以用这个,而且还可以在内存中搜索PCB来达到目的,所以没有绝对的胜利者。只有针对性的胜利者。 其实你这个修改ntosknrl!NtOpenProcess的入口代码一般就是修改第一条语句,可是我要是略往后移动一点呢,不就绕过去了吗?更别说上面的方法了! 所以只能分析这个怪程序,你可以贴上来,让大家都看看 |
|
|
6楼#
发布于:2005-06-17 00:50
[quote]以前讨论过,KMK还提供了一个老外做的恢复SDT的link 使用的什么方法?根据ntoskrnl中输出的函数检测SDT中每个项,不相同的话就恢复吗?可以再贴下那个link吗?谢谢了 :D [/quote] 我倒是找到了一个中国人做的恢复SDT的程序,如下所示: http://www.nsfocus.net/index.php?act=magazine&do=view&mid=2119 |
|
7楼#
发布于:2005-06-17 00:45
[quote]我看了一下,ntdll中导出了NtOpenProcess和ZwOpenProcess,而两者实际上是一回事。ntosknrl中也导出了NtOpenProcess和ZwOpenProces,而两者完全不同:ntosknrl!NtOpenProcess实际上是“正常的”SSDT入口,而ntosknrl!ZwOpenProcess,天知道是干什么的,呵呵。 改正常ntosknrl!NtOpenProcess的入口代码,注意不要忘了页面的属性 [/quote] 终于能够修改ntosknrl!NtOpenProcess的入口代码了,呵呵。我从detours中抽取了和ring3无关的代码和必要的功能,做了一个精简版的detours并且成功的hook了NtOpenProcess。可是仍然有问题: 1.前面说的那个奇怪的程序,它Open我的进程,被我成功的拦截了。可是在这种情况下,它仍然在我的进程中创建了一个远线程(通过icesword看到的)。真是奇怪,明明通过debug信息看到它Open我的进程,并且已经被拦截了,可它仍然能创建远线程,它是怎么做到的? 2.我试图再把ntosknrl!NtCreateThread也hook了,但ntddk居然没有NtCreateThread这个symbol。我能想到的办法是在ring3计算出ntosknrl!NtCreateThread的相对地址,然后再传给ring0去hook,但是这样做有点麻烦(不好意思,我是懒人)。有没有什么更直接的方法? 3.更让我担心的是,万一我把ntosknrl!NtCreateThread也hook了以后,那个奇怪的程序还是能创建远线程,那我就真的是撞鬼了...各位大侠仔细考虑一下,如果由你来编写那个奇怪的程序,你能怎么做,在被hook了NtOpenProcess和NtCreateThread依然创建远线程?需要说明的是,我的程序是可以先于它执行的。 bmyyyud,zhaock大侠,帮忙帮到底,讨论一下这几个问题吧。小弟盼求回复! |
|
8楼#
发布于:2005-06-16 13:33
以前讨论过,KMK还提供了一个老外做的恢复SDT的link 使用的什么方法?根据ntoskrnl中输出的函数检测SDT中每个项,不相同的话就恢复吗?可以再贴下那个link吗?谢谢了 :D |
|
9楼#
发布于:2005-06-14 08:24
[quote][quote]我看了一下,ntdll中导出了NtOpenProcess和ZwOpenProcess,而两者实际上是一回事。ntosknrl中也导出了NtOpenProcess和ZwOpenProces,而两者完全不同:ntosknrl!NtOpenProcess实际上是“正常的”SSDT入口,而ntosknrl!ZwOpenProcess,天知道是干什么的,呵呵。 改正常ntosknrl!NtOpenProcess的入口代码,注意不要忘了页面的属性 [/quote] 页面的属性怎么改呢,不好意思,我是新手,ring3下用惯了VirtualProtect,ring0下有点无所适从...... [/quote] 看PDE和PTE的结构 |
|
|
10楼#
发布于:2005-06-14 08:23
我看了一下,ntdll中导出了NtOpenProcess和ZwOpenProcess,而两者实际上是一回事。ntosknrl中也导出了NtOpenProcess和ZwOpenProces,而两者完全不同:ntosknrl!NtOpenProcess实际上是“正常的”SSDT入口,而ntosknrl!ZwOpenProcess,天知道是干什么的,呵呵。 我看了一下,确实ntdll导出的这两个其实是一个地址 ntosknrl!ZwOpenProcess好像从来未被调用 |
|
|
11楼#
发布于:2005-06-13 20:15
[quote]我看了一下,ntdll中导出了NtOpenProcess和ZwOpenProcess,而两者实际上是一回事。ntosknrl中也导出了NtOpenProcess和ZwOpenProces,而两者完全不同:ntosknrl!NtOpenProcess实际上是“正常的”SSDT入口,而ntosknrl!ZwOpenProcess,天知道是干什么的,呵呵。 改正常ntosknrl!NtOpenProcess的入口代码,注意不要忘了页面的属性 [/quote] 页面的属性怎么改呢,不好意思,我是新手,ring3下用惯了VirtualProtect,ring0下有点无所适从...... |
|
12楼#
发布于:2005-06-13 17:09
我看了一下,ntdll中导出了NtOpenProcess和ZwOpenProcess,而两者实际上是一回事。ntosknrl中也导出了NtOpenProcess和ZwOpenProces,而两者完全不同:ntosknrl!NtOpenProcess实际上是“正常的”SSDT入口,而ntosknrl!ZwOpenProcess,天知道是干什么的,呵呵。 改正常ntosknrl!NtOpenProcess的入口代码,注意不要忘了页面的属性 |
|
|
13楼#
发布于:2005-06-13 16:45
我看了一下,ntdll中导出了NtOpenProcess和ZwOpenProcess,而两者实际上是一回事。ntosknrl中也导出了NtOpenProcess和ZwOpenProces,而两者完全不同:ntosknrl!NtOpenProcess实际上是“正常的”SSDT入口,而ntosknrl!ZwOpenProcess,天知道是干什么的,呵呵。
言归正转,既然hook SSDT的方法这么容易被别人破掉(把入口换回NtOpenProcess就可以了),那么有没有其他方法?看有的资料上说可以换int 2e的中断处理函数,而xp中既然用sysenter/syscall了,看来这一招也不灵。有没有其他的办法呢? |
|
14楼#
发布于:2005-06-13 15:48
[quote]ntoskrnl.exe引出的NtOpenProcess和ZwOpenProcess有什么区别呢?是不是前者是SSDT的正常入口? 你可以自己用ice看一下,ZwOpenProcess mov eax,xxx ... int 2e 然后到KiSystemService,会根据xxx调用NtOpenProcess,NtOpenProcess是SSDT的正常入口 [/quote] 不太对,调用int 2e是ntdll中函数的做法,而且在xp及以后就改成sysenter了,ntdll中好像没有ZwOpenProcess(这个我需要先验证一下,回头再说) 在ntoskrnl中有个ZwOpenProcess是mov eax,xxx...然后直接call KiSystemService的,它好像和NtOpenProcess同在一个4M的页中,但似乎不在一个section中,据说存在ntoskrnl中存在这两个版本的差别是Zw版首先需要通过参数validation再调用nt版的 |
|
|
15楼#
发布于:2005-06-13 13:45
ntoskrnl.exe引出的NtOpenProcess和ZwOpenProcess有什么区别呢?是不是前者是SSDT的正常入口? 你可以自己用ice看一下,ZwOpenProcess mov eax,xxx ... int 2e 然后到KiSystemService,会根据xxx调用NtOpenProcess,NtOpenProcess是SSDT的正常入口 |
|
16楼#
发布于:2005-06-13 11:44
ntoskrnl.exe引出的NtOpenProcess和ZwOpenProcess有什么区别呢?是不是前者是SSDT的正常入口? 另外,我确实bpm KeServiceDescriptorTable->ServiceTable+4*X,不过还是拦不下来,估计是其他程序进行了反跟踪吧。 |
|
17楼#
发布于:2005-06-13 09:47
以前讨论过,KMK还提供了一个老外做的恢复SDT的link
|
|
|
18楼#
发布于:2005-06-12 23:38
有一个奇怪的程序,看起来似乎只使用了一个简单的用于port IO的driver(如何确信某个程序使用了哪些driver?)。而当我通过KeServiceDescriptorTable->ServiceTable的方式编写driver去hook ZwOpenProcess的时候,一开始工作的还好,一旦这个程序启动后,我的hook马上失效。后来用softice查看KeServiceDescriptorTable->ServiceTable,发现系统服务表已经不知什么时候被改回原样了。我使用bpm KeServiceDescriptorTable->ServiceTable,断点无效。 NtOpenProcess在ntoskrnl.exe引出了,从exports table就可以获得它的地址,去比较服务表中的地址,如果不一样,就可以恢复回去。 假设NtOpenProcess在服务表中的Id是x,你应该这样设 bpm KeServiceDescriptorTable->ServiceTable+4*X才对, 你那样设置当然截不住了 |
|