ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
阅读:3505回复:39

关于任意勾挂内核函数的的问题

楼主#
更多 发布于:2002-06-20 10:05
    我的思路是找到该函数的内存地址,反向查找页表所在的位置,修改页表的内容,然后将函数的前几个字节保存起来,并且通过一条jump指令让他跳到我的函数的地址。事后再恢复原来的内容。有愿意讨论的,请在此发表贴子或者给我发信,我的信箱在我的资料里有。

最新喜欢:

zackaryzackar...
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-06-21 18:00
还有《undocumented windows NT》的第四章你一定的看看,hehe
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-06-21 17:57
至于页目录表的问题,我觉得windows2000还是和linux差不多吧,他们应该都是简单得线性关系。但是这仅仅是停留在理论上,我还没实践所以不好说
----------------------------------------------------------------------
不说了吧,别人是有实践的-----见《不用驱动的Ring0代码实现》,hehe
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-06-21 17:29
巴西赢了,我也把函数钩过来了。不过比较笨!

至于页目录表的问题,我觉得windows2000还是和linux差不多吧,他们应该都是简单得线性关系。但是这仅仅是停留在理论上,我还没实践所以不好说。

另外,另外楼上的大虾提到一些参考资料,网上在那儿有?我看看之后再发表意见。

等我再修改一下之后,把源码放上来!希望大家别笑我写的代码蹩脚。

给了半天没给过去,我怎么样才能给pjf分呢?
VanCheer
驱动老牛
驱动老牛
  • 注册日期2002-02-21
  • 最后登录2003-08-28
  • 粉丝0
  • 关注0
  • 积分-20分
  • 威望-10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-06-21 16:48
刚刚看球去了,巴西赢了,happy。
你说得不错,这就会导至“漏球”,内核调试器有时也会漏(不过原因肯定不一样啦);我没用这种方法,因为知道被钩函数开始代码,所以总是先让它在hook函数例执行开始代码再jmp回去。

大兄弟,快去回答我的ntoskrnl的问题
[img]http://www.driverdevelop.com/forum/upload/VanCheer/2003-03-21_mon.gif[/img][img]http://www.driverdevelop.com/forum/upload/VanCheer/2002-12-07_smallbaby.jpg[/img]
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-06-21 16:48
刚刚看球去了,巴西赢了,happy。
你说得不错,这就会导至“漏球”,内核调试器有时也会漏(不过原因肯定不一样啦);我没用这种方法,因为知道被钩函数开始代码,所以总是先让它在hook函数例执行开始代码再jmp回去。
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
6楼#
发布于:2002-06-21 16:09
我提出的问题怎么没人理睬了?难道这不是问题吗?
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-06-21 14:07
页目录表里的每一项即页目录项的内容为0
-----------------------------------------------------------------------
并不是每一项,而是开始的一些项与没用的项根本没映射,你用Softice一直d下去,自让会看到希望的页目录项。

事实上就你的情况根本用不到页目录项,NT的映射很有规律且简单,直接由address就可算得address所在页表项的线性地址。
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
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》。
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
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个字节已经被恢复了阿。
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-06-21 11:09
cr3变化倒没关系,因为内核空间是由所有进程共享的。
lyabcd
驱动大牛
驱动大牛
  • 注册日期2001-08-09
  • 最后登录2015-10-01
  • 粉丝0
  • 关注0
  • 积分33分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
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/
datongguandian@sina.com
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
12楼#
发布于:2002-06-21 10:50
WinNT/2k页目录表入口地址与进程相关,每一个进程可能都不相同,操作系统在进行切换时,会重新设置CR3寄存器,这点与Win9x有区别。
MSDN里面介绍了一点
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
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。
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-06-21 09:02
好的,我先做实验,一会儿再恢复贴子。:)
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
15楼#
发布于:2002-06-21 08:06
同意PJF说的:页目录项是从0xC0300000开始的
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2002-06-21 07:50
试了再说嘛,呵呵
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2002-06-21 07:48
呵呵,谁跟你争内核是从哪儿开始的。我们在说页表与页目录是从哪儿开始的。只要你没加/3GB开关,0xC0000000没错。
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2002-06-20 22:10
0xc0000000是在linux内核的开始地址,windows2000应该是0x80000000。我是以080300000计算页目录表的,我觉得页目录表里内容是正确的。
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2002-06-20 21:07
ExAllocatePool的线性地址是: 80417ba0
页表基地址是:   80400000
页表项所在地址是: 8040005c
页表项的内容是:6f6e6e61
--------------------------------------------------------------------
错啦错啦,你这是2000系统吧?从老版NT起,页表项就一直是从0xC0000000开始的,页目录项是从0xC0300000开始的。你看看自己那儿有问题。
上一页
游客

返回顶部