swift
驱动中牛
驱动中牛
  • 注册日期2001-07-26
  • 最后登录2007-05-09
  • 粉丝0
  • 关注0
  • 积分70分
  • 威望7点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
阅读:3479回复:24

ndis.sys导出表里的函数的地址已经得到了,如何做hook?大家讨论或者大侠指点...

楼主#
更多 发布于:2002-05-27 16:12
在以前贴子的基础上,我已经将ndis.sys里的
NdisRegisterProtocol
NdisDeregisterProtocol
NdisOpenAdapter
NdisCloseAdapter
四个函数已经找到,但是如果做hook呢?
是要将四个函数的地址改变吗?那不是改ndis.sys吗?
是用我的函数的地址来写我所得到的四个函数的地址吗?
请指点或讨论...

最新喜欢:

cyliucyliu flyfoxflyfox znsoftznsoft
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-06-25 10:34
自己动手试试,就不乱了!:)
guard2002
驱动中牛
驱动中牛
  • 注册日期2002-05-21
  • 最后登录2017-03-07
  • 粉丝0
  • 关注0
  • 积分46分
  • 威望65点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2002-06-24 15:08
看的有点乱
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-05-29 13:05
为什么用softice看到的我写的函数的地址是0x68XXXXXX,而ndis.sys的基址是0xbfecXXXX,为什么我写的函数地址要小于ndis.sys的地址?
------------------------------------------------------------------
你写的函数的地址是0x68XXXXXX???在用户内存区?呵呵,肯定搞错了。事实上你的驱动加载地址一般在0xF*******。
-------------------------------------------------------------------------


而且,pjf我用你写的方法:
ULONG funcAddr = ( ULONG )(你的函数名字);
然后你拿着这个ULONG想做什么就做什么阿,比如赋值给寄存器:
__asm {
mov eax, funcAddr;
}

赋给内存:
char * ptr = ....
*(( ULONG * )ptr) = funcAddr;

这样得到的funcAddr,用softice看是一个地址值,它指向的内存存放着我的函数的地址,我是这样写的:
ULONG funcAddr=(ULONG)((char *)MyFunctionName - (char *)NdisBaseAddress)
然后*((ULONG *)ptr) = funcAddr,我用softice看了,ptr内存是改变了,
可是这样做好象不对,我再加载protocol的时候,会死机或者系统变的很慢,而且用softice没有拦截到中断,也就是说好象没有进到我自己的函数来。why?
------------------------------------------------------------------
你修改的export table?我以前用的是我说的方法二,确保可行。至于改export table我有空确认了再说。
你把这段程序运行一下看看:
__declspec(naked) PVOID MyGetThread()
{
_asm{
mov eax,DWORD[0ffdff124h]
ret
}
}

