amei
驱动牛犊
驱动牛犊
  • 注册日期2002-03-21
  • 最后登录2006-11-10
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
阅读:1549回复:13

com1

楼主#
更多 发布于:2002-07-16 14:57
我按照《虚拟设备驱动程序开发起步与进阶》一书中6.2.2I/O类的例子作一个监控com1口的程序,当我在应用程序中对3f8进行访问时,并没有触发handler函数。按理说VXD是可以扑捉com1口的,可为什么我的程序一点反映也没有,如果我改换378端口程序就可以正常运行,我想一定是在Win98中对com1口有什么特别的要求。
请各位多多指教,要快呀

最新喜欢:

beaverorbeaver...
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2002-07-16 15:07
windows自己的VxD已经虚拟了大多数的I/O port,VMM只允许VxD捕获给定的port
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-07-16 17:32
我按照《虚拟设备驱动程序开发起步与进阶》一书中6.2.2I/O类的例子作一个监控com1口的程序,当我在应用程序中对3f8进行访问时,并没有触发handler函数。按理说VXD是可以扑捉com1口的,可为什么我的程序一点反映也没有,如果我改换378端口程序就可以正常运行,我想一定是在Win98中对com1口有什么特别的要求。
请各位多多指教,要快呀


唔,你是不是那个发过贺卡的兄弟?呵呵

帮你写了一小段:
首先Vtoolsd的类在hook时使用Install_IO_Handler,注意这么一段话:The return value is TRUE if the service successfully installs the callback procedure. If a callback procedure is already installed for the specified port or the system limit for I/O callback procedures has been reached, then the service returns FALSE.

你所要的资源被系统占了,返回是FALSE。你非要Install的话首先把系统的干掉:Remove_IO_Handler。不过这样相应的原本系统的正常服务会变得不正常。不过可满足你够挂的欲望,呵呵。

小测试:
CPP文件:
// PPP.cpp - main module for VxD PPP

#define DEVICE_MAIN
#include \"ppp.h\"
Declare_Virtual_Device(PPP)
#undef DEVICE_MAIN

