阅读:3505回复:39
关于任意勾挂内核函数的的问题
我的思路是找到该函数的内存地址,反向查找页表所在的位置,修改页表的内容,然后将函数的前几个字节保存起来,并且通过一条jump指令让他跳到我的函数的地址。事后再恢复原来的内容。有愿意讨论的,请在此发表贴子或者给我发信,我的信箱在我的资料里有。
|
|
最新喜欢:zackar... |
沙发#
发布于:2002-06-21 18:00
还有《undocumented windows NT》的第四章你一定的看看,hehe
|
|
板凳#
发布于:2002-06-21 17:57
至于页目录表的问题,我觉得windows2000还是和linux差不多吧,他们应该都是简单得线性关系。但是这仅仅是停留在理论上,我还没实践所以不好说
---------------------------------------------------------------------- 不说了吧,别人是有实践的-----见《不用驱动的Ring0代码实现》,hehe |
|
地板#
发布于:2002-06-21 17:29
巴西赢了,我也把函数钩过来了。不过比较笨!
至于页目录表的问题,我觉得windows2000还是和linux差不多吧,他们应该都是简单得线性关系。但是这仅仅是停留在理论上,我还没实践所以不好说。 另外,另外楼上的大虾提到一些参考资料,网上在那儿有?我看看之后再发表意见。 等我再修改一下之后,把源码放上来!希望大家别笑我写的代码蹩脚。 给了半天没给过去,我怎么样才能给pjf分呢? |
|
地下室#
发布于:2002-06-21 16:48
刚刚看球去了,巴西赢了,happy。 大兄弟,快去回答我的ntoskrnl的问题 |
|
|
5楼#
发布于:2002-06-21 16:48
刚刚看球去了,巴西赢了,happy。
你说得不错,这就会导至“漏球”,内核调试器有时也会漏(不过原因肯定不一样啦);我没用这种方法,因为知道被钩函数开始代码,所以总是先让它在hook函数例执行开始代码再jmp回去。 |
|
6楼#
发布于:2002-06-21 16:09
我提出的问题怎么没人理睬了?难道这不是问题吗?
|
|
7楼#
发布于:2002-06-21 14:07
页目录表里的每一项即页目录项的内容为0
----------------------------------------------------------------------- 并不是每一项,而是开始的一些项与没用的项根本没映射,你用Softice一直d下去,自让会看到希望的页目录项。 事实上就你的情况根本用不到页目录项,NT的映射很有规律且简单,直接由address就可算得address所在页表项的线性地址。 |
|
8楼#
发布于:2002-06-21 13:00
另外我之所以讨论内核所在的位置,是因为内核的线性地址和物理地址之间应该存在一个简单的线性关系,那就是物理地址+内核的起始地址。linux里面是0xc0000000,而windows2000是0x80000000
----------------------------------------------------------------------------- 你又把NT与Linux混起来说,呵呵。Linux高于3G的内核空间减去3G就是物理地址,没错;但NT不是,建议反汇编一下ntoskrnl!MmGetPhysicalAddress。只有0x80000000与0xa0000000之间才有较简单的映射关系。 WinNT/2k页目录表入口地址与进程相关,每一个进程可能都不相同 ---------------------------------------------------------------------- 物理地址不同而已,NT会保持线性地址的一致性。 老哥的《小议Windows NT/2000分页机制》似乎讲得比较清楚,呵呵。也建议ysy看看《undocumented windows NT》。 |
|
9楼#
发布于:2002-06-21 12:16
假设你要hook函数 KerenelFunc,你的函数是MyFunc,你的挂接方式是保存KernelFunc的最开始的8个字节,然后在MyFunc里面你应该是这样做的吧:
MyFunc{ 1.恢复原来的前8个字节; 2.Call KernelFunc; 3.在重新修改KernelFunc的前8个字节的内容,使之跳到MyFunc。 } 多线程的问题在于: 如果线程A刚运行到1步结束就被调度出去了,然后线程B来了,他也要调用KernelFunc,那么他这个时候是不是就不会调用MyFunc呢?我想应该不会,因为这个时候开始的8个字节已经被恢复了阿。 |
|
10楼#
发布于:2002-06-21 11:09
cr3变化倒没关系,因为内核空间是由所有进程共享的。
|
|
11楼#
发布于:2002-06-21 11:07
System Service Hook技术我在《再谈Windows NT/2000内部数据结构》中提及,到现在为止,仍是可以参考的。由于新版本的Windows 2k/xp对一些重要的数据结构,和一些只读的image页面,设置cr0的wp位,这样即使在ring0写这些只读页面,都会出现bugcheck(Bug Check 0xBE: ATTEMPTED_WRITE_TO_READONLY_MEMORY)。当然解决办法有两种:
1、清除cr0的wp位。 2、windows在注册表中有一表项: HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management下将EnforceWriteProtection设成0,即可默认取消这一了限制。 softice使用第二种方法。当然这样做的话对于system service以外的所有readonly区域os都将不能做到保护这些只读页面。当然这是softice运行所必须的。因为softice不知道我们的断点(通过写入0xcc int 3)设在哪等等。 但是mark通过一个非常聪明的办法来实现这一功能。他这样做将只影响到他自己对system service table的修改,他通过建立一个mdl,来实现。对这个mdl有write access。这是一个极其聪明的办法,非对windows nt/2000有极深入研究的人可以想到的办法(特别是mm子系统)。 我在底下tsu00-002的帖子中列出了这段代码。你想明白regmon的未公开函数时(他通过.lib发布),一定要看明白我提供的那段代码。 如果你想明白windows 2k/xp在内部使用这一机制的流程,譬如:mminitsystem在system初始化阶段将EnforceWriteProtection读入内核变量MmEnforceWriteProtection,还有随后使用MiPteStr等等一些流程,你自已反汇编一下ntoskrnl吧。 转载自:http://webcrazy.xilubbs.com/ |
|
|
12楼#
发布于:2002-06-21 10:50
WinNT/2k页目录表入口地址与进程相关,每一个进程可能都不相同,操作系统在进行切换时,会重新设置CR3寄存器,这点与Win9x有区别。
MSDN里面介绍了一点 |
|
|
13楼#
发布于:2002-06-21 09:28
我觉得你们错了,我刚才做过的实验如果页目录表的起始地址是0xc0300000,那么页目录表里的每一项即页目录项的内容为0,如果是0x80300000的话也目录表里的内容是正确的,如下所示:
PageDirTable[512] = 1e3 PageDirTable[513] = 4001e3 PageDirTable[514] = 8001e3 PageDirTable[515] = c001e3 PageDirTable[516] = 10001e3 PageDirTable[517] = 14001e3 PageDirTable[518] = 18001e3 PageDirTable[519] = 1c001e3 PageDirTable[520] = 20001e3 PageDirTable[521] = 24001e3 PageDirTable[522] = 28001e3 PageDirTable[523] = 2c001e3 PageDirTable[524] = 30001e3 PageDirTable[525] = 34001e3 PageDirTable[526] = 38001e3 PageDirTable[527] = 3c001e3 PageDirTable[528] = 40001e3 PageDirTable[529] = 44001e3 PageDirTable[530] = 48001e3 PageDirTable[531] = 4c001e3 PageDirTable[532] = 50001e3 PageDirTable[533] = 54001e3 PageDirTable[534] = 58001e3 PageDirTable[535] = 5c001e3 另外我之所以讨论内核所在的位置,是因为内核的线性地址和物理地址之间应该存在一个简单的线性关系,那就是物理地址+内核的起始地址。linux里面是0xc0000000,而windows2000是0x80000000。 |
|
14楼#
发布于:2002-06-21 09:02
好的,我先做实验,一会儿再恢复贴子。:)
|
|
15楼#
发布于:2002-06-21 08:06
同意PJF说的:页目录项是从0xC0300000开始的
|
|
|
16楼#
发布于:2002-06-21 07:50
试了再说嘛,呵呵
|
|
17楼#
发布于:2002-06-21 07:48
呵呵,谁跟你争内核是从哪儿开始的。我们在说页表与页目录是从哪儿开始的。只要你没加/3GB开关,0xC0000000没错。
|
|
18楼#
发布于:2002-06-20 22:10
0xc0000000是在linux内核的开始地址,windows2000应该是0x80000000。我是以080300000计算页目录表的,我觉得页目录表里内容是正确的。
|
|
19楼#
发布于:2002-06-20 21:07
ExAllocatePool的线性地址是: 80417ba0
页表基地址是: 80400000 页表项所在地址是: 8040005c 页表项的内容是:6f6e6e61 -------------------------------------------------------------------- 错啦错啦,你这是2000系统吧?从老版NT起,页表项就一直是从0xC0000000开始的,页目录项是从0xC0300000开始的。你看看自己那儿有问题。 |
|
上一页
下一页