wang1203
驱动牛犊
驱动牛犊
  • 注册日期2004-08-06
  • 最后登录2004-09-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:4290回复:30

基于filedisk实现驱动回调应用程序

楼主#
更多 发布于:2004-08-14 15:50
我是驱动程序方面的菜鸟
在论坛搜索出了很多这方面的帖子,没有发现具体实现的例子

以filedisk为框架,想实现从filedisk.sys中调用filedisk.exe中的函数的方法。

第一步:在filedisk.exe中编写一个函数
int WINAPI CBFunc(int a, int b)
{
return a+b;
}

第二步:通过DeviceIoControl把函数指针传递给filedisk.sys
DeviceIoControl(
    Device,
    IOCTL_FILE_DISK_INIT_FILE,
    CBFunc, //callback
    4,
    NULL,
    0,
    &BytesReturned,
    NULL
    );

第三步:在filedisk.sys中获得这个函数的指针然后调用
    typedef int (__stdcall *CBFunc)(int a, int b);
    CBFunc tc;

    case IOCTL_FILE_DISK_INIT_FILE:
        tc = Irp->AssociatedIrp.SystemBuffer;
        a = 1;
        b = 2;
        ret = (*tc)(a, b);  //程序在此处飞掉

请问:
    我需要如何在程序中定义和使用这个函数,才能成功?

我很菜,提的问题如有不妥请别见笑,拜托了。
热切企盼ing.

最新喜欢:

aasa2aasa2
newkey
驱动小牛
驱动小牛
  • 注册日期2002-10-03
  • 最后登录2013-10-13
  • 粉丝1
  • 关注0
  • 积分45分
  • 威望392点
  • 贡献值1点
  • 好评度90点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-09-21 13:06
估计有很多限制

但这种方法如果能在限制范围内没问题, 无疑给驱动向应用层通知,提供了很简单的思路

比如在 核心态 可以 回调 应用态的

SendMsg(int iMsgNo)
{
   SendMessage(xxx, yyy, iMsgNo);
}

通过应用态再转一次, 应该可以避免很多问题

那位大虾,严格论证一下, 这些想法即时调试出来,当时没问题,心里也没底

www.xDrv.com
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2004-09-03 18:47
我试过,这种方法完全没问题的.
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
lak47
驱动牛犊
驱动牛犊
  • 注册日期2002-11-09
  • 最后登录2014-09-24
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望22点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-09-03 14:07
我试过的,这种方法不行,应该用APC
ildee
驱动牛犊
驱动牛犊
  • 注册日期2003-01-16
  • 最后登录2005-01-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-08-20 17:29
虽然我没试过,不过肯定不行!!

回调函数函数是在应用程序的进程空间内,传到驱动力有什么用吗??难道驱动也会使用你的地址空间吗??
ildee
驱动牛犊
驱动牛犊
  • 注册日期2003-01-16
  • 最后登录2005-01-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-08-20 17:12
虽然没有试验过,不过我觉得这种方法不可行!!

函数的指针是在应用程序进程内的地址空间,传到驱动程序里面有什么用吗??根本不在一个进程内。
AthlonxpX86
驱动小牛
驱动小牛
  • 注册日期2002-11-10
  • 最后登录2013-07-17
  • 粉丝0
  • 关注0
  • 积分29分
  • 威望43点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-08-20 16:45
你反汇编下函数代码看看即可,估计运行的时候在RING0运行的RING3函数使用的是RING0堆栈,所以自然有一定的限制,不过只要一般不是很大即可,而且可以在RING0中访问RING3堆栈中的内容所以问题不大。。。。。

按照楼主的方法,回调函数肯定被纳入ring0,其实已经算是驱动程序的例程了,只不过地址在用户地址空间,而且这种调用函数的结果肯定和用户模式调用这个函数的结果不太一样,我不太清楚你说的这种方法能不能称之为回调,自己处理堆栈....牛啊,举个例子

