论坛: 原创软件 标题: hi,大家好,我想在win2k下访问我的并口,怎么实现,请给予指教! 复制本贴地址    
作者: kingbug [kingbug]    论坛用户   登录
hi,大家好,我想在win2k下访问我的并口,怎么实现,请给予指教!

win98下可以!

请高手们给一个思路!!

地主 发表时间: 08/02 11:01

回复: tabris17 [tabris17]   论坛用户   登录
NT下所有RING 3进程任意端口I/O

Author: sinister
Email: sinister@whitecell.org
Homepage: http://www.whitecell.org 


(首先说明一下,本文所提到的方法并不是我所发明的,我只不过是按照思路实现
一下罢了。如果您是 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 0x2fab

static 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);
}





B1层 发表时间: 08/03 12:33

回复: tabris17 [tabris17]   论坛用户   登录
到网上找找一个叫WinIO

                        WinIo v1.2                          
    Direct Hardware Access Under Windows 9x/NT/2000         
            Copyright 1998-2000 Yariv Kaplan                
                http://www.internals.com                    
------------------------------------------------------------

The WinIo library allows 32-bit Windows applications to directly
access I/O ports and physical memory.

B2层 发表时间: 08/03 12:34

回复: shesh [shesh]   版主   登录
如果只是简单的发送数据,直接用CreateFile就可以访问了.

B3层 发表时间: 08/03 13:41

回复: kingbug [kingbug]   论坛用户   登录
en 
好的

谢谢

B4层 发表时间: 08/03 14:56

论坛: 原创软件

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号