You are on page 1of 16

PortTalk - A Windows NT I/O Port Device Driver

http://www.beyondlogic.org/porttalk/porttalk.htm

PortTalk - un driver de dispositivo portuario de la entrada-salida de Windows NT


Un problema que plaga Windows NT / 2000 y Windows XP, es l es control terminante sobre puertos de la entradasalida. Desemejante de Windows 95 y de 98, Windows NT /2000/XP causar una excepcin (instruccin privilegiada) si se hace una tentativa de tener acceso a un puerto que te no privilegien para hablar tambin. No es realmente Windows NT que hace esto, solamente ningunos 386 o procesador ms alto que funcionan en modo protegido. Que tiene acceso la entrada-salida a puertos en modo protegido es gobernada por dos acontecimientos, el nivel del privilegio de la entrada-salida (IOPL) en el registro de EFLAGS y el mapa de bits del permiso de la entrada-salida de un segmento del estado de la tarea (TSS). Bajo Windows NT, hay solamente dos niveles del privilegio de la entrada-salida usados, 0 llano y 3 llanos. Los programas de Usermode funcionarn en el nivel 3 del privilegio, mientras que los drivers de dispositivo y el ncleo funcionarn en el nivel 0 del privilegio, designado comnmente el anillo 0. Esto permite el sistema operativo y los conductores confiados en que funcionan en modo del ncleo para tener acceso a los puertos, mientras que evita que menos procesos confiados en del usermode el tacto de los puertos de la entrada-salida y causen conflictos. Todos los programas del usermode deben hablar con un driver de dispositivo que arbitre el acceso. La BITMAP del permiso de la entrada-salida se puede utilizar para no prohibir a bastante no privilegiado de los programas (es decir los programas del usermode) la capacidad de tener acceso a los puertos de la entrada-salida. Cuando se ejecuta una instruccin de la entrada-salida, cheque de la voluntad del procesador el primer si la tarea es bastante privilegiada tener acceso a los puertos. Si ste es el caso, la instruccin de la entrada-salida ser ejecutada. Sin embargo si la tarea no se permite de hacer la entradasalida, el procesador entonces comprobar la BITMAP del permiso de la entrada-salida. La BITMAP del permiso de la entrada-salida, como el nombre sugiere aplicaciones un de un solo bit de representar cada direccin de la entrada-salida. Si el pedacito que corresponde a un puerto se fija, entonces la instruccin generar una excepcin sin embargo si el pedacito est claro que entonces proceder la operacin de la entrada-salida. Esto da medios de permitir que ciertos procesos tengan acceso a ciertos puertos. Hay una BITMAP del permiso de la entrada-salida por tarea.