应用程序在一个函数里面肯定可以执行MessageBox("asdfghjkl");
但是到驱动程序中调用,堆栈改变,万一用户模式的API函数MessageBox有需要访问自己原来在用户模式的堆栈,你就傻了,而且要注意核心模式为函数提供的堆栈只有12K,不能深度调用,递归更是不可能,因此建议楼主还是放弃直接在驱动中直接调用用户模式函数,除非你的回调函数是按照驱动程序的要求写的,比如你最好不要调用一些WIN32API,因为这个函数本身已经不算是应用程序的一部分了,因此如果这样,你还不如直接把你的回调函数写到你的驱动程序中,这样还简单的多
AthlonxpX86(桃源村)
Sundsea
驱动老牛
驱动老牛
  • 注册日期2003-05-06
  • 最后登录2012-06-05
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望35点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-08-20 15:32
顶!!!!!!!!!!
用户模式访问底层函数,缓冲区是什么情况呀?
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
8楼#
发布于:2004-08-20 15:16
你反汇编下函数代码看看即可,估计运行的时候在RING0运行的RING3函数使用的是RING0堆栈,所以自然有一定的限制,不过只要一般不是很大即可,而且可以在RING0中访问RING3堆栈中的内容所以问题不大。。。。。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
AthlonxpX861
驱动牛犊
驱动牛犊
  • 注册日期2003-07-26
  • 最后登录2004-08-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-08-20 14:04
[quote]大家有没有试验啊,我记的一个进程中核心模式和用户模式不是同一个堆栈,(x86每一层都有不同的SS),这样即便是知道函数地址,也不能简单的通过指针来调用,(函数中的堆栈操作很容易出现问题,首先是函数参数,然后是new delete等)何况这种方法只能是在应用程序发送IRP后才能回调,而且我个人还是认为不能保证在处理IRP期间,进程上下文不发生变化,wowocock说的只是直接I/O和缓冲I/O提供的数据缓冲区不随进程上下文变化而变化,但是现在情况不一样了,你是以缓冲区中的数据作为指针调用函数,万一在调用函数之前发生了进程切换,你的指针................而且即使进程上下文不发生变化,也会有问题

没问题的,passive_level能保证线程上下文
 [/quote]
但是堆栈问题怎么解决?核心环境的堆栈肯定和用户模式的堆栈不同
punk
驱动小牛
驱动小牛
  • 注册日期2001-04-07
  • 最后登录2018-06-01
  • 粉丝0
  • 关注0
  • 积分621分
  • 威望164点
  • 贡献值0点
  • 好评度60点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-08-20 08:59
大家有没有试验啊,我记的一个进程中核心模式和用户模式不是同一个堆栈,(x86每一层都有不同的SS),这样即便是知道函数地址,也不能简单的通过指针来调用,(函数中的堆栈操作很容易出现问题,首先是函数参数,然后是new delete等)何况这种方法只能是在应用程序发送IRP后才能回调,而且我个人还是认为不能保证在处理IRP期间,进程上下文不发生变化,wowocock说的只是直接I/O和缓冲I/O提供的数据缓冲区不随进程上下文变化而变化,但是现在情况不一样了,你是以缓冲区中的数据作为指针调用函数,万一在调用函数之前发生了进程切换,你的指针................而且即使进程上下文不发生变化,也会有问题

没问题的,passive_level能保证线程上下文
不停学习
AthlonxpX86
驱动小牛
驱动小牛
  • 注册日期2002-11-10
  • 最后登录2013-07-17
  • 粉丝0
  • 关注0
  • 积分29分
  • 威望43点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-08-20 02:11
大家有没有试验啊,我记的一个进程中核心模式和用户模式不是同一个堆栈,(x86每一层都有不同的SS),这样即便是知道函数地址,也不能简单的通过指针来调用,(函数中的堆栈操作很容易出现问题,首先是函数参数,然后是new delete等)何况这种方法只能是在应用程序发送IRP后才能回调,而且我个人还是认为不能保证在处理IRP期间,进程上下文不发生变化,wowocock说的只是直接I/O和缓冲I/O提供的数据缓冲区不随进程上下文变化而变化,但是现在情况不一样了,你是以缓冲区中的数据作为指针调用函数,万一在调用函数之前发生了进程切换,你的指针................而且即使进程上下文不发生变化,也会有问题
AthlonxpX86(桃源村)
wang1203
驱动牛犊
驱动牛犊
  • 注册日期2004-08-06
  • 最后登录2004-09-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-08-19 21:03
嘿嘿,老兄我又没说他好,我只是针对楼主的想法的一个实现方法而已......


这两天出差,没有上来,感谢!

如何给分?
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
13楼#
发布于:2004-08-19 13:37
嘿嘿,老兄我又没说他好,我只是针对楼主的想法的一个实现方法而已......
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
punk
驱动小牛
驱动小牛
  • 注册日期2001-04-07
  • 最后登录2018-06-01
  • 粉丝0
  • 关注0
  • 积分621分
  • 威望164点
  • 贡献值0点
  • 好评度60点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2004-08-19 13:26