MyPort::MyPort():VIOPort(MY_PORT_NUMBER){
Remove_IO_Handler(MY_PORT_NUMBER);
if(hook())
{
globalEnable();
}
else
{
SHELL_Message(Get_Cur_VM_Handle(),MB_OK,\"ERROR\",\"ERROR\",NULL,NULL,NULL);
}
}

MyPort::~MyPort(){
unhook();
}

DWORD MyPort::handler(VMHANDLE hVM,DWORD port,CLIENT_STRUCT *pRegs,DWORD iotype,DWORD outdata)
{
switch(iotype){
case BYTE_INPUT:
return 0x55;
case WORD_INPUT:
return 0x55AA;
}
return 0;
}
BOOL PppDevice::OnSysDynamicDeviceInit()
{
pPort=new MyPort();
return TRUE;
}

BOOL PppDevice::OnSysDynamicDeviceExit()
{
delete pPort;
return TRUE;
}

头文件:
// PPP.h - include file for VxD PPP

#include <vtoolscp.h>

#define DEVICE_CLASS PppDevice
#define PPP_DeviceID UNDEFINED_DEVICE_ID
#define PPP_Init_Order UNDEFINED_INIT_ORDER
#define PPP_Major 1
#define PPP_Minor 0

class MyPort :public VIOPort
{
public:
MyPort();
~MyPort();
virtual DWORD handler(VMHANDLE hVM,DWORD port,CLIENT_STRUCT *pRegs,DWORD iotype,DWORD outdata);
};
#define MY_PORT_NUMBER 0x3f8

class PppDevice :public VDevice
{
public:
MyPort *pPort;
virtual BOOL OnSysDynamicDeviceInit();
virtual BOOL OnSysDynamicDeviceExit();
};


test小应用程序:
#include<stdio.h>
#include<windows.h>

void main()
{
DWORD a,b;
HANDLE hVxd;
hVxd=CreateFile(\"\\\\\\\\.\\\\ppp.vxd\",0,0,0,CREATE_NEW,FILE_FLAG_DELETE_ON_CLOSE,0);
if(hVxd==INVALID_HANDLE_VALUE)
printf(\"Error!\");
_asm{
xor eax,eax
mov dx,3f8h
in al,dx
mov a,eax
in ax,dx
mov b,eax
}
printf(\"%x,%x\\n\",a,b);
CloseHandle(hVxd);
}

结果:
55,55AA


最后重复说一句:这种hook是针对Ring3应用程序而言。
amei
驱动牛犊
驱动牛犊
  • 注册日期2002-03-21
  • 最后登录2006-11-10
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-07-17 15:03
感谢感谢,我终于捉到com1了。请接分吧!
amei
驱动牛犊
驱动牛犊
  • 注册日期2002-03-21
  • 最后登录2006-11-10
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-07-17 15:28
   不过我还有几个问题不明白,请帮我解答解答吧!
   你说如果我用了Remove_IO_Handler,原本系统的正常服务会变得不正常。而且你在最后还一再说明“这种hook是针对Ring3应用程序而言。”
    是这样的,我在捉到com1口后,我就在handler函数了写了一些东西,开始系统好好的,后来就莫名其妙的自动重启。而且我在vc环境下编的Vxd,打开编辑菜单应该有“构件*.VXD”,也变为“构件*.EXE”了。
我做的改动如下:(其他的和你给我的代码一样)
DWORD MyPort::handler(VMHANDLE hVM,DWORD port,CLIENT_STRUCT *pRegs,DWORD iotype,DWORD outdata)
{switch(iotype){
case BYTE_OUTPUT:
{
 dout<<\"in byte data:\"<<(BYTE)outdata<<endl;
 Simulate_VM_IO( MY_PORT_NUMBER, WORD_OUTPUT, 0x40);
 break;}
case WORD_OUTPUT:dout<<\"in word data:\"<<(WORD)   outdata<<endl;break;
case DWORD_OUTPUT:dout<<\"in dword data:\"<<(DWORD)outdata<<endl;break;
default:break;
}
return 0;
}
我只是想把3f8端口的字节转化为字操作,我发现我的VXD仍会捕捉
Simulate_VM_IO( MY_PORT_NUMBER, WORD_OUTPUT, 0x40)对3f8的操作,而不是执行这个输出操作。以后就只要我执行这个程序,系统就自动重启。
我的问题是:
1。系统自动重启,是因为我用Remove_IO_Handler使系统变得不正常了,还是我在handler里写得不对
2。为什么我在case BYTE_OUTPUT:用Simulate_VM_IO(MY_PORT_NUMBER, WORD_OUTPUT, 0x40);输出数据,还会被我的vxd的
case WORD_OUTPUT:再次捕获,而无法完成我想要的输出呢?
3。如果我想在vxd中也就是在ring0层,实现端口读写,怎么办呢?
我曾在一个VXD中单独用过simulate_VM_IO(0x3f8,WORD_OUTPUT,0x40)
是好用的呀,为什么在这里就不行呢?
    麻烦你了!急切盼望你的回音。




[编辑 -  7/17/02 by  amei]
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-07-17 16:36
我这儿没有问题:
DWORD MyPort::handler(VMHANDLE hVM,DWORD port,CLIENT_STRUCT *pRegs,DWORD iotype,DWORD outdata)
{
switch(iotype){
case BYTE_OUTPUT:
SHELL_Message(Get_Cur_VM_Handle(),MB_OK,\"OUTPUT\",\"BYTE\",NULL,NULL,NULL);
Simulate_VM_IO( MY_PORT_NUMBER, WORD_OUTPUT, 0x40);
break;
case WORD_OUTPUT:
break;
case DWORD_OUTPUT:
break;
default:
break;
}
return 0;
}
你看看其他地方有何问题?

我没98,在2000下编译了vxd还得跑N远去运行,很ft
amei
驱动牛犊
驱动牛犊
  • 注册日期2002-03-21
  • 最后登录2006-11-10
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-07-19 10:53
昨天出了一趟近差,今早回来第一件事就是看帖子。看到你给我回帖很高兴。在你handler改动如下:
case BYTE_OUTPUT:
SHELL_Message(Get_Cur_VM_Handle(),MB_OK,\"OUTPUT\",\"BYTE\",NULL,NULL,NULL);
Simulate_VM_IO( MY_PORT_NUMBER, WORD_OUTPUT, 0x40);
break;
case WORD_OUTPUT:
SHELL_Message(Get_Cur_VM_Handle(),MB_OK,\"OUTPUT\",\"WORD\",NULL,NULL,NULL);
break;
测试程序:
_asm
{mov dx,3f8h
 mov al,34h
 out dx,al
}
当你执行程序后,你会看到执行了两次SHELL_Message函数,一次是BYTE的,一次是WORD的,也就是说VXD捕获了一次字节输出,捕获了一次,字输出。
你测试你的3f8端口了吗?你保证输入了一个40h的字吗?
要使3f8可读写首先要往3fb里输入80h.



[编辑 -  7/19/02 by  amei]
amei
驱动牛犊
驱动牛犊
  • 注册日期2002-03-21
  • 最后登录2006-11-10
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-07-19 15:26
还有一个问题就是
win32程序是在系统虚拟机,dos程序是在虚拟机,vxd 程序在虚拟机之外,当我在vxd中对端口进行访问(比如,往3f8送一个40h),那我在dos下用debug的i,o命令对端口访问(i 3f8), 结果是00 ,是正常的吗?
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-07-20 21:29
昨天出了一趟近差,今早回来第一件事就是看帖子。看到你给我回帖很高兴。在你handler改动如下:
case BYTE_OUTPUT:
SHELL_Message(Get_Cur_VM_Handle(),MB_OK,\"OUTPUT\",\"BYTE\",NULL,NULL,NULL);
Simulate_VM_IO( MY_PORT_NUMBER, WORD_OUTPUT, 0x40);
break;
case WORD_OUTPUT:
SHELL_Message(Get_Cur_VM_Handle(),MB_OK,\"OUTPUT\",\"WORD\",NULL,NULL,NULL);
break;
测试程序:
_asm
{mov dx,3f8h
 mov al,34h
 out dx,al
}
当你执行程序后,你会看到执行了两次SHELL_Message函数,一次是BYTE的,一次是WORD的,也就是说VXD捕获了一次字节输出,捕获了一次,字输出。
你测试你的3f8端口了吗?你保证输入了一个40h的字吗?
要使3f8可读写首先要往3fb里输入80h.

[编辑 -  7/19/02 by  amei]

两三天没上网了,好忙。
捕获两次是因为你用的是Simulate_VM_IO,它并不简单执行out指令。你将其改为_outpw就不会这样了,它就是直接在ring0发端口指令。
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-07-20 21:33
还有一个问题就是
win32程序是在系统虚拟机,dos程序是在虚拟机,vxd 程序在虚拟机之外,当我在vxd中对端口进行访问(比如,往3f8送一个40h),那我在dos下用debug的i,o命令对端口访问(i 3f8), 结果是00 ,是正常的吗?


v86模式下相当于一个更受限制的ring3环境,但是v86监控机有可能在捕获异常后帮助其访问端口,模拟一个正确访问的过程。
amei
驱动牛犊
驱动牛犊
  • 注册日期2002-03-21
  • 最后登录2006-11-10
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-07-23 14:33
多谢多谢!
后来我也用_outpd了。
amei
驱动牛犊
驱动牛犊
  • 注册日期2002-03-21
  • 最后登录2006-11-10
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-07-23 14:38
多谢多谢!
高人呀,你怎么对vxd的函数那么精通呢?能否指点一二!
wangxdong
驱动小牛
驱动小牛
  • 注册日期2002-07-08
  • 最后登录2003-01-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-07-23 18:13
高手高手,我也来灌灌 :D :P
请多多指教!
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-07-23 19:12
多谢多谢!
高人呀,你怎么对vxd的函数那么精通呢?能否指点一二!


精通?才不行呢,一用2000就没写过vxd了,好遥远的东西。
游客

返回顶部