Puertos de la entrada-salida que tienen acceso debajo de NT/2000/XP Hay dos soluciones a solucionar el problema del acceso de la entrada-salida bajo Windows NT. La primera solucin es escribir un driver de dispositivo que funcione en el anillo 0 (nivel 0 del privilegio de la entrada-salida) al acceso tus puertos de la entrada-salida en tu favor. Los datos se pueden pasar a y desde tu programa del usermode al driver de dispositivo va llamadas de IOCTL. El conductor puede entonces ejecutar tus instrucciones de la entrada-salida. El problema con esto, es que asume que tienes el cdigo de fuente para realizar tal cambio. Otro alternativa posible es modificar la BITMAP del permiso de la entrada-salida para permitir una tarea particular, tiene acceso a ciertos puertos de la entrada-salida. Esto concede tu programa del usermode que funciona en el anillo 3 para hacer operaciones sin restriccin de la entrada-salida en puertos seleccionados, por la BITMAP del permiso de la entrada-salida. Este mtodo realmente no se recomienda, sino proporciona medios de permitir que los usos existentes funcionen bajo Windows NT / 2000. Escribir un driver de dispositivo para apoyar tu hardware es el mtodo preferido. El driver de dispositivo debe comprobar para saber si hay cualquier contencin antes de tener acceso al puerto. Sin embargo, usar un conductor tal como PortTalk puede llegar a ser absolutamente ineficaz. Cada vez que una llamada de IOCTL se hace para leer o para escribir un octeto o una palabra a un puerto, el procesador debe cambiar el anillo 3 a el anillo 0 realiza la operacin, entonces cambia detrs. Si tus intenciones fueran escribir, por ejemplo un programador se programa que en serie usando un perno portuario paralelo, del microcontrolador tendra sentido mejor de enviar un indicador a un almacenador intermediario de x muchos octetos. El driver de dispositivo despus serializara los datos y generara el apretn de manos necesario en la programacin de un dispositivo de PIC. Tal ejemplo es el conductor USBLPTPD11 en http://www.beyondlogic.org/usb/usblptpd11.htm. Este conductor acepta un almacenador intermediario de octetos va el IOCTL_WRITE_I2C IoDeviceCall y entonces explosiones grandes esto hacia fuera en formato de I2C en un perno portuario paralelo. El cdigo de fuente para este conductor est disponible y est bien digno de una mirada. El driver de dispositivo del porttalk viene completo con cdigo de fuente. Proporciona la facilidad para modificar la BITMAP del permiso del IO y/o escribir y leer a los puertos de la entrada-salida va IOCTL llama. Compatibilidad - usar usos existentes bajo Windows NT /2000/XP PortTalk se puede utilizar conjuntamente con allowio para hacer los programas existentes que tienen acceso a los puertos de la entrada-salida trabajan bajo Windows NT /2000/XP. Como sabes ya, cualquier programa 32bit causar una excepcin privilegiada de la instruccin. Muchos cortes se han producido para el acceso portuario de la entrada-salida bajo Windows 95 y 98 tales como bibliotecas de .DLL. Si necesitas funcionar tal programa bajo Windows NT, una excepcin ocurrir. Intento PortTalk. 16 el pedacito los programas de Windows y del DOS funcionar en las mquinas virtuales. En muchos casos los usos existentes deben ser transparentes en Windows NT /2000/XP. Sin embargo otros apenas rechazan funcionar. Las mquinas virtuales tienen ayuda para los puertos de comunicacin, el vdeo, el ratn, y el teclado. Por lo tanto cualquier programa que usa estos puertos comunes de la entrada-salida debe funcionar, no obstante hay a menudo un problema con la sincronizacin. Otros programas del MSDOS que tienen acceso al hardware especfico requieren VDDs (drivers de dispositivo virtuales) escrito

para permitiros ser utilizado con Windows NT. La mquina virtual interceptar operaciones de la entrada-salida y las enviar a un tratante de la entradasalida para procesar. La manera la mquina virtual hace esto, est dando las derechas escasas a las operaciones de la entrada-salida y creando a un tratante de la excepcin para cavar nuevamente dentro del apilado, para encontrar la instruccin pasada y para descifrarla. Dando al VDM las derechas completas a los puertos de la entrada-salida, no tiene ningn medio de interceptar operaciones de la entrada-salida, as creando menos problemas con la sincronizacin o la necesidad de proporcionar VDDs para un hardware ms obscuro. Para cambiar los procesos IOPM, debemos primero tener la identificacin del proceso para el proceso que deseamos conceder el acceso tambin. Esto es lograda creando el proceso ourselves, as que podemos pasar el ProcessID a nuestro driver de dispositivo. Se utiliza un uso pequeo que acepta el nombre del programa como discusin. Este uso entonces crea el proceso (es decir ejecuta el programa) que comienza y contina como otro proceso en el sistema. Nota: Podemos tambin colocar un servicio repetido con el sistema operativo que notifica nuestro conductor de cualquier proceso comenzado y cul es su identificacin. Podemos entonces guardar un directorio de los procesos que deseamos para tener acceso a ciertos puertos. Cuando se ejecuta este proceso, el servicio repetido informa al conductor que ha comenzado y cul es de proceso identificacin es. Podramos entonces cambiar automticamente el IOPM de este proceso. Ver el conductor de proceso del monitor en Process.zip

Cuando un programa del pedacito de Windows 32 se comienza a usar CreateProcess (), volver el ProcessID para el programa de 32 pedacitos. Esto se pasa al driver de dispositivo que usa una llamada de IOCTL.