[quote][quote][quote][quote]我是驱动程序方面的菜鸟
在论坛搜索出了很多这方面的帖子,没有发现具体实现的例子

以filedisk为框架,想实现从filedisk.sys中调用filedisk.exe中的函数的方法。

第一步:在filedisk.exe中编写一个函数
int WINAPI CBFunc(int a, int b)
{
return a+b;
}

第二步:通过DeviceIoControl把函数指针传递给filedisk.sys
DeviceIoControl(
    Device,
    IOCTL_FILE_DISK_INIT_FILE,
    CBFunc, //callback
    4,
    NULL,
    0,
    &BytesReturned,
    NULL
    );

第三步:在filedisk.sys中获得这个函数的指针然后调用
    typedef int (__stdcall *CBFunc)(int a, int b);
    CBFunc tc;

    case IOCTL_FILE_DISK_INIT_FILE:
        tc = Irp->AssociatedIrp.SystemBuffer;
        a = 1;
        b = 2;
        ret = (*tc)(a, b);  //程序在此处飞掉

请问:
    我需要如何在程序中定义和使用这个函数,才能成功?

我很菜,提的问题如有不妥请别见笑,拜托了。
热切企盼ing.

我觉得如果你用的是缓冲io的话,错误很简单
tc = *(CBFunc *)Irp->AssociatedIrp.SystemBuffer; [/quote]

楼上的有没有做过测试呢??我也在Irp->AssociatedIrp.SystemBuffer测试过,可里面的根本就是不是你传来的函数指针,请你做过测试后再说。。。。。。。 [/quote]

我没测试过,但是不用测试,你的代码也有问题:
inBuf = irpSp->Parameters.DeviceIoControl.Type3InputBuffer;
outBuf = Irp->UserBuffer;
tc = (CBFunc)inBuf;应该改成tc = *(CBFunc*)inBuf;
这两个是完全不一样的,所以才有:里面的根本就是不是你传来的函数指针
 [/quote]
请你用SOFTICE调试后再说对错,我是直接在汇编中调试的,而且也执行成功的,嘿嘿。。。。。。。 [/quote]
呵呵,原来把程序代码段的地址作为缓冲地址传进来了!
很抱歉,我没看应用程序部分。
尽管如此,我觉得这种传递参数的做法不好!
不停学习
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
15楼#
发布于:2004-08-19 13:03
[quote][quote][quote]我是驱动程序方面的菜鸟
在论坛搜索出了很多这方面的帖子,没有发现具体实现的例子

以filedisk为框架,想实现从filedisk.sys中调用filedisk.exe中的函数的方法。

第一步:在filedisk.exe中编写一个函数
int WINAPI CBFunc(int a, int b)
{
return a+b;
}

第二步:通过DeviceIoControl把函数指针传递给filedisk.sys
DeviceIoControl(
    Device,
    IOCTL_FILE_DISK_INIT_FILE,
    CBFunc, //callback
    4,
    NULL,
    0,
    &BytesReturned,
    NULL
    );

第三步:在filedisk.sys中获得这个函数的指针然后调用
    typedef int (__stdcall *CBFunc)(int a, int b);
    CBFunc tc;

    case IOCTL_FILE_DISK_INIT_FILE:
        tc = Irp->AssociatedIrp.SystemBuffer;
        a = 1;
        b = 2;
        ret = (*tc)(a, b);  //程序在此处飞掉

请问:
    我需要如何在程序中定义和使用这个函数,才能成功?

我很菜,提的问题如有不妥请别见笑,拜托了。
热切企盼ing.

我觉得如果你用的是缓冲io的话,错误很简单
tc = *(CBFunc *)Irp->AssociatedIrp.SystemBuffer; [/quote]

楼上的有没有做过测试呢??我也在Irp->AssociatedIrp.SystemBuffer测试过,可里面的根本就是不是你传来的函数指针,请你做过测试后再说。。。。。。。 [/quote]

我没测试过,但是不用测试,你的代码也有问题:
inBuf = irpSp->Parameters.DeviceIoControl.Type3InputBuffer;
outBuf = Irp->UserBuffer;
tc = (CBFunc)inBuf;应该改成tc = *(CBFunc*)inBuf;
这两个是完全不一样的,所以才有:里面的根本就是不是你传来的函数指针
 [/quote]
