Por dentro dos Aplicativos Nativos

Mark Russinovich Publicado: 1 de novembro de 2006

Introdução

Se você tiver alguma familiaridade com a arquitetura do NT, provavelmente estará ciente de que a API que os aplicativos Win32 usam não é a API NT "real". Os ambientes operacionais da NT, que incluem POSIX, OS/2 e Win32, conversam com seus aplicativos cliente por meio de suas próprias APIs, mas conversam com o NT usando a API "nativa" do NT. A API nativa está em sua maioria não documentada, com apenas cerca de 25 de suas 250 funções descritas no kit de driver de dispositivo NT Windows.

O que a maioria das pessoas não sabe, no entanto, é que existem aplicativos "nativos" no NT que não são clientes de nenhum dos ambientes operacionais. Esses programas falam a API NT nativa e não podem usar APIs de ambiente operacional como o Win32. Por que esses programas seriam necessários" Qualquer programa que deve ser executado antes do subsistema Win32 ser iniciado (na hora em que a caixa de logon é exibida) deve ser um aplicativo nativo. O exemplo mais visível de um aplicativo nativo é o programa "autochk" que executa o chkdsk durante a inicialização da Tela Azul (é o programa que imprime o "". s na tela). Naturalmente, o servidor do ambiente operacional Win32, CSRSS.EXE (Subsistema de Tempo de Execução Cliente-Servidor), também deve ser um aplicativo nativo.

Neste artigo, descreverei como os aplicativos nativos são criados e como eles funcionam.

Como o Autochk é executado

O Autochk é executado entre o tempo em que os drivers de inicialização do NT e de início do sistema são carregados e a paginação é ativada. Neste ponto da sequência de inicialização, o Gerenciador de Sessão (smss.exe) está inicializando o ambiente em modo de usuário do NT, e nenhum outro programa está ativo. O valor HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute , um MULTI_SZ, contém os nomes e argumentos de programas executados pelo Gerenciador de Sessão e é onde o Autochk é especificado. Aqui está o que você normalmente encontrará se olhar para esse valor, quando "Autochk" recebe "*" como argumento:

Autocheck Autochk *

O Gerenciador de Sessão examina o <diretório winnt>\system32 para os executáveis listados nesse valor. Quando o Autochk é executado, não há arquivos abertos para que o Autochk possa abrir qualquer volume no modo bruto, incluindo a unidade de inicialização, e manipular suas estruturas de dados em disco. Isso não seria possível em nenhum momento posterior.

Criando aplicativos nativos

Microsoft não documenta, mas o utilitário de build do NT DDK sabe como fazer aplicativos nativos (e provavelmente usado para compilar o Autochk). Especifique informações em um arquivo SOURCES que define o aplicativo, o mesmo que seria feito para drivers de dispositivo. No entanto, em vez de indicar ao Build que você deseja um driver, você informa que deseja um aplicativo nativo no arquivo SOURCES assim:

TARGETTYPE=PROGRAM

O utilitário Build usa um makefile padrão para guiá-lo, \ddk\inc\makefile.def, que procura uma biblioteca em tempo de execução chamada nt.lib ao compilar aplicativos nativos. Infelizmente, Microsoft não envia esse arquivo com o DDK (ele está incluído no DDK do Server 2003, mas suspeito que se você vincular a essa versão seu aplicativo nativo não será executado no XP ou Windows 2000). No entanto, você pode contornar esse problema incluindo uma linha em makefile.def que substitui a seleção de nt.lib especificando a biblioteca de runtime do Visual C++, msvcrt.lib

Se você executar o comando Build no ambiente "Checked Build" do DDK, ele produzirá um aplicativo nativo com informações completas de depuração em %BASEDIR%\lib%CPU%\Checked (por exemplo, c:\ddk\lib\i386\checked\native.exe), e, se você executá-lo no ambiente "Free Build", uma versão de lançamento do programa será gerada em %BASEDIR%\lib%CPU%\Free. Esses são os mesmos locais em que as imagens do driver de dispositivo são colocadas pelo Build.

Aplicativos nativos têm extensões de arquivo ".exe", mas você não pode executá-las como Win32 .exe's. Se você tentar, receberá a mensagem:

O aplicativo não pode ser executado no modo NT Windows.

Dentro de um aplicativo nativo

Em vez de winmain ou principal, o ponto de entrada para aplicativos nativos é NtProcessStartup. Além disso, ao contrário dos outros pontos de entrada do Win32, os aplicativos nativos devem acessar uma estrutura de dados passada como seu único parâmetro para localizar argumentos de linha de comando.

A maior parte do ambiente de runtime de um aplicativo nativo é fornecida pelo NTDLL.DLL, a biblioteca de exportação de API nativa do NT. Os aplicativos nativos devem criar seu próprio heap do qual alocar armazenamento usando RtlCreateHeap, uma função NTDLL. A memória é alocada de um heap com RtlAllocateHeap e liberada com RtlFreeHeap. Se um aplicativo nativo quiser imprimir algo na tela, ele deverá usar a função NtDisplayString, que será gerada para a tela azul de inicialização.

Os aplicativos nativos não retornam simplesmente de sua função de inicialização, como programas Win32, pois não há nenhum código de runtime para o qual retornar. Em vez disso, eles precisam ser encerrados chamando NtProcessTerminate.

O runtime NTDLL consiste em centenas de funções que permitem que aplicativos nativos executem E/S de arquivo, interajam com drivers de dispositivo e executem comunicações entre processos. Infelizmente, como afirmou anteriormente, a grande maioria dessas funções não está documentada.