Los programas del DOS no tienen su propio ProcessID. Funcionan debajo de la mquina virtual del DOS de Windows NT (NTVDM.EXE) que es un subsistema protegido del ambiente que emula MS-DOS. Cuando se llama un programa del DOS usando este programa, conseguir el ProcessID para NTVDM.EXE y consecuentemente cambia IOPM de NTVDM. Sin embargo si NTVDM es ya residente (si otro programa del DOS est funcionando) volver una identificacin del proceso de cero. Esto no causa un problema si el IOPM del NT de la mquina virtual del DOS se fija ya para permitir cualquier operacin del IO, sin embargo si el primer programa del DOS fue llamado de la lnea de comando sin usar AllowIo, el NTVDM no tiene el IOPM modificado. Windows 3.1 programas funcionar con la ULULACIN (Windows en Win32). ste es otro subsistema protegido que funciona dentro del proceso de NTVDM. El funcionamiento de un programa Win3.1 volver el ProcessID de NTVDM de acuerdo con el problema precisado arriba. Cuando el driver de dispositivo tiene el ProcessID, encuentra el indicador para procesar para nuestro programa creado recientemente y fija el IOPM para permitir todas las instrucciones de la entrada-salida. Una vez que el ProcessID se haya dado a nuestro driver de dispositivo de PortTalk, el allowio programa finales. El funcionamiento de un programa de DOS/Win 3.1 debajo de NTVDM.EXE no debe crear normalmente ninguna problemas importante. NTVDM interceptar normalmente la mayora de las llamadas del IO y comprobar estos recursos contra el registro para cerciorarse de son parados. Si son funcionando, una caja de mensaje har estallar como simular a la que est demostrada aqu, dando al usuario la opcin para terminar el programa o para no hacer caso del error. Si el usuario elige no hacer caso del error, tener acceso no ser concedido al puerto de la entrada-salida que se ofende. Al menos usar PortTalk para quitar toda la proteccin de la entrada-salida conceder a uso las derechas completas a cualquier puerto. Consecuentemente si desea hablar con tu ratn en COM1. Resultado - tus heladas del ratn. Usar este programa se debe hacer en la discrecin del usuario informado y educado. Si no, la inestabilidad del sistema resultar. Una solucin a este problema es ser selectiva a qu puertos no prohibes a de total acceso tambin. Llamar tu usar del uso
>allowio Test.exe /a de C:\

conceder a test.exe el acceso exclusivo a todos los puertos. Sin embargo si t uso,
>allowio Test.exe 0x378 de C:\

esto conceder el acceso de test.exe solamente a 0x378 a 0x37F. Pues un octeto representa 8 direcciones portuarias y ese la mayora de los dispositivos utilizarn un banco de 8 o 16 direcciones, no necesitas especificar cada direccin portuaria, solamente un puerto en el lmite de 8 octetos. As 0x378 conceder el acceso de test.exe a LPT1, incluyendo los registros de los datos, del estado y de control. Comenzando e instalando el conductor En la mayora de los casos, el conductor de PORTTALK.SYS no se requiere ser instalado explcitamente. Al funcionar el usermode ejecutable por ejemplo allowio.exe, comprobar para saber si