请你用SOFTICE调试后再说对错,我是直接在汇编中调试的,而且也执行成功的,嘿嘿。。。。。。。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2004-08-19 12:29
看看函数地址传下来的和user mode下的是否相同,如果相同的话,还要注意函数的调用方式是否一致(stdcall fastcall etc),我没有试过,胡乱说的,希望有所帮助。 :P
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2004-08-19 12:26
其实函数的地址只是一个数值而已,通过哪种方式不能传下来啊!! 所以还是代码的问题,不是方法的问题。:P
punk
驱动小牛
驱动小牛
  • 注册日期2001-04-07
  • 最后登录2018-06-01
  • 粉丝0
  • 关注0
  • 积分621分
  • 威望164点
  • 贡献值0点
  • 好评度60点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2004-08-19 11:42
[quote][quote]我是驱动程序方面的菜鸟
在论坛搜索出了很多这方面的帖子,没有发现具体实现的例子

以filedisk为框架,想实现从filedisk.sys中调用filedisk.exe中的函数的方法。

第一步:在filedisk.exe中编写一个函数
int WINAPI CBFunc(int a, int b)
{
return a+b;
}

第二步:通过DeviceIoControl把函数指针传递给filedisk.sys
DeviceIoControl(
    Device,
    IOCTL_FILE_DISK_INIT_FILE,
    CBFunc, //callback
    4,
    NULL,
    0,
    &BytesReturned,
    NULL
    );

第三步:在filedisk.sys中获得这个函数的指针然后调用
    typedef int (__stdcall *CBFunc)(int a, int b);
    CBFunc tc;

    case IOCTL_FILE_DISK_INIT_FILE:
        tc = Irp->AssociatedIrp.SystemBuffer;
        a = 1;
        b = 2;
        ret = (*tc)(a, b);  //程序在此处飞掉

请问:
    我需要如何在程序中定义和使用这个函数,才能成功?

我很菜,提的问题如有不妥请别见笑,拜托了。
热切企盼ing.

我觉得如果你用的是缓冲io的话,错误很简单
tc = *(CBFunc *)Irp->AssociatedIrp.SystemBuffer; [/quote]

楼上的有没有做过测试呢??我也在Irp->AssociatedIrp.SystemBuffer测试过,可里面的根本就是不是你传来的函数指针,请你做过测试后再说。。。。。。。 [/quote]

我没测试过,但是不用测试,你的代码也有问题:
inBuf = irpSp->Parameters.DeviceIoControl.Type3InputBuffer;
outBuf = Irp->UserBuffer;
tc = (CBFunc)inBuf;应该改成tc = *(CBFunc*)inBuf;
这两个是完全不一样的,所以才有:里面的根本就是不是你传来的函数指针
不停学习
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
19楼#
发布于:2004-08-19 10:54
[quote]我是驱动程序方面的菜鸟
在论坛搜索出了很多这方面的帖子,没有发现具体实现的例子

以filedisk为框架,想实现从filedisk.sys中调用filedisk.exe中的函数的方法。

第一步:在filedisk.exe中编写一个函数
int WINAPI CBFunc(int a, int b)
{
return a+b;
}

第二步:通过DeviceIoControl把函数指针传递给filedisk.sys
DeviceIoControl(
    Device,
    IOCTL_FILE_DISK_INIT_FILE,
    CBFunc, //callback
    4,
    NULL,
    0,
    &BytesReturned,
    NULL
    );

第三步:在filedisk.sys中获得这个函数的指针然后调用
    typedef int (__stdcall *CBFunc)(int a, int b);
    CBFunc tc;

    case IOCTL_FILE_DISK_INIT_FILE:
        tc = Irp->AssociatedIrp.SystemBuffer;
        a = 1;
        b = 2;
        ret = (*tc)(a, b);  //程序在此处飞掉

请问:
    我需要如何在程序中定义和使用这个函数,才能成功?

我很菜,提的问题如有不妥请别见笑,拜托了。
热切企盼ing.

我觉得如果你用的是缓冲io的话,错误很简单
tc = *(CBFunc *)Irp->AssociatedIrp.SystemBuffer; [/quote]

楼上的有没有做过测试呢??我也在Irp->AssociatedIrp.SystemBuffer测试过,可里面的根本就是不是你传来的函数指针,请你做过测试后再说。。。。。。。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
上一页
游客

返回顶部