[求助]2000下对端口操作的方法? 在9x下对端口操作可以用_inp() _outp()等函数由于2000对硬件操作的限制,此类函数已经不能再用请教大家如何在2000下对端口操作,同时该方法在9x下兼容期待回复,谢谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 使用winio库吧,2k下好像只能进入内核模式才行了,要不就写驱动,像winio那样,我觉得 Ke386SetIoAccessMapKe386IoSetAccessProcess -------------------------------------------------------------------上面的解答我看得不太懂,能解答详细一点吗?1.使用winio能兼容98吗?2.我看见有人写过dll文件,可以提供对I/O口操作的函数,请问是怎么实现的?------------------------------------------------------------------- 文章找到了,自己看吧,98不知道行不行,要不就行RING0吧NT下所有RING 3进程任意端口IO(首先说明一下,本文所提到的方法并不是我所发明的,我只不过是按照思路实现一下罢了。如果您是 NT KERNEL 的高手,那么还是别看了,免得耽误时间。)以NT内核为基础的OS出于对安全的考虑,对I/O端口实行了严格限制。即在 RING 3 下所有进程均不许直接进行端口I/O操作。这虽然提高安全性,但也给程序员们带来了不少麻烦。关于 RING 3 下端口I/O 也有过不少讨论。一种方法是利用未公开的内核函数 Ke386SetIoAccessMap,Ke386IoSetAccessProcess,来设置 TSS 中的IOPM。这种方法只能指定某一个 RING 3 进程允许端口I/O。还有就是直接手工设置标志寄存器中的IOPL位与TSS中的IOPM。(INTEL 手册中还提到了如果 CPL = 0的情况下,那么 IOPL 也同样受到影响)。这里介绍了另一种方式,也就是通过直接设置 TSS 的段界限来实现 RING 3 进程任意端口I/O。下面的代码演示了这一过程。错误之处还望各位指正。/*****************************************************************文件名 : WssIo.c描述 : 任意端口读写作者 : sinister最后修改日期 : 2002-11-02*****************************************************************/#include "ntddk.h"#include "string.h"#ifndef DWORD#define DWORD unsigned int#endif#ifndef WORD#define WORD unsigned short#endif#define NOT_BUSY 9#define DEFAULT_TSS_LIMIT 0x20ab //缺省的 TSS 段界限#define NEW_TSS_LIMIT 0x2fabstatic NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);#pragma pack(push,1)typedef struct tagGDTR{WORD wLimit;DWORD *dwBase;}GDTR, *PGDTR;typedef struct tagGDTENTRY{DWORD dwLimit : 16;DWORD dwBaselo : 16;DWORD dwBasemid : 8;DWORD dwType : 4;DWORD dwSystem : 1;DWORD dwDpl : 2;DWORD dwPresent : 1;DWORD dwLimithi : 4;DWORD dwAvailable : 1;DWORD dwZero : 1;DWORD dwSize : 1;DWORD dwGranularity : 1;DWORD dwBasehi : 8;} GDTENTRY, *PGDTENTRY;#pragma pack(pop)VOID SetAllPorcIO( int iTrue ){GDTR gdtr;PGDTENTRY gdt;WORD TSSseg;__asm {cli // 屏蔽中断sgdt gdtr // 得到 GDT 基地址与段界限str TSSseg // 得到 TSS 选择子movzx esi,TSSseg // 扩展到 ESI 中以便计算add esi,gdtr.dwBase // 得到 TSS 在 GDT 中描述符 mov gdt,esi}if ( iTrue == 1 ) {gdt->dwLimit = NEW_TSS_LIMIT; // 设置新的 TSS 段界限}else {gdt->dwLimit = DEFAULT_TSS_LIMIT;}gdt->dwType = NOT_BUSY; //必须设置为NOTBUSY状态__asm {ltr TSSseg // 将设置好的 TSS 重新装入sti // 开中断}}// 驱动入口NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) {UNICODE_STRING nameString, linkString;PDEVICE_OBJECT deviceObject;NTSTATUS status;HANDLE hHandle;int i;//卸载驱动DriverObject->DriverUnload = DriverUnload;//建立设备RtlInitUnicodeString( &nameString, L"\\Device\\WssIo" );status = IoCreateDevice( DriverObject,0,&nameString,FILE_DEVICE_UNKNOWN,0,TRUE,&deviceObject);if (!NT_SUCCESS( status ))return status;RtlInitUnicodeString( &linkString, L"\\DosDevices\\WssIo" );status = IoCreateSymbolicLink (&linkString, &nameString);if (!NT_SUCCESS( status )){IoDeleteDevice (DriverObject->DeviceObject);return status;} SetAllPorcIO(1);for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {DriverObject->MajorFunction[i] = MydrvDispatch;}DriverObject->DriverUnload = DriverUnload;return STATUS_SUCCESS; } //处理设备对象操作static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ Irp->IoStatus.Status = STATUS_SUCCESS;Irp->IoStatus.Information = 0L;IoCompleteRequest( Irp, 0 );return Irp->IoStatus.Status;}VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject){UNICODE_STRING nameString;SetAllPorcIO(0);RtlInitUnicodeString( &nameString, L"\\DosDevices\\WssIo" ); IoDeleteSymbolicLink(&nameString);IoDeleteDevice(pDriverObject->DeviceObject);return;}应用层测试程序void main(){int i = 0;__asm {mov al,0a0hmov dx,0388hout dx,almov dx,0388hin al,dxmov byte ptr i,al}printf("%d\n",i);}关于我们: WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。 WSS 主页:http://www.whitecell.org/ vs2008对话框使用shockwave flash object控件问题 VC6简单问题:WCHAR c = L'我'; 为什么不能GetActiveView? 为什会有警告呢?? 请教几个C++的名词 我在程序中用afxbeginthread()开始一个线程,我怎样在这个线程的外部结束他,用什么函数 ==急==急==急==是MUTEX的,把我急死了。怎么我WAIT到了,没有释放,下面还能WAIT到???? pb中使用条形码控件MSBCODE9.OCX? 关于MUTEX的使用 指针操作 这样的错误如何解决? 菜鸟问题,组合框的用法,我的下拉框总是不出??
要不就写驱动,像winio那样,我觉得
Ke386IoSetAccessProcess
上面的解答我看得不太懂,能解答详细一点吗?1.使用winio能兼容98吗?2.我看见有人写过dll文件,可以提供对I/O口操作的函数,请问是怎么实现的?-------------------------------------------------------------------
/*****************************************************************
文件名 : WssIo.c
描述 : 任意端口读写
作者 : sinister
最后修改日期 : 2002-11-02
*****************************************************************/#include "ntddk.h"
#include "string.h"#ifndef DWORD
#define DWORD unsigned int
#endif#ifndef WORD
#define WORD unsigned short
#endif#define NOT_BUSY 9
#define DEFAULT_TSS_LIMIT 0x20ab //缺省的 TSS 段界限
#define NEW_TSS_LIMIT 0x2fabstatic NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);#pragma pack(push,1)
typedef struct tagGDTR{
WORD wLimit;
DWORD *dwBase;
}GDTR, *PGDTR;typedef struct tagGDTENTRY{
DWORD dwLimit : 16;
DWORD dwBaselo : 16;
DWORD dwBasemid : 8;
DWORD dwType : 4;
DWORD dwSystem : 1;
DWORD dwDpl : 2;
DWORD dwPresent : 1;
DWORD dwLimithi : 4;
DWORD dwAvailable : 1;
DWORD dwZero : 1;
DWORD dwSize : 1;
DWORD dwGranularity : 1;
DWORD dwBasehi : 8;
} GDTENTRY, *PGDTENTRY;#pragma pack(pop)VOID SetAllPorcIO( int iTrue )
{
GDTR gdtr;
PGDTENTRY gdt;WORD TSSseg;
__asm {
cli // 屏蔽中断
sgdt gdtr // 得到 GDT 基地址与段界限
str TSSseg // 得到 TSS 选择子
movzx esi,TSSseg // 扩展到 ESI 中以便计算
add esi,gdtr.dwBase // 得到 TSS 在 GDT 中描述符
mov gdt,esi
}if ( iTrue == 1 )
{
gdt->dwLimit = NEW_TSS_LIMIT; // 设置新的 TSS 段界限
}else {
gdt->dwLimit = DEFAULT_TSS_LIMIT;
}gdt->dwType = NOT_BUSY; //必须设置为NOTBUSY状态__asm {
ltr TSSseg // 将设置好的 TSS 重新装入
sti // 开中断
}
}
// 驱动入口
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{UNICODE_STRING nameString, linkString;
PDEVICE_OBJECT deviceObject;
NTSTATUS status;
HANDLE hHandle;
int i;
//卸载驱动
DriverObject->DriverUnload = DriverUnload;//建立设备
RtlInitUnicodeString( &nameString, L"\\Device\\WssIo" );status = IoCreateDevice( DriverObject,
0,
&nameString,
FILE_DEVICE_UNKNOWN,
0,
TRUE,
&deviceObject
);
if (!NT_SUCCESS( status ))
return status;
RtlInitUnicodeString( &linkString, L"\\DosDevices\\WssIo" );status = IoCreateSymbolicLink (&linkString, &nameString);if (!NT_SUCCESS( status ))
{
IoDeleteDevice (DriverObject->DeviceObject);
return status;
} SetAllPorcIO(1);for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {DriverObject->MajorFunction[i] = MydrvDispatch;
}DriverObject->DriverUnload = DriverUnload;return STATUS_SUCCESS;
}
//处理设备对象操作static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0L;
IoCompleteRequest( Irp, 0 );
return Irp->IoStatus.Status;}
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject)
{
UNICODE_STRING nameString;SetAllPorcIO(0);RtlInitUnicodeString( &nameString, L"\\DosDevices\\WssIo" );
IoDeleteSymbolicLink(&nameString);
IoDeleteDevice(pDriverObject->DeviceObject);return;
}
应用层测试程序void main()
{
int i = 0;
__asm {
mov al,0a0h
mov dx,0388h
out dx,al
mov dx,0388h
in al,dx
mov byte ptr i,al
}printf("%d\n",i);
}
关于我们: WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
WSS 主页:http://www.whitecell.org/