hay el driver de dispositivo y si no puede ser abierto, instalar y comenzar el conductor para ti. No obstante para que suceda esto correctamente, el conductor de PORTTALK.SYS debe estar en el mismo directorio que el usermode ejecutable funcion y el usuario debe tener privilegios del administrador. Una vez que el conductor haya estado instalado por primera vez, cualquier usuario con privilegios normales del usuario puede tener acceso al driver de dispositivo normalmente. Esto es ideal en sala de clase/ambientes corporativos donde est suprema la seguridad. El conductor se puede tambin instalar manualmente usando el archivo del registro incluido. El copy el PORTTALK.SYS a tu directorio de /system32/drivers y chasca encendido el archivo de PORTTALK.REG para cargar las llaves requeridas del registro. Entonces reanudar la computadora y en cargador-para arriba el conductor de PORTTALK.SYS cargar y comenzar automticamente. Esto se recomienda para la sala de clase/el uso corporativo donde el conductor se puede almacenar lejos con seguridad en el directorio del sistema. Versiones comprobadas y libres del conductor Dos versiones del conductor existen. La distribucin estndar es una versin compilada libre que tiene declaraciones que eliminan errores quitadas y se ejecuta as ms rpidamente. Sin embargo al escribir tu propio cdigo, o eliminando errores de problemas tales como overuns del almacenador intermediario, una versin comprobada del conductor se proporciona que exhibe eliminar errores. stos eliminan errores de mensajes se pueden leer con cualquier bueno eliminan errores del espectador. Un tal espectador recomendado es el sistema Internals DebugView que se puede descargar de su Web site (http://www.sysinternals.com) para libre. La estructura comprobada del conductor se proporciona en la carpeta comprobada de la distribucin. Substituir simplemente el PORTTALK.SYS por este conductor y la recarga a exhibir elimina errores de la informacin. Recompiling el cdigo El cdigo para el driver de dispositivo se ha compilado usando Microsoft C visual y el Windows 2000 DDK. Se proporciona el cdigo de fuente, pero durante el ciclo de desarrollo normal que no se requiere ser recompiled. Tambin se ha construido para los propsitos de prueba en Windows XP DDK que incluye las herramientas de la estructura y es no ms dependiente en Microsoft C visual que es instalado. (Excelente para la gente de Borland) Manipulando el IOPM (BITMAP del permiso de la entrada-salida) Cambiar el IOPM dentro de tus conductores del modo del ncleo requiere el conocimiento de un par de llamadas indocumentadas. stos son Ke386IoSetAccessProcess, Ke386SetIoAccessMap y PsLookupProcessByProcessId.
PsLookupProcessByProcessId (EN ulProcId de ULONG, HACIA FUERA pEProcess del ** del _EPROCESS del struct);

Las rutinas de IOPM utilizan un indicador para procesar y no el ProcessID. Por lo tanto nuestra primera tarea es convertir el ProcessID a un indicador al proceso. Hay llamadas documentadas tales como PsGetCurrentProcess (), no obstante no deseamos el proceso actual sino algo el indicador al proceso del proceso que deseamos conceder el acceso a. Esta informacin se pasa al conductor bajo la forma de

processID. Debemos entonces utilizar la llamada indocumentada PsLookupProcessByProcessId para convertir nuestro ProcessID a un indicador al proceso. Una vez que tengamos un indicador a procesar podemos comenzar a manipular la BITMAP del permiso de la entrada-salida usando las llamadas indocumentadas siguientes
Ke386SetIoAccessMap vaco (interno, IOPM *); Ke386QueryIoAccessMap vaco (interno, IOPM *); Ke386IoSetAccessProcess vaco (PEPROCESS, internos);

Ke386SetIoAccessMap copiar el IOPM especificado a los TSS. Ke386QueryIoAccessMap lo leer de los TSS. El IOPM es el especificar del arsenal de 8192 octetos qu puertos no se prohiben el acceso y que no son. Cada direccin es representada por un pedacito, as los 8192 octetos especificarn el acceso hasta 64K. Cualquier pedacito cero permitir el acceso, mientras que el negar el acceso. Despus de que el IOPM se haya copiado a los TSS, el indicador compensado de IOPM se debe ajustar al punto a nuestro IOPM. Se hace esto usando el Ke386IoSetAccessProcess. El parmetro interno se debe fijar a 1 para permitirte ser fijado. Llamar la funcin con cero quitar el indicador. El hablar con el driver de dispositivo - modo APIs del usuario PortTalk tambin tiene IOCTLs a permitir el leer y el escribir a los puertos de la entrada-salida. En este caso, tu programa del usermode abrira el driver de dispositivo de PortTalk y pasara datos al conductor con llamadas de IOCTL. El conductor entonces habla con los puertos de la entrada-salida en el anillo 0. El conductor de Porttalk contiene dos llamadas de IOCTL para leer en y para escribir a los puertos de la entrada-salida. El archivo de fuente de la CA, pt_iotcl.c se puede utilizar para proporcionar la ayuda fcil basada en las llamadas populares de inportb/outportb y del INP/del outp apoyadas en ambientes de programacin anteriores. Por simplemente incluyendo OpenPortTalk de pt_ioctl.c y el llamar cuando programas comienzo y ClosePortTalk cuando tus finales del programa t pueden tener la funcionalidad de las llamadas de inportb/outportb y del INP/del outp.
caera del __cdecl del vaco del #include del #include del #include (vaco) {valor sin firmar del carbn; printf (IoExample para PortTalk V2.0 \ Peacock 2001 \ nhttp de Craig del nCopyright: /www.beyondlogic.org \ n); OpenPortTalk (); outportb (0x378, 0xFF); valor = inportb (0x378); printf (valor vuelto = 0x%02X \ n, valor); outp (0x378, 0xAA); valor = INP (0x378); printf (valor vuelto = 0x%02X \ n, valor); ClosePortTalk (); }

El programa de muestra arriba se incluye en el directorio de IoExample junto con el pt_ioctl.c. El pt_ioctl se puede utilizar como ejemplo de cmo cargar y abrir el conductor y despus hacer llamadas de IOCTL_WRITE_PORT_UCHAR y de IOCTL_READ_PORT_UCHAR.

Descargar la fuente, los conductores y los programas de Usermode


Versin 2.2, octetos 67K Historia de la revisin
o

6 de abril de 2002 - versin 2.2.

Fij un error tipogrfico del mensaje del eliminar errores en el IoExample.

13 de enero de 2002 - versin 2.1, probada en el Windows 2000 SP2 y Windows XP RTM. Uninstall.exe agregado al reparto con ms viejas versiones de V1.x de PortTalk.

12 de enero de 2002 - versin 2.0, probada en el Windows 2000 SP2 y Windows XP RTM. El uno mismo instala el conductor para la facilidad de empleo. Tipo mejorado comprobacin. Distribuido con el uso de la demostracin del cdigo de IoExample de las macros del INP/del outp de inportb/outportb () () y de las llamadas de IOCTL.

6 de septiembre de 2001 - versin 1.02 Archivo fijo de .reg despus de que el arreglo anterior rompiera la ayuda del Windows 2000. Ahora apoya Windows NT /2000/XP.

26 de junio de 2001 - versin 1.01 Archivo fijo de .reg para apoyar el Windows 2000 y Windows NT4.

13 de marzo de 1999 - primer lanzamiento pblico de la versin 1.0 para Windows NT4.

Informacin importante para aumentar de PortTalk V1.x


Al instalar PortTalk V2.x en las mquinas con una ms vieja versin de V1.x, el conductor existente debe un-ser instalado. Funcionar simplemente el uninstall.exe contenido dentro del paquete de PortTalk con privilegios del administrador. Despus de que se haya quitado el viejo conductor, allowio.exe o IoExample.exe de funcionamiento detectar la ausencia de PortTalk y reinstalar el conductor nuevo. Adems, el conductor se puede quitar manualmente. Esto se recomienda solamente para los usuarios experimentados. Cualquiera

Substituir tu viejo porttalk.sys por la nueva versin y reanudarlo. Suprimir el HKEY_LOCAL_MACHINE \ el sistema \ el currentcontrolset \ los servicios \ la llave del porttalk y reanudarlos. Utilizar el instalador del driver de dispositivo de Windows NT para parar y para quitar el conductor de PortTalk.

Referencias

Kit del driver de dispositivo del NT del Microsoft Windows Microsoft Win32 SDK Manual del revelador de la arquitectura de Intel - arquitectura bsica, pedido nmero 243190. Manual del revelador de la arquitectura de Intel - manual de referencia del sistema de instruccin, pedido nmero 243191. Manual del revelador de la arquitectura de Intel - gua de la programacin de sistema, pedido nmero 243192.
Peacock 1999-2007 - 6 de abril de 2007 de Craig del copyright.

A problem that plagues Windows NT/2000 and Windows XP, is it's strict control over I/O ports. Unlike Windows 95 & 98, Windows NT/2000/XP will cause an exception (Privileged Instruction) if an attempt is made to access a port that you are not privileged to talk too. Actually it's not Windows NT that does this, but any 386 or higher processor running in protected mode. Accessing I/O Ports in protected mode is governed by two events, The I/O privilege level (IOPL) in the EFLAGS register and the I/O permission bit map of a Task

State Segment (TSS). Under Windows NT, there are only two I/O privilege levels used, level 0 & level 3. Usermode programs will run in privilege level 3, while device drivers and the kernel will run in privilege level 0, commonly referred to as ring 0. This allows the trusted operating system and drivers running in kernel mode to access the ports, while preventing less trusted usermode processes from touching the I/O ports and causing conflicts. All usermode programs should talk to a device driver which arbitrates access. The I/O permission bitmap can be used to allow programs not privileged enough (I.e. usermode programs) the ability to access the I/O ports. When an I/O instruction is executed, the processor will first check if the task is privileged enough to access the ports. Should this be the case, the I/O instruction will be executed. However if the task is not allowed to do I/O, the processor will then check the I/O permission bitmap. The I/O permission bitmap, as the name suggests uses a single bit to represent each I/O address. If the bit corresponding to a port is set, then the instruction will generate an exception however if the bit is clear then the I/O operation will proceed. This gives a means to allow certain processes to access certain ports. There is one I/O permission bitmap per task. Accessing I/O Ports under NT/2000/XP There are two solutions to solving the problem of I/O access under Windows NT. The first solution is to write a device driver which runs in ring 0 (I/O privilege level 0) to access your I/O ports on your behalf. Data can be passed to and from your usermode program to the device driver via IOCTL calls. The driver can then execute your I/O instructions. The problem with this, is that it assumes you have the source code to make such a change. Another possible alternative is to modify the I/O permission bitmap to allow a particular task, access to certain I/O ports. This grants your usermode program running in ring 3 to do unrestricted I/O operations on selected ports, per the I/O permission bitmap. This method is not really recommended, but provides a means of allowing existing applications to run under windows NT/2000. Writing a device driver to support your hardware is the preferred method. The device driver should check for any contentions before accessing the port. However, using a driver such as PortTalk can become quite inefficient. Each time an IOCTL call is made to read or write a byte or word to a port, the processor must switch from ring 3 to ring 0 perform the operation, then switch back. If your intentions were to write, for example a microcontroller programmer which is programmed serially using a parallel port pin, it would make better sense to send a pointer to a buffer of x many bytes. The device driver would then serialise the data

and generate the handshake necessary in the programming of a PIC device. Such an example is the USBLPTPD11 driver at http://www.beyondlogic.org/usb/usblptpd11.htm. This driver accepts a buffer of bytes via the IOCTL_WRITE_I2C IoDeviceCall and then big bangs this out in I2C format on a parallel port pin. The source code for this driver is available and is well worth a look. The porttalk device driver comes complete with source code. It provides the facility to modify the IO permission bitmap and/or write and read to I/O ports via IOCTL calls. Compatibility - Using existing applications under Windows NT/2000/XP PortTalk can be used in conjunction with allowio to make existing programs that access the I/O ports work under Windows NT/2000/XP. As you already know, any 32bit program will cause a Privileged Instruction Exception. Many hacks have been produced for I/O port access under Windows 95 and 98 such as .DLL libraries. Should you need to run such a program under Windows NT, an exception will occur. Try PortTalk. 16 Bit Windows and DOS programs will run on virtual machines. In many cases existing applications should be transparent on Windows NT/2000/XP. However others just refuse to run. The virtual machines has support for communication ports, video, mouse, and keyboard. Therefore any program using these common I/O ports should run, however there is often a problem with timing. Other MSDOS programs accessing specific hardware requires VDDs (Virtual Device Drivers) written to enable them to be used with Windows NT. The Virtual Machine will intercept I/O operations and send them to a I/O handler for processing. The way the Virtual Machine does this, is by giving insufficient rights to I/O operations and creating an exception handler to dig back into the stack, find the last instruction and decode it. By giving the VDM full rights to I/O ports, it has no means of intercepting I/O operations, thus creating less problems with timing or the need to provide VDDs for obscurer hardware. In order to change a processes IOPM, we must first have the process ID for the process we want to grant access too. This is accomplished by creating the process ourselves, so we can pass the ProcessID to our device driver. An small application is used which accepts the program name as an argument. This application then creates the process (i.e. executes the program) which starts and continues as another process in the system. Note : We can also register a callback with the operating system which notifies our driver of any processes started and what their ID is. We can then keep a directory of processes that we want to have access to certain ports. When this process is executed, the callback informs the driver it has started and what it's process ID is. We could then automatically change the IOPM of this process. See

the Process Monitor driver at Process.zip

When a Windows 32 bit program is started using CreateProcess(), it will return the ProcessID for the 32 Bit Program. This is passed to the Device Driver using an IOCTL Call. DOS programs do not have their own ProcessID's. They run under the Windows NT Virtual DOS Machine (NTVDM.EXE) which is a protected environment subsystem that emulates MS-DOS. When a DOS program is called using this program, it will get the ProcessID for NTVDM.EXE and as a result changes NTVDM's IOPM. However if NTVDM is already resident (if another DOS Program is running) it will return a process ID of zero. This doesn't cause a problem if the NT Virtual DOS Machine's IOPM is already set to allow any IO operation, however if the first DOS program was called from the command line without using "AllowIo", the NTVDM will not have the modified IOPM. Windows 3.1 programs will run using WOW (Windows on Win32). This is another protected subsystem that runs within the NTVDM process. Running a Win3.1 program will return the ProcessID of NTVDM in accordance with the problem set out above. When the device driver has the ProcessID, it finds the pointer to process for our newly created program and sets the IOPM to allow all I/O instructions. Once the ProcessID has been given to our PortTalk device driver, the allowio programs

finishes. Running a DOS/Win 3.1 program normally under NTVDM.EXE should not create any major problems. NTVDM will normally intercept most IO calls and check these resources against the registry to make sure they are not in use. Should they be in use, a message box will pop as simular to the one shown here, giving the user the option to terminate the program or ignore the error. If the user chooses to ignore the error, access will NOT be granted to the offending I/O Port. However using PortTalk to remove all I/O Protection will grant the application full rights to any port. As a result if it wants to talk to your mouse on COM1, it will. Result - Your mouse freezes. Using this program should be done at the discretion of the informed and educated user. If not, system instability will result. One solution to this problem is to be selective to what ports you allow full access too. Calling your application using
C:\>allowio Test.exe /a

will grant test.exe exclusive access to all ports. However if you use,
C:\>allowio Test.exe 0x378

this will grant test.exe access only to 0x378 to 0x37F. As one byte represents 8 port addresses and that most devices will use a bank of 8 or 16 addresses, you need not specify every port address, only one port in the 8 byte boundary. Thus 0x378 will grant test.exe access to LPT1, including the data, status and control registers. Starting and installing the driver In most cases, the PORTTALK.SYS driver isn't required to be explicitly installed. When running the usermode executable such as allowio.exe, it will check for the device driver and if it cannot be opened, it will install and start the driver for you. However for this to happen correctly, the PORTTALK.SYS driver must be in the same directory than the usermode executable ran and the user must have administrator privileges. Once the driver has been installed for the first time, any user with normal user privileges can access the device driver normally. This is ideal in classroom/corporate environments where security is paramount. The driver can also be installed manually using the registry file included. Copy the PORTTALK.SYS to your /system32/drivers directory and click on the PORTTALK.REG file to load the required registry keys. Then reboot the computer and on boot-up the PORTTALK.SYS driver will load and start automatically. This is recommended for classroom/corporate use where the driver can be stored away securely in the system directory. Checked and Free Driver Versions

Two versions of the driver exist. The standard distribution is a free compiled version which has debugging statements removed and thus execute faster. However when writing your own code, or debugging problems such as buffer overuns, a checked version of the driver is provided which displays debugging. These debug messages can be read with any good debug viewer. One such recommended viewer is the System Internals DebugView which can be downloaded from their website (http://www.sysinternals.com) for free. The checked build of the driver is provided in the checked folder of the distribution. Simply replace the PORTTALK.SYS with this driver and reload to display debug information. Recompiling the code The code for the device driver has been compiled using Microsoft Visual C and the Windows 2000 DDK. The source code is provided, but during the normal development cycle it is not required to be recompiled. It has also been built for testing purposes on the Windows XP DDK which includes build tools and is no longer dependent on Microsoft Visual C being installed. (Excellent for Borland Folks) Manipulating the IOPM (I/O Permission Bitmap) Changing the IOPM within your Kernel Mode Drivers requires the knowledge of a couple of undocumented calls. These are Ke386IoSetAccessProcess, Ke386SetIoAccessMap and PsLookupProcessByProcessId.
PsLookupProcessByProcessId(IN ULONG ulProcId,OUT struct _EPROCESS ** pEProcess);

The IOPM routines use a Pointer to Process and not the ProcessID. Therefore our first task is to convert the ProcessID to a Pointer to Process. There are documented calls such as PsGetCurrentProcess(), however we don't want the current process but rather the pointer to process of the process we wish to grant access to. This information is passed to the driver in the form of a processID. We must then use the undocumented call PsLookupProcessByProcessId to convert our ProcessID to a Pointer to Process. Once we have a Pointer to Process we can start manipulating the I/O permission bitmap using the following undocumented calls
void Ke386SetIoAccessMap(int, IOPM *); void Ke386QueryIoAccessMap(int, IOPM *); void Ke386IoSetAccessProcess(PEPROCESS, int);

Ke386SetIoAccessMap will copy the IOPM specified to the TSS. Ke386QueryIoAccessMap will read it from the TSS. The IOPM is a 8192 byte array specifying which ports are allowed access and which ones aren't. Each address is represented by one bit, thus the 8192 bytes will specify access up to

64K. Any zero bit will allow access, while a one will deny access. After the IOPM has been copied to the TSS, the IOPM offset pointer must be adjusted to point to our IOPM. This is done using the Ke386IoSetAccessProcess. The int parameter must be set to 1 to enable it to be set. Calling the function with zero will remove the pointer. Talking to the Device Driver - User Mode APIs PortTalk also has IOCTLs to allow reading and writing to I/O Ports. In this case, your usermode program would open the PortTalk device driver and pass data to the driver through IOCTL calls. The driver then talks to the I/O port(s) in ring 0. The Porttalk driver contains two IOCTL calls to read from and write to I/O Ports. A c source file, pt_iotcl.c can be used to provide easy support based on the popular inportb/outportb and inp/outp calls supported in earlier programming environments. By simply including pt_ioctl.c and calling OpenPortTalk when you program starts and ClosePortTalk when your program finishes you can have the functionality of the inportb/outportb and inp/outp calls.
#include #include #include void __cdecl main(void) { unsigned char value; printf("IoExample for PortTalk V2.0\nCopyright 2001 Craig Peacock\nhttp://www.beyondlogic.org\n"); OpenPortTalk(); outportb(0x378, 0xFF); value = inportb(0x378); printf("Value returned = 0x%02X \n",value); outp(0x378, 0xAA); value = inp(0x378); printf("Value returned = 0x%02X \n",value); ClosePortTalk(); }

The sample program above is included in the IoExample directory along with the pt_ioctl.c. The pt_ioctl can be used as an example of how to load and open the driver and then make IOCTL_WRITE_PORT_UCHAR and IOCTL_READ_PORT_UCHAR calls.

Downloading the Source, Drivers and Usermode Programs


Version 2.2, 67K bytes Revision History
o

6th April 2002 - Version 2.2. Fixed a debug message typo in the IoExample.

13th January 2002 - Version 2.1, tested on Windows 2000 SP2 and Windows XP RTM. Added uninstall.exe to deal with older V1.x versions of PortTalk.

12th January 2002 Version 2.0, tested on Windows 2000 SP2 and Windows XP RTM. Self installs driver for ease of use. Improved type checking. Distributed with IoExample code showing use of inportb/outportb() inp/outp() macros and IOCTL calls.

6th September 2001 Version 1.02 Fixed .reg file after previous fix broke Windows 2000 Support. Now supports Windows NT/2000/XP.

26th June 2001 Version 1.01 Fixed .reg file to support both Windows 2000 and Windows NT4.

13th March 1999 Version 1.0 first public release for Windows NT4.

Important information for upgrading from PortTalk V1.x


When installing PortTalk V2.x on machines with an older version of V1.x, the existing driver must be un-installed. Simply run the uninstall.exe contained within the PortTalk package with administrator privileges. After the old driver has been removed, running allowio.exe or IoExample.exe will detect the absence of PortTalk and re-install the new driver. Additionally, the driver can be removed manually. This is only recommended for advanced users. Either

Replace your old porttalk.sys with the new version and reboot. Delete the HKEY_LOCAL_MACHINE\system\currentcontrolset\services\porttalk key and reboot. Use the Windows NT Device Driver Installer to stop and remove the

PortTalk Driver. References


Microsoft Windows NT Device Driver Kit Microsoft Win32 SDK Intel Architecture Developers Manual - Basic Architecture, Order Number 243190. Intel Architecture Developers Manual - Instruction Set Reference Manual, Order Number 243191. Intel Architecture Developers Manual - System Programming Guide, Order Number 243192.

Copyright 1999-2007 Craig Peacock - 6th April 2007.

You might also like