截获:
........
UCHAR push[6]={0x68};
func=(PULONG)FindFunc(FindNtoskrnl(),\"KeGetCurrentThread\");
if(func!=NULL){
_asm cli
addr=(ULONG)MyGetThread;
memcpy((PUCHAR)func,push,1);
memcpy((PUCHAR)func+1,(PUCHAR)&addr,4);
_asm sti
}
你钩挂你的程序仅需做小改动:push[6]={0x68,0,0,0,0,0xc3}、memcpy((PUCHAR)func,push,6);
之前保存一下系统函数原来的值:memcpy(backup,(PUCHAR)func,6);等等。
若你要调原来的函数,先copy回保存的6字节,再call func地址:
mov eax,func
call func
返回后又改过来。
----------------------------------------------------------------------

好象与pjf说的有些出入哦!
-----------------------------------------------------------------
一样的,6字节与8字节的区别
swift
驱动中牛
驱动中牛
  • 注册日期2001-07-26
  • 最后登录2007-05-09
  • 粉丝0
  • 关注0
  • 积分70分
  • 威望7点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-05-29 10:10
你说的好象与pjf说的有些出入哦!
xemexzj
驱动牛犊
驱动牛犊
  • 注册日期2001-11-07
  • 最后登录2006-03-15
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-05-29 10:02
为什么用softice看到的我写的函数的地址是0x68XXXXXX,而ndis.sys的基址是0xbfecXXXX,为什么我写的函数地址要小于ndis.sys的地址?

而且,pjf我用你写的方法:
ULONG funcAddr = ( ULONG )(你的函数名字);
然后你拿着这个ULONG想做什么就做什么阿,比如赋值给寄存器:
__asm {
mov eax, funcAddr;
}

赋给内存:
char * ptr = ....
*(( ULONG * )ptr) = funcAddr;

这样得到的funcAddr,用softice看是一个地址值,它指向的内存存放着我的函数的地址,我是这样写的:
ULONG funcAddr=(ULONG)((char *)MyFunctionName - (char *)NdisBaseAddress)
然后*((ULONG *)ptr) = funcAddr,我用softice看了,ptr内存是改变了,
可是这样做好象不对,我再加载protocol的时候,会死机或者系统变的很慢,而且用softice没有拦截到中断,也就是说好象没有进到我自己的函数来。why?

 


比较简单的方法是将已得到的函数地址的前8字节改为:
mov eax, [your fun address]
jmp eax
8字节内容如下 0x058d + 4bytes函数地址 + 0xe0ff
在你的函数内再将原函数的8字节内容恢佛
只要你hook的函数不是被非常频繁的调用这种方法没问题
xeme
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
6楼#
发布于:2002-05-29 09:54
可能地址还有一个变换关系,看看PE文件的结构吧。
swift
驱动中牛
驱动中牛
  • 注册日期2001-07-26
  • 最后登录2007-05-09
  • 粉丝0
  • 关注0
  • 积分70分
  • 威望7点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-05-29 09:17
为什么用softice看到的我写的函数的地址是0x68XXXXXX,而ndis.sys的基址是0xbfecXXXX,为什么我写的函数地址要小于ndis.sys的地址?

而且,pjf我用你写的方法:
ULONG funcAddr = ( ULONG )(你的函数名字);
然后你拿着这个ULONG想做什么就做什么阿,比如赋值给寄存器:
__asm {
mov eax, funcAddr;
}

赋给内存:
char * ptr = ....
*(( ULONG * )ptr) = funcAddr;

这样得到的funcAddr,用softice看是一个地址值,它指向的内存存放着我的函数的地址,我是这样写的:
ULONG funcAddr=(ULONG)((char *)MyFunctionName - (char *)NdisBaseAddress)
然后*((ULONG *)ptr) = funcAddr,我用softice看了,ptr内存是改变了,
可是这样做好象不对,我再加载protocol的时候,会死机或者系统变的很慢,而且用softice没有拦截到中断,也就是说好象没有进到我自己的函数来。why?

sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-05-28 18:51
如果成功了,再发个贴子哈.
111
swift
驱动中牛
驱动中牛
  • 注册日期2001-07-26
  • 最后登录2007-05-09
  • 粉丝0
  • 关注0
  • 积分70分
  • 威望7点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-05-28 15:58
我使用的是第一种方法,我修改了ndis.sys的export table,但我想在系统启动时,在ndis.sys和tcpip之间加载我的.sys
swift
驱动中牛
驱动中牛
  • 注册日期2001-07-26
  • 最后登录2007-05-09
  • 粉丝0
  • 关注0
  • 积分70分
  • 威望7点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-05-28 15:53
好的,我找找,3x
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-05-28 15:52
你用的第一种方法吗?这样比你的驱动先加载的驱动由于加载器已处理过了导出函数(将地址写入该驱动映像),不再受你的影响。而后面的办法改动了ndis,不管它何时加载,只要调用函数就会进入你的程序。不过看你似乎想在tcpip调用函数前就钩挂好,还是得改启动顺序。
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-05-28 15:43
设置它的启动顺序与启动组等,各本书都有介绍,DDK文档更加详细,你还是自己翻翻吧。
swift
驱动中牛
驱动中牛
  • 注册日期2001-07-26
  • 最后登录2007-05-09
  • 粉丝0
  • 关注0
  • 积分70分
  • 威望7点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-05-28 15:19
3x,pjf
用sofeice已经看到地址已经更改了,可是我又遇到了安装问题,
现在我是用osrloader来加载,但象这样的.sys一定要在系统启动的时候,在ndis之后,tcpip之前加载,用osrloader可以实现吗?
怎样才能把.sys安装上,让它在系统启动的时候启动?
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-05-28 12:43
第一种方法没什么好说的,第二种方法举个例子:
你的函数:
__declspec(naked) PVOID MyGetThread()
{
_asm{
mov eax,DWORD[0ffdff124h]
ret
}
}

截获:
........
UCHAR push[6]={0x68};
func=(PULONG)FindFunc(FindNtoskrnl(),\"KeGetCurrentThread\");
if(func!=NULL){
        _asm cli
        addr=(ULONG)MyGetThread;
        memcpy((PUCHAR)func,push,1);
        memcpy((PUCHAR)func+1,(PUCHAR)&addr,4);
        _asm sti
}
//由于2000中KeGetCurrentThread函数第六字节就是C3(ret),我这儿没加,你得copy过去。我没用到原函数,你要用到的话得保存原来的值。
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2002-05-28 12:35
你不是已经找到export table里的函数了吗?自己看看是不是rva,显然加载器会帮你搞定一切的。
--------------------------------------------------------------------
就是说加载器载别的程序调用导出函数时会自动在该程序映像中加上你的base(相对ndis头),你用下面与句得到地址:
func =PCHAR(Base)+functions[ord];
自然写进去时减掉base。(your address - Base)
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2002-05-28 12:15
在pe表里的export table里的地址都是rva呀,如果我想改变ndis.sys在内存中image的值,是不是也要算出我的函数地址与ndis.sys基址的rva呢?还是直接把我的函数的地址写到export table里面?
--------------------------------------------------------------------
你不是已经找到export table里的函数了吗?自己看看是不是rva,显然加载器会帮你搞定一切的。
swift
驱动中牛
驱动中牛
  • 注册日期2001-07-26
  • 最后登录2007-05-09
  • 粉丝0
  • 关注0
  • 积分70分
  • 威望7点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2002-05-28 09:35
在pe表里的export table里的地址都是rva呀,如果我想改变ndis.sys在内存中image的值,是不是也要算出我的函数地址与ndis.sys基址的rva呢?还是直接把我的函数的地址写到export table里面?
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
18楼#
发布于:2002-05-28 09:31
比如:
  ULONG funcAddr = ( ULONG )(你的函数名字);
  然后你拿着这个ULONG想做什么就做什么阿,比如赋值给寄存器:
  __asm {
     mov eax, funcAddr;
  }

  赋给内存:
  char * ptr = ....
  *(( ULONG * )ptr) = funcAddr;

  编译器都不出错的。
swift
驱动中牛
驱动中牛
  • 注册日期2001-07-26
  • 最后登录2007-05-09
  • 粉丝0
  • 关注0
  • 积分70分
  • 威望7点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2002-05-28 09:01
能否说的清楚一些,3x
上一页
游客

返回顶部