Um Driver NDIS Para Interceptação de Datagramas IP Paulo Fernando da Silva psilva@senior.com.br Sérgio Stringari stringari@furb.br Resumo. Este artigo apresenta o desenvolvimento de um driver NDIS 1 para interceptação de pacotes em redes TCP/IP. Também são demonstradas considerações sobre o funcionamento de um driver e a sua relação com o sistema operacional. São vistas as funções da NDIS utilizadas no driver e a especificação do mesmo. Palavras-chave: Redes de Computadores, Segurança, Driver de Rede, NDIS, Internet. 1 Introdução Muitas ferramentas de rede necessitam dos dados que estão sendo transmitidos pela rede para poderem desempenhar suas tarefas. Porém em alguns sistemas operacionais os aplicativos não conseguem obter tais dados, neste caso é necessário o desenvolvimento de um driver que tenha a capacidade de interceptar pacotes de rede. Um driver é um conjunto de serviços disponibilizados para que se possa interagir com os dispositivos de hardware do sistema. Os sistemas operacionais da Microsoft possuem uma grande variedade de driver s para suporte aos dispositivos mais comuns como teclado, mouse, porta serial, etc. Nos sistemas operacionais da Microsoft, existe uma API específica para o desenvolvimento de driver s de rede, trata-se da NDIS. Esta API fornece funções para que um driver possa interagir com dispositivos de rede e até mesmo gerenciálos. O driver apresentado neste artigo utiliza funções da NDIS para interceptar datagramas IP e passá-los para o programa aplicativo que os tenham solicitado. Assim o programa aplicativo terá acesso aos dados transmitidos pela rede e poderá utiliza-los para desempenhar suas tarefas. 2 Tecnologias Envolvidas no Desenvolvimento do Driver Para que um driver execute a tarefa de monitoração dos pacotes é necessário que o mesmo estabeleça, de alguma forma, uma comunicação com o dispositivo de 1 Network Driver Interface Specification: é uma interface padrão especificação de driver s de rede.
hardware que está recebendo tais dados. Os sistemas operacionais que operam em modo protegido, como é o caso do Windows 98 (o qual foi utilizado para desenvolver o driver apresentado neste artigo), impedem que aplicativos acessem diretamente dispositivos de hardware. Nestes sistemas operacionais somente programas que rodam em um nível privilegiado de execução podem acessar dispositivos de hardware ou estruturas do sistema operacional. Uma visão geral da arquitetura do sistema operacional Windows 98, extraída de Microsoft (1999a), que demonstra esta característica é apresentada na Figura 1. Aplicativos Ferramentas de interface com o usuário Núcleo do Windows 98 Virtual Machine Manager Installable File System Manager Configuration Manager Drivers de Dispositivo Hardware Figura 1: Visão geral da arquitetura do Windows 98. Conforme visto na Figura 1 os programas que rodam em um nível privilegiado de execução e podem acessar diretamente dispositivos de hardware são chamado de drivers de dispositivo (arquivos com a extensão VxD), estes programas podem tanto acessar dispositivos de hardware como simular a existência de tais dispositivos, de forma que um aplicativo possa interagir com um hardware que na verdade não existe.
Os drivers de dispositivo podem oferecer serviços para a manipulação de dispositivos de hardware. Os serviços que um driver de dispositivo oferece podem estar acessando diretamente o dispositivo de hardware ou utilizando os serviços de algum outro driver de dispositivo para isto. Os programas aplicativos que desejam interagir com algum dispositivo de hardware devem faze-lo através de um driver de dispositivo que ofereça serviços para a manipulação de tal hardware, conforme Mendonça (maio 2001) e demonstrado na Figura 2. Aplicativo deseja realizar acesso de I/O. Aplicativo se conecta a um driver de dispositivo. Aplicativo solicita serviços do driver de dispositivo, que tem privilégio alto e que pode realizar o acesso de I/O Vxd realiza o acesso de I/O e devolve ao aplicativo dados lidos da porta. Figura 2: Programa aplicativo acessando um hardware Sendo assim para que o driver apresentado neste artigo seja executado, é necessário que o mesmo seja utilizado por algum programa aplicativo. O aplicativo utiliza serviços oferecidos pelo driver de dispositivo, que roda em um nível de código privilegiado e pode acessar estruturas que o aplicativo não poderia. O driver de dispositivo apresentado neste artigo, não interage diretamente com o dispositivo de hardware, ao invés disto ele utiliza serviços de um outro driver de dispositivo oferecido pelo sistema operacional Windows 98, o Ndis.vxd. Este driver oferece serviços específicos para manipulação de dispositivos de rede, através de uma API chamada NDIS. A NDIS é uma interface padrão para a comunicação dos drivers de placa de adaptador de rede com os drivers de protocolo e o sistema operacional. Duas tecnologias utilizadas para o desenvolvimento do driver e a sua comunicação com programas aplicativos devem ser destacadas:
a) forma como programas aplicativos se comunicam de com o driver de dispositivo da NDIS apresentado neste artigo, utilizando funções da API do Windows 98; b) comunicação do driver de dispositivo apresentado neste artigo com o driver de dispositivo Ndis.vxd, utilizando funções da NDIS. 2.1 Utilização da API do Windows 98 A API do Windows 98 disponibiliza funções para que um programa aplicativo possa abrir, utilizar serviços e fechar um driver de dispositivo, desde que tal driver esteja preparado para oferecer serviços à programas aplicativos. Para um programa aplicativo carregar um driver de dispositivo basta utilizar a função CreateFile e especificar qual driver deseja abrir, se o driver suportar esta operação a função CreateFile irá retornar um código que representa o driver que acabou de ser aberto, este código é chamado de Handle. Se o driver não puder ser aberto por um programa aplicativo a função CreateFile irá retornar um código nulo. A utilização de serviços oferecidos pelo driver de dispositivo é feita através da função DeviceIoControl. O programa aplicativo deve chamar esta função e passar através dela um parâmetro (código de controle) para o driver de dispositivo, quando o driver de dispositivo receber o código de controle, se suportar tal código, irá realizar a operação definida para o respectivo código. A função DeviceIoControl recebe como parâmetro uma estrutura chamada Overlapped, esta estrutura controla operações de I/O assíncronas entre o programa aplicativo e o driver de dispositivo. Dentro do Overlapped existe uma outra estrutura chamada de evento, quando o evento está não-setado significa que o processo associado a este evento não foi completo, quando o evento está setado significa que o processo foi concluído. Quando a função DeviceIoControl retorna um código indicando que a operação está pendente o aplicativo precisa ficar esperando que o processo solicitado seja concluído, ou seja, o evento passe para o estado de setado. Para esperar o resultado de uma comunicação assíncrona é utilizada a função GetOverlappedResult. Para fechar o driver basta utiliza a função CloseHandle para fechar o handle do driver que havia sido aberto anteriormente. Maiores informações sobre funções da API do Windows podem ser encontradas no Microsoft Developer Network (MICROSOFT, 2000a). 2.2 Utilização da API da NDIS A NDIS permite o desenvolvimento de três tipos específicos de driver, conforme demonstrado na Figura 3.
Driver de Protocolo NDIS Driver Intermediário NDIS NDIS Driver NDIS de mini-porta Dispositivo físico de rede Figura 3: Drivers oferecidos pela NDIS. De acordo com a Figura 3 os drivers oferecidos pela NDIS são: a) driver NDIS de miniporta: é o driver de mais baixo nível suportado pela NDIS. Este tipo de driver tem como função principal gerenciar o funcionamento algum tipo de dispositivo físico de rede (hardware). Além disto neste driver devem ser implementadas funções que permitam a comunicação com outros drivers de mais alto nível; b) driver NDIS intermediário: por ser um driver situado em uma posição intermediária, este tipo de driver pode se comunicar com drivers de miniporta e drivers de protocolo. Um driver intermediário não precisa gerenciar um dispositivo físico de rede, ele utiliza funções de drivers de miniporta para se comunicar com o dispositivo de rede, abstraindo detalhes do gerenciamento do dispositivo. Um driver intermediário NDIS pode ser utilizado para fornecer dispositivos de rede virtuais para os drivers de mais alto nível ou para fazer conversão de dados entre diferentes tipos de protocolos de rede;
c) driver de protocolo NDIS: é o driver de mais alto nível suportado pela NDIS. Este tipo de driver tem a capacidade de enviar e receber pacotes solicitados por uma aplicação, ele registra funções na NDIS que são chamadas quando determinados eventos ocorrem. O driver apresentado neste artigo trata-se de uma implementação de um driver de protocolo NDIS, que é notificado cada vez que o dispositivo de rede recebe um novo pacote. 2.2.1 Driver de Protocolo NDIS Para que seja desenvolvido um driver de protocolo NDIS, e o mesmo funcione corretamente, é necessário seguir o formato exigido pela NDIS para este tipo de driver. Na inicialização do driver é necessário que exista uma função que tenha obrigatoriamente o nome DriverEntry e os parâmetros definidos pela NDIS. Esta função tem o objetivo de determinar as características do driver de protocolo que esta iniciando e registrar o driver na NDIS. Para registrar o driver de protocolo na NDIS é utilizada a função NdisRegisterProtocol da API da NDIS. Nas características do driver de protocolo, passadas para a NDIS quando o protocolo é registrado, são definidas várias funções que compõem o protocolo. Algumas destas funções são chamadas pelo driver para fazer com que o protocolo execute certas operações, e outras são chamadas pela NDIS quando determinados eventos ocorrem. Após definir cada uma das funções do driver de protocolo, basta chamar a função que conecta o protocolo a um adaptador de rede e as funções do protocolo começarão a serem chamadas pela NDIS conforme os eventos forem ocorrendo. Para finalizar o funcionamento do protocolo basta chamar a função que desconecta o protocolo do adaptador de rede. Maiores informações sobre drivers NDIS podem ser encontradas no site da Microsoft junto à documentação do Microsoft Driver Development Kit (MICROSOFT; 1999b, 2000b). 3 Desenvolvimento do Driver O driver tem como objetivo interceptar datagramas IP para os mais diversos fins, quem determina a finalidade da interceptação dos datagramas é o programa aplicativo que utiliza o driver. Este driver deve ser utilizado em um host conectado a uma rede que utilize o protocolo TCP/IP (a rede utilizada para desenvolver o driver foi a Internet). Todos os datagramas que trafegarem entre o host e a Internet passarão pelo driver. Um aplicativo que esteja utilizando o driver terá acesso a todas as informações monitoradas pelo mesmo, e poderá utilizar estas informações para desempenhar as suas tarefas.
3.1 Especificação do Driver A especificação do driver foi dividida em dezesseis processos e sub-processos que estão envolvidos nas funções principais de inicializar o funcionamento do driver, tratar solicitações de conexão, desconexão, filtro e recebimento de pacotes, e finalizar o funcionamento do driver. Na Tabela 1 são enumerados os processos do driver juntamente com a descrição de cada um deles. Nome do processo Descrição do processo Processo A Carga do driver Processo B Procedimento de controle Processo C Inicialização Processo D Trata códigos de controle Processo E Trata código de conexão Processo F Trata código de desconexão Processo G Trata código para setar filtro Processo H Trata código para receber pacotes Processo I Protocolo se conecta ao adaptador Processo J Conecta adaptador completado Processo K Protocolo se desconecta ao adaptador Processo L Desconecta adaptador completado Processo M Requisição completada Processo N Protocolo recebe pacotes Processo O Transferência de dados completada Processo P Protocolo se descarrega Tabela 1: Processos do driver. Na Figura 5 é apresentada uma visualização geral da especificação do driver. Nesta figura podemos observar a relação entre os principais processos especificados para o driver. Os processo B e P não estão descritos na visualização geral, pois o processo B é apenas um procedimento para chamar os processos C e D. O processo P é apenas a chamada de uma função para finalizar o protocolo.
Figura 4: Visualização geral do driver. Os processos do driver são ativados pela carga do driver por parte de um programa aplicativo qualquer que o utilize e por códigos enviados por este mesmo programa aplicativo para o driver. Os processos A e C são chamados um após o outro quando a aplicação realiza a carga do driver. O processo D é ativado quando o programa aplicativo que utiliza o driver envia um código de solicitação para o driver, este processo é responsável por chamar os processo E, F, G e H. Os processos I, J, K, L e M são eventos do driver de protocolo definido pelo driver, e são chamados quando o respectivo evento ocorrer. Finalmente, o processo N é chamado pelo driver do adaptador de rede quando um pacote chega ao adaptador. Este processo é responsável pela chamada do processo O. 3.2 Implementação do Driver O driver apresentado neste artigo foi implementado em Silva (2001) e utilizado por um aplicativo que tem como objetivo emitir mensagem de alerta para
o usuário quando ocorrerem situações suspeitas em conexões com redes TCP/IP. As situações suspeitas são previamente configuradas pelo usuário no próprio aplicativo. A implementação do módulo driver deve obedecer a um formato muito específico exigido pela NDIS, para tanto, parte do código foi escrita na linguagem assembly e outra parte na linguagem C. Uma declaração genérica de driver pode ser encontrada em Mendonça (jun. 2001). Na implementação do driver foram utilizados recursos da ferramenta Microsoft DDK (Driver Development Kit) 98. Esta ferramenta provê recursos para o desenvolvimento de drivers para o sistema operacional Windows 98. Os principais recursos oferecidos pelo Microsoft DDK 98 são: a) exemplos dos tipos de driver e de funções disponíveis; b) código-fonte de programas que são utilizados no desenvolvimento dos drivers; c) documentações de como desenvolver os drivers e utilizar funções. Maiores informações sobre o Microsoft DDK 98 podem ser encontradas em Microsoft (1999b, 2000b). Na implementação do driver também foi utilizado o ambiente de desenvolvimento Microsoft Visual C++ 6.0. Maiores informações sobre a implementação do driver, inclusive com especificação e código fonte completos, podem ser encontradas em Silva (2001). 4 Conclusões A NDIS demonstrou ser de grande utilidade no desenvolvimento de driver s de rede. Por ser uma interface padrão implementada pelo sistema operacional, faz com que o desenvolvimento do driver não necessite conhecer detalhes do hardware com o qual está interagindo. Para o desenvolvimento de um driver de rede, basta que sejam conhecidas as interfaces das funções que são disponibilizadas pela NDIS e o objetivo de cada uma destas funções, com isto é possível desenvolver driver s para gerenciar dispositivos de rede ou realizar a interação de programas aplicativos com este dispositivos, como foi o caso do driver apresentado neste artigo. No desenvolvimento de um driver de rede, juntamente com a NDIS, devem ser utilizados recursos do Microsoft DDK, pois esta ferramenta possui exemplos e documentação completa de como utilizar a NDIS no desenvolvimento de driver s de rede. Referências bibliográficas MENDONÇA, Alexandre; ZELENOVSKY, Ricardo; FRANÇA, Paulo R. Programação de hardware em windows 9x/2000 1 o parte. Developer s, Rio de Janeiro, v. 5, n. 57, p 38-41, maio 2001.
MENDONÇA, Alexandre; ZELENOVSKY, Ricardo; FRANÇA, Paulo R. Programação de hardware em Windows 9x/2000 2 o parte. Developer s, Rio de Janeiro, v. 5, n. 58, p 42-44, jun. 2001. MICROSOFT PRESS. Microsoft Windows 98 resource kit. Rio de Janeiro: Campus, 1999. MICROSOFT CORPORATION. Microsoft developer network, 2000. Disponível em <http://msdn.microsoft.com/default.asp>. Acesso em: 20 set. 2001. MICROSOFT CORPORATION. Microsoft Windows 2000 DDK, 2000. Disponível em <http://www.microsoft.com/ddk/w2kddk.asp>. Acesso em: 8 jun. 2001. MICROSOFT CORPORATION. Microsoft Windows 1998 DDK, 1999. Disponível em <http://www.microsoft.com/ddk/ddk98.asp>. Acesso em: 8 jun. 2001. SILVA, Paulo Fernando da. Protótipo de software de segurança em redes para a monitoração de pacotes em uma conexão TCP/IP. 2001, 112f. Trabalho de Conclusão de Curso (Bacharelado em Ciências da Computação) - Centro de Ciências Exatas e Naturais, Universidade Regional de Blumenau, Blumenau.