Um guia para o DEBUG
( Programa Microsoft® DEBUG.EXE )
Direitos reservados©2004,2007,2009,2017 para Daniel B. Sedory
Esta página pode ser copiada gratuitamente apenas para uso pessoal !
( Não pode ser usada para qualquer outro propósito, a menos que você tenha
primeiro contatado (somente em inglês) e tenha recebido permissão do autor ! )
Sítio traduzido para a língua portuguesa por
Augusto Manzano com autorização expressa de Daniel B. Sedory
(vide final da página 2).
Acesse aqui a versão original em inglês.
Em 1980, Tim Paterson começou a trabalhar em um sistema operacional de 16 bits para a placa 8086 S-100 que ele havia projetado para a SCP (Seattle Computer Products) no ano anterior. Para o correto funcionamento de seu sistema, chamado QDOS (posteriormente denominado 86-DOS) Tim criou um depurador e um chip de ROM: o código dessa ROM foi lançado no regime de domínio público. Mais tarde, Tim adaptou o código para ser executado como um programa .COM em QDOS e adicionou a capacidade de desmontar o código de máquina do processador 8086. Enquanto isso, a Microsoft® estava comprando os direitos do sistema QDOS de Tim para a IBM® que projetava 'secretamente' seu PC. Tim foi contratado pela Microsoft como o principal autor de seu primeiro sistema operacional. Quando completou seu trabalho no IBM Personal Computer™ DOS 1.00 em 1981, seu utilitário DEBUG.COM foi incluído nele. Todas as funcionalidades implementadas por Tim no DEBUG ainda estão no programa e pouco foi adicionado a ele (a principal exceção é o comando Assemble (montagem), implementado no DOS 2.0.
[ Agradeço ao próprio Tim Paterson por ter analisado esta perspectiva no início do DEBUG. ]
Com o lançamento do DOS 2.0 o DEBUG ganhou a capacidade de montar instruções diretamente no código de máquina (comando A). Este é um dos comandos mais importantes para muitos de seus usuários. Embora falte muito da funcionalidade de um Assembler autônomo, como por exemplo, executar Jumps (saltos) baseados em rótulos (só é aceito saltos com endereços hexadecimais), muitos programas .COM úteis foram escritos com este comando. No DOS 3.0 o comando P (Proceed) de prosseguir foi adicionado permitindo ao DEBUG executar sub-rotinas. Ao mesmo tempo, tornou-se possível fazer uso de Interrupções com o comando T (Trace) de acompanhamento. Quando o DOS passou a fazer uso de funções EMS (Memória Expandida) sob o DOS 4.0, quatro novos comandos: xa, xd, xm e xs foram adicionados ao DEBUG e são raramente usados por nós programadores. Para a maioria de nós, a única alteração notável no DEBUG foi a inclusão do comando de ajuda '?' no DOS 5.0.
O código DEBUG passou por uma série de mudanças (e também de 'correções de erros') ao longo dos anos. Algumas dessas alterações internas foram relacionadas às chamadas do sistema DOS e à saída da tela, então, houve a alteração no suporte do tipo de arquivo .COM para .EXE no DOS 5.0. Apesar de todas essas mudanças e outras que se seguiram, o DEBUG nunca teve uma revisão oficial desde a versão 2.40 (esses dígitos foram incorporados em todas as versões do DEBUG desde o DOS 3.0). Só podemos especular sobre os reais motivos pelos quais a Microsoft® nunca atualizou o DEBUG para lidar com instruções além dos processadores Intel® 8086/8087/8088. A Microsoft® desenvolveu seu próprio Assembler (MASM), compilador 'C' e Debugger (CodeView) que também poderia ser usado, se você estivesse disposto a pagar um valor extra por isso de modo que poderia ter sido esse um dos motivos para não focar o programa DEBUG. Ao invés de usar o MASM e o CodeView muitos optaram pelo montador Borland® (TASM) e pelo Turbo™ Debugger mais baratos quando lançados ou usaram outros produtos comerciais. No entanto, os usuários e estudantes podem aprender muito sobre a linguagem Assembly ao utilizarem o programa DEBUG.
As estruturas internas dessas versões do Windows® para o DEBUG parecem muito diferentes de qualquer estrutura usada anteriormente no DOS, pelo menos à primeira vista. No entanto, você encontrará a indicação "Vers 2.40" em um local diferente. O próprio Windows® passou por muitas mudanças durante esse período, como lidar com o sistema de arquivos FAT32. Mas sem acesso ao código fonte não podemos ter certeza se houve grandes diferenças no DEBUG. As mudanças podem ocorrer devido a algo simples como apenas reorganizar as mensagens de erro no código-fonte e/ou usar um novo Assembler/Linkeditor.
O DEBUG sempre foi uma ferramenta eficaz nas mãos de qualquer programador, mas algum tempo após a introdução do Windows™ 95 e especialmente com o Windows™ 98, essa eficácia diminuiu quando seus comandos de I/O se tornaram menos confiáveis. Seja devido a um 'bug' no DEBUG propriamente dito ou no Windows®. O fato é que os comandos de I/O no Windows™ 9x/Me não são confiáveis para acesso direto a discos rígidos. Se você executar nosso ATA drive ID script (somente em inglês) no Win9x/Me, verá que os dados retornados são tão interessantes quanto perturbadores: parece que todos os demais bytes ainda estão corretos. Então, a pergunta que não quer calar é: qual a causa desse problema?
O programa DEBUG incluído no Windows® NT/2000/XP/2003 parece operar de maneira semelhante junto ao DOS 5.0, mas com duas principais exceções:
1) No DEBUG não é permitido carregar ou escrever em nenhum setor de HDD lógico. Somente os arquivos nomeados ainda podem ser lidos ou gravados em um sistema operacional do tipo NT. No entanto, é possível acessar setores de disquete nas unidades de drives A:\ ou B:\ com o comando L (Load) de carregar e W (Write) de escrever, mas somente se os disquetes contiverem um sistema de arquivos que o sistema operacional host (2000, XP, 2003) pode reconhecer.
(Consulte comando L na seção Tutorial [somente em inglês] para obter mais informações.)
[ Obs: O DEBUG nunca conseguiu acessar diretamente áreas de um disco rígido fora dos volumes de unidade, como uma tabela de partição estendida ou mesmo o setor MBR. No entanto, o DEBUG pode ser usado para acessar esses dados programando-os para executar comandos INT13 ou usando um arquivo de script sob DOS (por exemplo, nosso antigo script CopyMBR [somente em inglês]). Note que nenhuma versão do Windows após o Win98/ME permitirá acesso aos comandos INT13. ]
2) Os comandos I e O são essencialmente inúteis, uma vez que a interface do programa com o resto do sistema só está sendo emulado sob essas versões do Windows® ao invés de ter acesso direto ao hardware. Isso já era recorrente em versões anteriores do Windows®.
Isso pode surpreendê-lo: propositadamente mencionamos a versão do DOS 5.0 do DEBUG já que o arquivo DEBUG.EXE incluído no Windows® XP (e todas as outras versões da série NT são exatamente o mesmo arquivo de programa criado para o MS-DOS 5.0 com md5sum = c17afa0aad78c621f818dd6729572c48). O DEBUG era apenas mais um dos pequenos programas do DOS 5.0 que não exigiam alterações para serem executados em um sistema operacional NT. É quase irônico que outro desses programas seja o EDLIN, um editor de linha não apreciado pela maioria dos usuários do DOS. Embora o EDLIN tenha sido criado por Tim Paterson, ele fez isso em duas semanas e ficou chocado quando soube que a IBM tinha incluído esse programa na versão 1.00 do PC-DOS. Sem sombra dúvida, Tim desejava que esse programa tivesse sido substituído por algo melhor em 1981. Isso não ocorreu até o lançamento do DOS 5.0, quando o EDLIN foi efetivamente substituído pelo programa Microsoft EDIT.COM (v 1.0 no ano de 1991. Obs: A primeira versão do EDIT necessitava do programa QBASIC para ser executado). No entanto, o programa EDLIN foi mantido para ser 'compatível' com versões anteriores de vários arquivos Batch de terceiros. Embora o NOTEPAD, mais avançado, esteja presente no Windows™, você pode usar a versão autônoma de 1995 do programa EDIT(v 2.0.026) no prompt de comando do Windows™ XP: seus menus respondem adequadamento aos cliques do mouse.
Embora tenha sido criado no início da era do processador de 16 bits (antes dos 80286 existirem) as versões mais recentes do DEBUG (como as encontradas no arquivo EBD.CAB do disquete de inicialização de emergência do Windows™ Me ou 98SE) ainda são úteis para técnicos de PCs no que tange ao acesso direto a determinadas posições de memória em sistemas atuais como por exemplo (Intel® Pentium™ IV). O DEBUG também pode ser muito útil para fins educacionais. E mesmo para depurar o código de montagem que é necessário durante o processo de inicialização: o software que verifica a tabela de partição em discos rígidos e carrega os setores de inicialização do sistema operacional na memória. Infelizmente, muitos dos programas de inicialização de setores MBR mais recentes usam instruções que exigem uma CPU de classe 386 (ou mesmo 486) para funcionar, tornando difícil usar DEBUG para tal propósito Devido às questões de compatibilidade com versões anteriores da maioria dos processadores Intel® e ao fato de que foi incluído no Microsoft® Windows™ XP e 2003 o DEBUG teve uma vida útil muito maior do que o esperado. Embora a CPU ITANIUM™ não fosse x86-compatível o processador AMD64 era. Em 2005 a Intel® criou as chamadas CPUs "x64-based" que eram mais uma vez x86-compatíveis. Então o DEBUG continua a encontrar algum uso em computadores de 64 bits, até mesmo nas máquinas baseada no Intel® Core™ 2 Quad (4 processors in one).
Sim, o programa DEBUG e alguns outros utilitários anteriores a época do DOS foram removidos da linha de comando da versão de 64 bits do Windows 7 e nunca mais serão usados no sistema operacional Microsoft. No entanto, é possível há algum tempo executar o IBM PC DOS 1.x0, 2.x0 e 3.30 (e possivelmente outros) juntamente com suas versões do DEBUG em uma pequena janela no Windows XP (32-bit), Windows 7 (64-bit), 8 e até a última atualização do Windows 10 (Anniversary). Leia aqui sobre o programa PCE (PC Emulator) de Hampa Hug (somente em inglês). Se você deseja executar a última versão do MS-DEBUG a partir do MS-DOS 6.22 ou executar o programa DEBUG de 32-bits clone que é abaixo indicado, talvez seja necessário instalar o programa BOCHS, QEMU ou outro emulador como o VPC, VirtualBox, VMWare Player ou ainda outro tipo de programa de máquina virtual. Há o programa PCE que possui uma característica interessante: você pode executar com este programa no seu computador um código de compatível com a ROM-BIOS de um computador IBM-PC original como se estivesse utilizando a máquina física da época..
Há uns anos usamos um "clone" do MS-DEBUG desenvolvido para o sistema operacional FreeDOS que vem melhorando ao longo deste tempo. Você pode baixar e usar este programa de graça. Atualmente recomendamos uma página feita para ele em um sítio criado por Vernon C. Brooks, que tinha sido um programador sênior para o sistema operacional PC DOS 7.0 da IBM. O sítio em questão trata do histórico do IBM PC DOS, sendo este muito informativo (PC DOS Retro): Enhanced DEBUG (versão atual, desde dezembro de 2014, é 1.32b). Infelizmente, como o próprio DEBUG, este programa não funcionará em nenhum sistema operacional Windows de 64 bits; tentar fazer isso resultará nesta mensagem de erro:
C:\DEBUG> DEBUGX -? assemble A [endereço] compare C intervalo de endereços dump D[B|W|D] [intervalo] dump interrupt DI interrupção [contador] dump LDT DL seletor [contador] dump MCB chain DM dump ext memory DX [endereço_físico] enter E endereço [lista] fill F lista de intervalos go G [=endereço] [endereços] hex add/sub H valor1 valor2 input I[W|D] porta load file L [endereço] load sectors L [endereço] [unidade] [primeiro setor] [número] move M intervalo de endereços set x86 mode M [x] (x=0..6) set FPU mode MC [2|N] (2=287,N=não FPU) name N [[unidade:][caminho]nome do arquivo [lista de argumentos]] output O[W|D] byte da porta proceed P [=endereço] [número] proceed return PR quit Q register R [registrador [valor]] MMX register RM FPU register RN[R] toggle 386 regs RX search S lista de intervalos trace T [=endereço] [contador] trace mode TM [0|1] unassemble U [lista] write file W [endereço] write sectors W [endereço] [unidade] [primeiro setor] [número] prompts: '-' = real/modo-v86; '#' = modo-protegido - |
O DEBUG foi originalmente projetado para trabalhar com programas .COM com tamanho máximo de 65.280 bytes [ (64 x 1024) - 256 ] ou menos. Quanto menos, dependia do número máximo de bytes que o programa poderia colocar na Stack (pilha) ao mesmo tempo. A subtração de 256 bytes é necessária uma vez que o DEBUG geralmente usa a área do deslocamento 00 até FF hex para alguns dados internos como o nome do arquivo carregado. Lembre-se, de que os programas.COM por definição devem caber dentro de um único segmento de memória (somente 64 KB).
Mesmo quando executado o MS-DEBUG no sistema operacional Windows® mais recente por ser um antigo aplicativo DOS de 16 bits. Você só poderá abrir arquivos cujos nomes foram salvos na convenção DOS 8.3, ou seja, 11 caracteres no total usando 8 caracteres para o nome e 3 caracteres para a extensão.
Posterior ao DOS 1.10 o DEBUG foi capaz de carregar arquivos maiores que 64 KB. Basicamente o tamanho de um arquivo que o DEBUG pode usar com segurança sem erros depende da quantidade de memória disponível e da maneira como o sistema operacional gerencia a memória. Vamos ver mais sobre isso abaixo .
|
Lembre-se: Os segmentos atribuídos ao DEBUG dependem da quantidade de memória em uso e não da memória disponível no computador. A mesma máquina DOS que possui 16 ou 4096 MB de memória geralmente carrega o DEBUG nos mesmos segmentos, a menos que um programa 'termine e permaneça residente' ou quando a memória não é desabilitada antes de ser executado o DEBUG.
Qualquer versão do DEBUG do DOS 2.0 ou superior faz uso da função EXEC do sistema operacional, o que significa que é possível executar uma quantidade limitada de depuração em programas .EXE. No entanto, o DEBUG nunca pode ser usado para salvar um .EXE ou um arquivo .HEX em disco, uma vez que ambos os tipos de arquivo contém dados extras que o DEBUG não foi programado para acessar após a função EXEC remover da memória esses dados. É bem possível, porém, alterar a extensão de um arquivo .EXE, por exemplo, para .BIN, e então usar o DEBUG para editar esse arquivo e, em seguida, alterá-lo novamente para uma extensão .EXE. Normalmente, recomendamos usar um editor Hexadecimal. É propício salientar que o DEBUG pode ser usado com arquivos de lote e scripts para atuar sobre essas edições automaticamente.
Um dos programas .EXE mais simples que você pode usar com o DEBUG é o DOS "Stub" encontrado em muitos executáveis do Windows®. Para saber mais sobre este assunto acesse as informações aqui (somente em inglês).
Sempre haverá algum código e dados colocados nos primeiros 256 bytes do segmento para uso do próprio DEBUG. E, embora o DEBUG funcione geralmente como esperado se você desligar esta área poderá ocorrer alguns casos em que você desejaria não ter feito isto. Os bytes de código são simples e sempre são encontrados nos mesmos locais: os dois primeiros bytes desta área ("CD 20") são o código de máquina para a interrupção do DOS: INT 20. Os bytes de deslocamento 50h e 51h ("CD 21") formam um INT 21 e o byte "CB" no deslocamento 52h é uma instrução RETF.
|
Ao executar o DEBUG em uma janela DOS do Windows® (em CMD.exe) o despejo dos seus primeiros 256 bytes quase sempre mostrará o mesmo string fragmentado (mostrado abaixo em texto na cor branca). Os caracteres apresentados são os restos da execução do programa Ntvdm (que é iniciado assim que qualquer comando de 16 bits é executado) quando lida cada uma das linhas do arquivo AUTOEXEC.NT (localizado na pasta [diretório] C:\WINDOWS\system32), ou seja, a mesma área de memória onde os parâmetros da linha de comando são armazenados. A linha mais longa nesse arquivo, incluindo seu byte 0Dh (carriage return) é sucessivamente substituída por linhas mais curtas do arquivo até o processo resultar no que foi copiado para os offsets 82h por meio de CEh do segmento do DEBUG:
|
Obs: Se você renomear ou excluir AUTOEXEC.NT não poderá executar o DEBUG (nem qualquer outro programa de 16 bits, o qual deve ser executado em Ntvdm). No entanto, você pode salvar uma cópia do AUTOEXEC.NT para depois editá-lo e ver como suas alterações afetam o que foi copiado para o DEBUG. Você pode reduzir seu tamanho apenas para um único byte. No entanto, para ver qualquer coisa além de zero bytes nos offsets 82h e posterior, pelo menos um byte especial (20h) deve ser colocado entre um byte não-especial no início de uma linha e o que você deseja ver. Se o arquivo contiver apenas 3 bytes: "T", espaço e "S", 0s offsets 82h e 83h serão "S" seguidos de 0Dh.
Esta seção está "em desenvolvimento", mas se estiver vendo isso antes de seu término poderá imaginar do que se trata?
Embora quase todos os códigos utilizados pelos programadores funcionem como esperados, uma vez que eles eliminaram seus próprios erros de lógica, ocasionalmente, poderá acontecer o surgimento de resultados inesperados porque os programadores não foram a fundo o suficiente na leitura aprofundada dos manuais do processador usado em um PC. Programadores profissionais sempre testarão seus códigos de diversas maneiras de um ponto de vista razoável, mas é fundamental estudar os detalhes de programação do processador, especialmente as seções relacionadas a qualquer tarefa a ser executada, tendo este objetivo no topo de sua lista. OBS: Se você deseja ser um hacker melhor, o exemplo aqui mostrado pode fazer com que você mergulhe de cabeça nos detalhes técnicos do processor Intel e sobre como suas CPUs lidam com as diversas instruções que possui.
Você encontrou duas linhas distintas de instruções assembly que o DEBUG executa sem nunca parar na segunda linha? O exemplo seguinte é um dos muitos exemplos que podemos listar nesta situação. Abra qualquer instância do DEBUG (DOS ou Windows - qualquer versão), copie e cole o pequeno código seguinte por meio do comando E (Enter) a partir do prompt (-):
e 100 8C C8 8E D0 B0 74 90 90
Após entrar o código anterior execute "u 100 107" e observe o que é apresentado:
xxxx:0100 8CC8 MOV AX,CS <- Deixe o segimento CS na pilha.
xxxx:0102 8ED0 MOV SS,AX <- Uma instrução da tecla!
xxxx:0104 B074 MOV AL,73 <- Pode ser qualquer coisa.
xxxx:0106 90 NOP
xxxx:0107 90 NOP
Agora, execute o comando "r" e na sequência execute o comando (t). Assim que você entrar no comando t notará que o deslocamento usado fica definido de 0102h, até o deslocamento 0106h. Será este um "bug" nunca tratado? A instrução do offset (deslocamento) 0104h ff poderia ser qualquer dado de: 1-, 2-, 3- ou mesmo 4- bytes. Escolhemos propositadamente uma ação que afeta o conteúdo do registrador, neste caso (AL) para que você pudesse ver que essa instrução realmente foi executada pela CPU, sem que o usuário tenha a opção de fazê-lo.
Este efeito sempre será observado independentemente da versão do DEBUG nos sistemas operacionais MS-DOS 7.1, 5.0 ou qualquer versão anterior, mesmo no IBM PC DOS 1.0. Se você expandir sua pesquisa para outras ferramentas de depuração perceberá que cada versão de duas ou mais ferramentas apresentam o mesmo "erro": muita coincidência. Então, por que será que esse código afeta as habilidades de ação sobre a interrupção de certo depurador?
Se você ainda não obteve o conjunto de manuais de referência de instruções do processador Intel®. É melhor obtê-los. Procure pelas palavras chave: Intel, IA32, Software, Instruction. Pelo menos faça o download de uma cópia digital PDF do conjunto de referência dos manuais (Geralmente encontrados em dois arquivos separados: Volume 2A: Instruction Set Reference, A-M e Volume 2B: Instruction Set Reference, N-Z). Na cópia que eu obtive em janeiro de 2006 para "MOV—Move", foi encontrado: " Loading the SS register with a MOV instruction inhibits all interrupts until after the execution of the next instruction. (Carregar o registro SS com uma instrução MOV inibe todas as interrupções até a execução da próxima instrução). Esta operação permite que um ponteiro de pilha seja carregado no registrador ESP com a próxima instrução (MOV ESP, valor do ponteiro de pilha) antes da ocorrência de uma interrupção1." (IA-32 Intel® Architecture Software Developer’s Manual, Volume 2A: Instruction Set Reference, A-M, 253666-018, Jan 2006, "MOV—Move," páginas 3-584). A nota de rodapé 1 afirma claramente que: " If a code instruction breakpoint (for debug) is placed on an instruction located immediately after a MOV SS instruction, the breakpoint may not be triggered. [Se um ponto de interrupção de instruções de código (para depuração) for colocado em uma instrução localizada imediatamente após uma instrução de MOV SS , o ponto de interrupção pode não ser acionado]" (páginas 3-585). Para os novatos no uso de programas depuradores a operação no "ponto de interrupção da instrução" a que se refere não é um ponto de interrupção definido pelos usuário, mas sim, um ponto de interrupção definido automaticamente pelo próprio depurador. Então, de acordo com a documentação dos manuais, o que você julga ser um "bug" do DEBUG é de fato uma ação realizada pelo processador naquilo em que foi projetado para fazer.
Devido a isto acreditamos que o MS-DEBUG é completamente livre de "bugs"? Não. No futuro, publicaremos alguns exemplos de 'bugs' reais do programa DEBUG.
Antes de usar qualquer um dos comandos de depuração (Trace, Procedure) ou Register, você deve se familiarizar com as abreviaturas dos Registradores da CPU referenciados pelo programa DEBUG (Veja o Apêndice, Os registradores da CPU 8086 para maiores detalhes.)
Você também deve saber sobre o método de endereçamento SEGMENT:OFFSET usado pelo DEBUG (e por outros programas utilitários).
|
Uma nota sobre onde e como DEBUG é usado na memória de um computador. Usar o DEBUG em uma janela prompt do Windows® pela primeira pode facilmente confundir você. Se você abrir duas instâncias do DEBUG (uma por janela DOS) e examinar toda a memória que pode ser acessada, notará a existência de dados completamente diferentes em muitas das mesmas localizações de memória em ambas as janelas. A razão disso advém do fato de que cada aplicação sob o sistema operacional Windows™ é (teoricamente) executada de forma separada como se fosse um "computador virtual" de 4 Gigabytes para reproduzir uma cópia dos dados críticos dentro do primeiro Megabyte de memória da máquina feito em cada instância em execução do DEBUG. Somente abaixo do DOS de 16 bits o DEBUG realmente tem acesso aos locais reais de memória nos quais o próprio sistema operacional está sendo executado, tornando muito mais fácil travar todo o sistema se um erro ocorrer. No Windows® a teoria diz que tais erros devem travar apenas a janela do aplicativo CMD que causou o problema, mas não no computador inteiro. Pelo menos é assim que o Windows® deve operar. Por experiência, parece que o Windows™ 2000/XP faz um trabalho muito melhor para manter o controle de seus sistemas nas mesmas circunstâncias que muitas vezes terminaram em Blue Screen (famosa tela azul) como ocorre com versões anteriores. |
Recomendamos ler todo o Tutorial do DEBUG antes de usar esses links de comandos rápido.
Para obter ajuda sobre todos os comandos disponíveis dentro do DEBUG, basta inserir um ponto de interrogação (?) no prompt do DEBUG ao fazer uso do DOS 5.0 ou superior.
Clique em um dos comando a seguir para obter mais detalhes:
-?
assemble A [endereço]
compare C intervalo de endereço
dump D [intervalo]
enter E endereço [lista]
fill F lista de intervalos
go G [=endereço] [endereços]
hex H valor1 valor2
input I porta
load L [endereço] [unidade] [primeiro setor] [número]
move M intervalo de endereços
name N [caminho] [lista de argumentos]
output O byte da porta
proceed P [=endereço] [número]
quit Q
register R [registrador]
search S lista de intervalos
trace T [=endereço] [valor]
unassemble U [intervalo]
write W [endereço] [unidade] [primeiro setor] [número]
Atualizado: 9 de dezembro de 2007 (09/12/2007); 12 de fevereiro de 2009 (12/02/2009); 24 de agosto de 2009 (24/08/2009); 20 de abril de 2015 (20/04/2015).
Última atualização: 18 de fevereiro de 2017. (18/02/2017)