Saturday 5 August 2017

Gdb Print Format Binary Options


8.4 Formatos de saída Por padrão, o GDB imprime um valor de acordo com seu tipo de dados. Às vezes isso não é o que você quer. Por exemplo, você pode querer imprimir um número em hexadecimal, ou um ponteiro em decimal. Ou você pode querer exibir dados na memória em um determinado endereço como uma seqüência de caracteres ou como uma instrução. Para fazer essas coisas, especifique um formato de saída quando você imprime um valor. O uso mais simples de formatos de saída é dizer como imprimir um valor já calculado. Isso é feito iniciando os argumentos do comando de impressão com uma barra e uma letra de formato. As letras de formato suportadas são: x Considere os bits do valor como um inteiro e imprima o inteiro em hexadecimal. D Imprime como número inteiro em decimal assinado. U Imprimir como número inteiro em decimal não assinado. O Imprimir como um número inteiro em octal. T Imprimir como um inteiro no binário. A letra t significa dois. (2) a Imprimir como um endereço, tanto absoluto em hexadecimal quanto como um deslocamento do símbolo precedente mais próximo. Você pode usar este formato usado para descobrir onde (em qual função) um endereço desconhecido está localizado: O símbolo de informação de comando 0x54320 produz resultados semelhantes. Veja o símbolo da informação da seção. C Considere como um número inteiro e imprima-o como uma constante de caractere. F Considere os bits do valor como um número de ponto flutuante e imprima usando a sintaxe típica de ponto flutuante. Por exemplo, para imprimir o contador de programas em hexadecimal (consulte a seção 8.10 Registros), digite Note que nenhum espaço é necessário antes da barra porque os nomes de comandos no GDB não podem conter uma barra. Para reimprimir o último valor no histórico de valores com um formato diferente, você pode usar o comando print com apenas um formato e nenhuma expressão. Compile com a opção - g (para a maioria dos compiladores GNU e Intel), que gera informações adicionadas no código do objeto para que o depurador possa corresponder a uma linha de código-fonte (por exemplo, p / x reimprime o último valor em hex. GNU) Com o passo de execução. Não use a diretiva de otimização do compilador, como - O ou - O2, que reorganizam as operações de computação para ganhar velocidade, já que este reordenamento não corresponderá à ordem de execução no código-fonte e pode ser impossível segui-lo. Controlc: Parar a execução. Pode parar o programa em qualquer lugar, em sua fonte ou em uma biblioteca de C ou em qualquer lugar. Para executar um comando do shell: comando ou comando do shell Comando do GDB: Use a tecla TAB info bre TAB completará o comando resultando em pontos de interrupção de informações Pressione TAB duas vezes para ver todas as opções disponíveis se houver mais de uma opção disponível ou digite M-RETURN. De-Referencing STL Containers: A exibição de classes de contêineres STL usando o nome da variável p do GDB resulta em uma exibição enigmática de definições de modelo e ponteiros. Abreviatura do comando GDB: info bre RETURN funcionará como bre é uma abreviação válida para pontos de interrupção. Use o seguinte /. Arquivo gdbinit (V1.03 09/15/08). Agora funciona com o GDB 4.3. (Versões arquivadas: V1.01 GDB 6.4 somente) Agradecimentos ao Dr. Eng. Dan C. Marinescu para permissão para publicar este script. Use os seguintes comandos fornecidos pelo script: Eu tenho GDB, mas o binário eu quero engenheiro reverso dinamicamente não tem símbolos, que é quando eu executar o utilitário de arquivo que me mostra despojado: Que opções eu tenho se o ambiente em que este executa doesnt Permitir que uma instância IDA Pro remota se conecte ao gdbserver. Em suma: o ambiente que você tem é limitado no que ele permite que você faça, mas você tem trustd old gdb e um binário para engenharia reversa. 27 de abril de 13 às 3:13 Convenções usadas mais observações preliminares Eu estou cortando a saída de GDB para a brevidade desde que mostra geralmente os direitos reservados e a outra informação no início de toda a sessão. Quando eu reproduzir a saída Ill iniciar na primeira linha de prompt (gdb), ou no caso ou comandos auto-executados da primeira linha de saída genuína. Para distinguir comandos inseridos no prompt do GDB, estes terão um líder (gdb) como no mundo real. Para o comando shell isso não será nenhum prefixo ou como ele parece ser a convenção na maioria dos sistemas unixóides. Quando eu uso um comando específico, como vim como meu editor, você é livre para usar o seu editor favorito, é claro. Seja ele emacs ou nano. Eu não vou julgá-lo) Primeiros passos Esta seção trata de configurar seu ambiente gdb e iniciar o processo. Ill também incluem alguns tidbits para os recém-chegados completa. Truques que você deve saber GDB tem um prompt agradável em que o cursor irá parar após o programa quebras ou sempre que você está pisando ou alguns tal. Pressionar RETURN (aka ENTER) depois de executar um comando GDB executará o mesmo comando novamente. Isso é útil quando você está passando por código com etapa ou próximo e simplesmente deseja continuar um por um. Os comandos podem ser abreviados desde que não sejam ambíguos. Para alguns comandos usados, existe uma abreviação particular que tem precedência apesar da ambigüidade: b para quebrar (apesar de bt e backtrace) c ou cont para continuar (apesar da chamada catch e assim por diante) n para o próximo (apesar ni e nexti) Você pode chamar Funções de biblioteca reais ou mesmo funções de dentro do programa depurado usando a chamada de comando. Isso significa que você pode experimentar o comportamento ou forçar o comportamento. Você pode iniciar o GDB com gdbtui ou gdb - tui para obter um - supostamente mais conveniente - mais visual interface de usuário de texto. Ele mostra o código fonte na parte superior eo prompt (gdb) abaixo. Você também pode alternar para esse layout executando o layout de comando src no prompt (gdb). O GDB tem um recurso de conclusão de linha de comando muito parecido com muitos shells, então use o Tab para sua vantagem e também certifique-se de usar a ajuda ou o keywordcommand de ajuda sempre que precisar de ajuda. Shell permite que você execute comandos no shell, para que você possa executar comandos de dentro de sua sessão do GDB. Durante o desenvolvimento um exemplo seria shell make. impressão. Examinar e exibir vários formatos (/ FMT) que você pode usar para tornar a saída mais legível. Quando a depuração em nível de origem você pode usar moldes de tipo C para exibir valores. Imagine uma string C atrás de um vazio (que GDB sabe graças aos símbolos em tal caso). Basta converter em (char) e imprimi-lo: print (char). Como o processo é executado Como queremos analisar dinamicamente o binário, precisamos iniciá-lo primeiro. Linha de comando Podemos fazer isso diretamente da linha de comando, passando não apenas o caminho para o binário, mas também os argumentos com os quais queremos iniciá-lo. Todo o processo então se parece com isto: Fácil o suficiente. A partir do prompt (gdb), você pode emitir o comando run (abreviação r) para executar ./exe com os parâmetros fornecidos na linha de comando. Eu prefiro este método, mas sua milhagem pode variar. GDB prompt Fire up GDB e no prompt (gdb) use o comando file para carregar o binário e então use o comando run para iniciá-lo com os argumentos que você quer passar: uma alternativa para o acima seria o uso de set args like Isso: Você também pode ver, em qualquer caso, quais argumentos serão passados ​​para o processo iniciado, emitindo um: btw: se você estivesse se perguntando sobre variáveis ​​de ambiente, use o comando de ajuda incorporado do GDB como conjunto de ajuda e ajuda a mostrar. Ponteiros: definir ambiente VARNAMEVALUE e mostrar ambiente VARNAME e unset ambiente VARNAME. Phew, mas por que o programa pára com um SIGSEGV (falha de segmento) Bem, nós não sabemos ainda, mas parece que este pouco beasty quer o tratamento adequado. Desde que nós praticamos a computação defensiva, nós não queremos executar qualquer coisa que não sabemos muito sobre, direito Então vamos começar de novo. Se isso teria sido malware wed tem que lavar a máquina e reinstalar ou restaurar um instantâneo se é um hóspede VM. Primeiro, queremos executar o comando info da seguinte forma: Existem duas informações importantes, a mais relevante para nós é a linha indicando: tudo bem, então podemos definir um ponto de interrupção sobre aquele e então executar o processo com os argumentos que nós chique..gdbinit para a vitória Mas espere, isto está começando tedious já. Nenhum método fácil de automatizar essas etapas de alguma forma Como uma questão de fato não é. Um arquivo chamado. gdbinit pode ser usado para emitir comandos para o GDB durante a inicialização. Você também pode passar um arquivo com comandos do GDB usando o argumento - x na linha de comando (shell). Se eu tiver um número de projetos, geralmente eles estão em subpastas com um arquivo. gdbinit cada. Nota-lateral: - nx impede que o conteúdo. gdbinit seja executado durante a inicialização. Portanto, sabemos quais os argumentos que queremos passar e sabemos o endereço do ponto de interrupção, isso traduz o seguinte arquivo. gdbinit: A saída que recebo quando começo o gdb sem outros argumentos é: Nice Mas isso parece diferente. Assembly e GDB Então você está acostumado a ver a próxima linha que você está indo para executar e, em seguida, seu fiel velho (gdb) prompt. Mas nada disso. Não temos fonte para este binário e, além disso, símbolos. Doh Então, nós contemplamos o sinal intermitente no prompt (gdb) e nos perguntamos o que fazer. Não se preocupe, GDB também pode lidar com o código de montagem. Único problema, o padrão é - na minha opinião - inconveniente ATAMPT assembly sintaxe. Eu prefiro o sabor da Intel eo seguinte comando diz ao GDB para fazer exatamente isso: Mostrar o código de montagem E como ele vai nos mostrar o código de montagem Bem, semelhante ao modo TUI (verifique a tag wiki para gdb) usando o seguinte Comando: e se você estiver tão inclinado, também: que também irá mostrar o conteúdo dos registros em uma visão geral. Vamos executá-lo novamente Então nós acabamos com o seguinte. Gdbinit para os nossos propósitos: E quando começamos gdb sem argumentos acabamos com isso: Doce. Assim, podemos ver a desmontagem enquanto passamos pelo código. Poderíamos concluir isso aqui, mas é claro que há mais truques a serem aprendidos, então por que não ir um pouco mais longe. NOTA: os registos com fundo branco / cinzento mostram que um valor foi alterado. Não muito significativo quando acabamos de iniciar o programa, mas poderoso útil ao pisar através de código mais tarde. Btw, se você preferir salvar a propriedade de tela e tê-lo menos visual, começando com GDB 7.0 você pode usar: em versões GDB antes que você pode emular o comportamento por configurações um display automático: ou mais curto disp / i pc onde / i é o Formato, você pode recordá-lo melhor por pensamento instrução e pc sendo o ponteiro de instrução, também conhecido como contador de programa - daí PC. Também é bom saber Às vezes, ao pisar através da montagem, as vistas regs e asm serão obtidas. Basta executar os respectivos comandos de layout novamente para restaurá-los à sua antiga glória: Depuração no nível de montagem Acontece quando você está no modo de montagem alguns dos comandos que você está acostumado a partir de depuração a nível de fonte simplesmente não vai funcionar. Isso faz sentido, porque uma única linha de origem significa normalmente uma dúzia de instruções ou mais. O próximo e os comandos de passo, no entanto, têm contrapartes de nível de instrução: nexti (estenografia ni qualquer outra pessoa pensando em arbustos) stepi (ta de taquímetro) De nossa desmontagem acima sabemos: e para todos os efeitos práticos esta é a função principal. Claro que se você fosse para engenharia reversa de malware você deve ter mais cuidado, mas neste caso é. Então vamos adicionar um ponto de interrupção a este endereço (0x40f961) em vez do ponto de entrada: Se examinarmos (abreviação x) o código no qual estamos atualmente, podemos ver: Ok, a chamada é o que queremos seguir, então vamos passo Dentro dele usando si. Podemos ver outra chamada imediatamente no ponteiro de instrução ao inserir a função: A chamada nos leva a uma função que chama ptrace (PTRACETRACEME.). Agora, por que faria isso? Bem, é um velho truque anti-depurador que Mellowcandle descreveu em outro QampA aqui: Mas como podemos contorná-lo? Tem que sobrescrever a chamada para a função que chama ptrace () com nop ou algo assim Essas linhas. Este é o lugar onde GDB se torna um pouco pesado. Mas podemos usar o conjunto de modo a fazer a magia para nós. Deixa primeiro inspecionar os bytes da instrução: O 0xe8 é uma instrução da chamada e nós sabemos agora que é 5 bytes por muito tempo. Então, vamos nop isso. (X / 10b pc significa examinar 10 bytes no contador do programa - o formato padrão é hex já). Então fazemos enquanto parado em 0x40911f: e verifique o local corrigido: Excelente. Agora podemos executá-lo. Alternativas para o método dado alternativa para patching: conjunto 0x40911f 0x90909090 seguido pelo conjunto 0x409123 0x90 Manipular o contador de programa (ponteiro de instrução) em vez disso: conjunto pc5 ou o conjunto mais explícito pcpc5 salto pc5 Melhores maneiras ainda de manipular / patch o programa em execução Existem alternativas (E forma superior) métodos como este por Tavis Ormandy. Eu estou reproduzindo o macro de montagem abaixo (no caso de ele ficar offline do outro lugar): Novamente o trecho de script acima não foi escrito por mim, mas por Tavis Ormandy - veja o link acima. Isso conclui este pequeno QampA.8. Examinando Dados A maneira usual de examinar dados em seu programa é com o comando de impressão (abreviado p), ou seu sinônimo inspecionar. Ele avalia e imprime o valor de uma expressão do idioma no qual o programa está escrito (consulte a seção Usando o GDB com diferentes idiomas). Print expr print / f expr expr é uma expressão (no idioma de origem). Por padrão, o valor de expr é impresso em um formato apropriado para seu tipo de dados, você pode escolher um formato diferente especificando / f. Onde f é uma letra especificando o formato veja Formatos de saída. Print print / f Se você omitir expr. O GDB exibe o último valor novamente (a partir do histórico de valores, consulte a seção Histórico de valores). Isso permite que você inspecione convenientemente o mesmo valor em um formato alternativo. Uma maneira mais baixa de examinar os dados é com o comando x. Examina dados na memória em um endereço especificado e imprime-o em um formato especificado. Consulte a seção Examinando a memória. Se você estiver interessado em informações sobre tipos, ou sobre como os campos de uma estrutura ou uma classe são declarados, use o comando ptype exp em vez de imprimir. Consulte a seção Examinando a Tabela de Símbolos. 8.1 Expressões imprimir e muitos outros comandos GDB aceitar uma expressão e calcular seu valor. Qualquer tipo de constante, variável ou operador definido pela linguagem de programação que você está usando é válido em uma expressão no GDB. Isso inclui expressões condicionais, chamadas de função, moldes e constantes de string. Infelizmente não inclui símbolos definidos por preprocessor definir comandos. O GDB suporta constantes de matriz em expressões inseridas pelo usuário. A sintaxe é. . Por exemplo, você pode usar o comando print para criar uma matriz na memória que é malloc ed no programa de destino. Como C é tão difundido, a maioria das expressões mostradas nos exemplos neste manual estão em C. Consulte a seção Uso do GDB com diferentes idiomas. Para obter informações sobre como usar expressões em outros idiomas. Nesta seção, discutimos os operadores que você pode usar em expressões GDB, independentemente da linguagem de programação. Casts são suportados em todas as linguagens, não apenas em C, porque é tão útil para lançar um número em um ponteiro, a fim de examinar uma estrutura nesse endereço na memória. O GDB suporta esses operadores, além dos comuns às linguagens de programação: é um operador binário para tratar partes da memória como matrizes. Consulte a seção Arrays artificiais. Para maiores informações. :: permite que você especifique uma variável em termos do arquivo ou função onde ele é definido. Consulte a seção Variáveis ​​de programa. Addr Refere-se a um objeto de tipo tipo armazenado no endereço addr na memória. Addr pode ser qualquer expressão cujo valor é um inteiro ou ponteiro (mas os parênteses são necessários em torno de operadores binários, assim como em um elenco). Essa construção é permitida, independentemente do tipo de dados normalmente deve residir no addr. 8.2 Variáveis ​​de programa O tipo mais comum de expressão a ser utilizado é o nome de uma variável no seu programa. As variáveis ​​nas expressões são entendidas no quadro de pilha selecionado (ver seção Selecionando um quadro) elas devem ser: globais (ou arquivos estáticos) visíveis de acordo com as regras de escopo da linguagem de programação a partir do ponto de execução nesse quadro Isso significa que Na função você pode examinar e usar a variável a sempre que seu programa está executando dentro da função foo. Mas você só pode usar ou examinar a variável b enquanto seu programa está sendo executado dentro do bloco onde b é declarado. Há uma exceção: você pode se referir a uma variável ou função cujo escopo é um único arquivo de origem mesmo se o ponto de execução atual não estiver neste arquivo. Mas é possível ter mais de uma variável ou função com o mesmo nome (em diferentes arquivos de origem). Se isso acontecer, referindo-se a esse nome tem efeitos imprevisíveis. Se desejar, você pode especificar uma variável estática em uma função ou arquivo específico, usando a notação de dois pontos: Aqui o arquivo ou função é o nome do contexto para a variável estática. No caso de nomes de arquivos, você pode usar aspas para garantir que o GDB analise o nome do arquivo como uma única palavra - por exemplo, para imprimir um valor global de x definido em f2.c. Esta utilização de :: é muito raramente em conflito com o uso muito semelhante da mesma notação em C. O GDB também suporta o uso do operador de resolução de escopo C em expressões GDB. Aviso: Ocasionalmente, uma variável local pode parecer ter o valor errado em determinados pontos de uma função - logo após a entrada em um novo escopo, e logo antes de sair. Você pode ver esse problema quando você está pisando por instruções da máquina. Isso ocorre porque, na maioria das máquinas, é necessário mais de uma instrução para configurar uma estrutura de pilha (incluindo definições de variáveis ​​locais) se você estiver pisando por instruções da máquina, as variáveis ​​podem parecer ter valores errados até que a estrutura da pilha esteja completamente construída. Na saída, geralmente também leva mais de uma instrução de máquina para destruir uma moldura de pilha depois de começar a passar por esse grupo de instruções, as definições de variáveis ​​locais podem ter desaparecido. Isso também pode acontecer quando o compilador faz otimizações significativas. Para ter certeza de sempre ver valores precisos, desative todas as otimizações durante a compilação. Outro possível efeito das otimizações do compilador é otimizar as variáveis ​​não utilizadas fora da existência ou atribuir variáveis ​​aos registradores (em oposição aos endereços de memória). Dependendo do suporte para esses casos oferecidos pelo formato de informação de depuração usado pelo compilador, o GDB pode não ser capaz de exibir valores para essas variáveis ​​locais. Se isso acontecer, o GDB imprimirá uma mensagem como esta: Para resolver esses problemas, recompile sem otimizações, ou use um formato de informação de depuração diferente, se o compilador suportar vários desses formatos. Por exemplo, o GCC, o compilador GNU C / C normalmente suporta a opção - gstabs. - gstabs produz informações de depuração em um formato que é superior a formatos como COFF. Você pode ser capaz de usar DWARF2 (-gdwarf-2), que também é um formulário eficaz para informações de depuração. Consulte a seção Opções para depuração do seu programa ou GNU CC no uso do GNU CC. Para maiores informações. O operando esquerdo de deve residir na memória. Os valores de matriz feitos com desta forma se comportam como outros arrays em termos de subscritos e são coagidos a ponteiros quando usados ​​em expressões. Os arrays artificiais aparecem mais frequentemente em expressões através do histórico de valores (consulte a seção Histórico de valores), após a impressão de um. Outra maneira de criar uma matriz artificial é usar um elenco. Isso re-interpreta um valor como se fosse uma matriz. O valor não precisa estar na memória: Como uma conveniência, se você deixar o comprimento da matriz fora (como no (tipo) valor) GDB calcula o tamanho para preencher o valor (como sizeof (valor) / sizeof (tipo). O mecanismo de matriz não é suficiente em estruturas de dados moderadamente complexas, os elementos de interesse podem não ser realmente adjacentes - por exemplo, se você estiver interessado nos valores de ponteiros em uma matriz. Um trabalho útil nessa situação é usar Uma variável de conveniência como um contador em uma expressão que imprime o primeiro valor interessante e, em seguida, repita essa expressão via RET. Por exemplo, suponha que você tenha uma matriz dtab de ponteiros para estruturas e você está interessado no Valores de um campo fv em cada estrutura. Este é um exemplo do que você pode digitar: 8.4 Formatos de saída Por padrão, o GDB imprime um valor de acordo com seu tipo de dados. Às vezes isso não é o que você quer. Imprimir um número em hexadecimal, ou um ponteiro em decimal. Ou você pode querer exibir dados na memória em um determinado endereço como uma seqüência de caracteres ou como uma instrução. Para fazer essas coisas, especifique um formato de saída quando você imprime um valor. O uso mais simples de formatos de saída é dizer como imprimir um valor já calculado. Isso é feito iniciando os argumentos do comando de impressão com uma barra e uma letra de formato. As letras de formato suportadas são: x Considere os bits do valor como um inteiro e imprima o inteiro em hexadecimal. D Imprime como número inteiro em decimal assinado. U Imprimir como número inteiro em decimal não assinado. O Imprimir como um número inteiro em octal. T Imprimir como um inteiro no binário. A letra t significa dois. (2) a Imprimir como um endereço, tanto absoluto em hexadecimal quanto como um deslocamento do símbolo precedente mais próximo. Você pode usar este formato usado para descobrir onde (em qual função) está localizado um endereço desconhecido: O símbolo de informação de comando 0x54320 produz resultados semelhantes. Veja o símbolo da informação da seção. C Considere como um número inteiro e imprima-o como uma constante de caractere. F Considere os bits do valor como um número de ponto flutuante e imprima usando a sintaxe típica de ponto flutuante. Por exemplo, para imprimir o contador de programas em hexadecimal (consulte a seção 8.10 Registros), digite Note que nenhum espaço é necessário antes da barra porque os nomes de comandos no GDB não podem conter uma barra. Para reimprimir o último valor no histórico de valores com um formato diferente, você pode usar o comando print com apenas um formato e nenhuma expressão. Por exemplo, p / x reimprime o último valor em hexadecimal. 8.5 Examinando a memória Você pode usar o comando x (para examinar) para examinar a memória em qualquer um dos vários formatos, independentemente dos tipos de dados de seus programas. X / nfu addr x addr x Use o comando x para examinar a memória. N. F. E u são todos os parâmetros opcionais que especificam a quantidade de memória a ser exibida e como formatá-la. Addr é uma expressão que dá o endereço onde você deseja iniciar a exibição de memória. Se você usar padrões para nfu. Você não precisa digitar a barra /. Vários comandos definem padrões convenientes para addr. N. A contagem de repetição A contagem de repetição é um inteiro decimal o padrão é 1. Ele especifica a quantidade de memória (contagem por unidades u) para exibir. F. O formato de exibição O formato de exibição é um dos formatos usados ​​pela impressão. S (string com terminação nula) ou i (instrução de máquina). O padrão é x (hexadecimal) inicialmente. O padrão é alterado sempre que você usa x ou print. você. O tamanho da unidade O tamanho da unidade é qualquer um de b Bytes. H Meias palavras (dois bytes). W Palavras (quatro bytes). Este é o padrão inicial. G Palavras gigantes (oito bytes). Cada vez que você especificar um tamanho de unidade com x. Esse tamanho torna-se a unidade padrão na próxima vez que você usa x. (Para os formatos s e i, o tamanho da unidade é ignorado e normalmente não é escrito.) Addr. Endereço de exibição inicial addr é o endereço onde você deseja que o GDB comece a exibir a memória. A expressão não precisa ter um valor de ponteiro (embora possa) é sempre interpretada como um endereço inteiro de um byte de memória. Consulte a seção Expressões. Para obter mais informações sobre expressões. O padrão para addr geralmente é apenas após o último endereço examinado - mas vários outros comandos também definem o endereço padrão: info breakpoints (para o endereço do último ponto de interrupção listado), linha de informação (para o endereço inicial de uma linha) e Imprimir (se você usá-lo para exibir um valor da memória). Por exemplo, x / 3uh 0x54320 é uma solicitação para exibir três halfwords (h) de memória, formatado como inteiros decimais não assinados (u), começando no endereço 0x54320. X / 4xw sp imprime as quatro palavras (w) da memória acima do ponteiro da pilha (aqui, sp ver seção Registros) em hexadecimal (x). Uma vez que as letras que indicam tamanhos de unidades são todas distintas das letras que especificam formatos de saída, você não precisa se lembrar se o tamanho da unidade ou o formato vem primeiro ou a ordem funciona. As especificações de saída 4xw e 4wx significam exatamente a mesma coisa. (No entanto, a contagem n deve vir primeiro wx4 não funciona.) Mesmo que o tamanho da unidade u é ignorado para os formatos s e i. Você ainda pode querer usar uma contagem n, por exemplo, 3i especifica que você deseja ver três instruções de máquina, incluindo quaisquer operandos. O comando desmontar fornece uma forma alternativa de inspecionar as instruções da máquina, veja Fonte e código da máquina. Todos os padrões para os argumentos para x são projetados para tornar mais fácil para continuar digitalização memória com especificações mínimas cada vez que você usar x. Por exemplo, depois de ter inspecionado três instruções de máquina com x / 3i addr. Você pode inspecionar os próximos sete com apenas x / 7. Se você usar RET para repetir o comando x, a contagem de repetição n é usada novamente os outros argumentos padrão como para usos sucessivos de x. Os endereços e conteúdos impressos pelo comando x não são guardados no histórico de valores porque muitas vezes há demasiados deles e eles ficariam no caminho. Em vez disso, o GDB torna esses valores disponíveis para uso posterior em expressões como valores das variáveis ​​de conveniência e. Após um comando x, o último endereço examinado está disponível para uso em expressões na variável de conveniência. O conteúdo desse endereço, conforme examinado, está disponível na variável conveniência. Se o comando x tem uma contagem de repetição, o endereço eo conteúdo salvos são da última unidade de memória impressa, isso não é o mesmo que o último endereço impresso se várias unidades foram impressas na última linha de saída. 8.6 Exibição automática Se você achar que deseja imprimir o valor de uma expressão com freqüência (para ver como ela muda), talvez queira adicioná-la à lista de exibição automática para que o GDB imprima seu valor sempre que o programa parar. Cada expressão adicionada à lista recebe um número para identificá-lo para remover uma expressão da lista, você especifica esse número. O display automático tem a seguinte aparência: Este display exibe números de item, expressões e seus valores atuais. Tal como acontece com os displays que você solicitar manualmente usando x ou imprimir. Você pode especificar o formato de saída que você prefere de fato, a tela decide se deseja usar a impressão ou x dependendo de quão elaborada é sua especificação de formato - usa x se você especificar um tamanho de unidade ou um dos dois formatos (i e s) Que são suportados somente por x caso contrário ele usa a impressão. Display expr Adiciona a expressão expr à lista de expressões a serem exibidas sempre que o programa pára. Consulte a seção Expressões. O ecrã não é repetido se premir RET novamente depois de o utilizar. Display / fmt expr Para fmt especificando apenas um formato de exibição e não um tamanho ou contagem, adicione a expressão expr à lista de exibição automática, mas organize para exibi-la cada vez no formato especificado fmt. Consulte a seção Formatos de saída. Display / fmt addr Para fmt i ou s. Ou incluindo um tamanho de unidade ou um número de unidades, adicione a expressão addr como um endereço de memória a ser examinado cada vez que seu programa pára. Examinar significa, de fato, fazer x / fmt addr. Consulte a seção Examinando a memória. Por exemplo, display / i pc pode ser útil, para ver a instrução da máquina a ser executada cada vez que a execução pára (pc é um nome comum para o contador do programa veja a seção Registros). Undisplay dnums. Excluir dnums de exibição. Remova os números de item dnums da lista de expressões a serem exibidas. A indicação não é repetida se você pressionar RET depois de usá-la. (Caso contrário, você só iria obter o erro Sem número de exibição.) Desativar exibir dnums. Desativar a exibição de números de item dnums. Um item de exibição desabilitado não é impresso automaticamente, mas não é esquecido. Pode ser ativado novamente mais tarde. Habilitar dnums de exibição. Ativar exibição de números de item dnums. Torna-se eficaz novamente na exibição automática de sua expressão, até que você especifique o contrário. Display Exibe os valores atuais das expressões na lista, tal como é feito quando seu programa pára. Info display Imprime a lista de expressões previamente configuradas para exibir automaticamente, cada uma com seu número de item, mas sem mostrar os valores. Isso inclui expressões desativadas, que são marcadas como tal. Ele também inclui expressões que não seriam exibidas agora porque elas se referem a variáveis ​​automáticas não disponíveis no momento. Se uma expressão de exibição se refere a variáveis ​​locais, então não faz sentido fora do contexto lexical para o qual foi configurado. Essa expressão é desativada quando a execução entra em um contexto em que uma de suas variáveis ​​não está definida. Por exemplo, se você der ao comando display lastchar enquanto estiver dentro de uma função com um argumento lastchar. O GDB exibe esse argumento enquanto seu programa continua a parar dentro dessa função. Quando ele pára em outro lugar - onde não há nenhuma variável lastchar --- o display é desativado automaticamente. A próxima vez que o programa parar quando lastchar for significativo, você pode ativar a expressão de exibição mais uma vez. Você pode usar o endereço de impressão set off para eliminar todas as telas dependentes da máquina a partir da interface GDB. Por exemplo, com o endereço de impressão desligado. Você deve obter o mesmo texto para backtraces em todas as máquinas - ou não eles envolvem argumentos ponteiro. Show print address Mostra se os endereços devem ou não ser impressos. Quando o GDB imprime um endereço simbólico, normalmente imprime o símbolo mais próximo mais um offset. Se esse símbolo não identificar exclusivamente o endereço (por exemplo, é um nome cujo escopo é um arquivo de origem único), talvez seja necessário esclarecer. Uma maneira de fazer isso é com a linha de informações. Por exemplo linha de informação 0x4537. Como alternativa, você pode configurar o GDB para imprimir o arquivo de origem eo número da linha quando ele imprime um endereço simbólico: set print symbol-filename em Tell GDB para imprimir o nome do arquivo de origem eo número de linha de um símbolo na forma simbólica de um endereço. Set print symbol-filename off Não imprimir o nome do arquivo de origem eo número de linha de um símbolo. Esse é o padrão. Show print symbol-filename Mostra se o GDB imprimirá ou não o nome do arquivo de origem eo número da linha de um símbolo na forma simbólica de um endereço. Outra situação em que é útil mostrar nomes de arquivos de símbolos e números de linha é quando o código de desmontagem GDB mostra o número da linha eo arquivo de origem que corresponde a cada instrução. Além disso, você pode querer ver o formulário simbólico somente se o endereço que está sendo impresso é razoavelmente próximo ao símbolo mais próximo mais próximo: set print max-symbolic-offset max-offset Diga ao GDB para exibir apenas a forma simbólica de um endereço se o deslocamento entre O símbolo mais próximo mais cedo eo endereço é menor que o máximo de deslocamento. O padrão é 0, o que indica ao GDB que imprima sempre a forma simbólica de um endereço, se algum símbolo o preceder. Show print max-symbolic-offset Pergunte como é grande o deslocamento máximo que o GDB imprime em um endereço simbólico. Se você tiver um ponteiro e não tiver certeza de onde ele aponta, tente definir o símbolo de impressão-nome de arquivo. Em seguida, você pode determinar o nome ea localização do arquivo de origem da variável onde ele aponta, usando o ponteiro p / a. Isso interpreta o endereço em forma simbólica. Por exemplo, aqui o GDB mostra que uma variável ptt aponta para outra variável t. Definido em hi2.c. Aviso: Para ponteiros que apontam para uma variável local, p / a não mostra o nome do símbolo eo nome do arquivo do referente, mesmo com as opções de impressão de conjunto apropriadas ativadas. Outras configurações controlam como diferentes tipos de objetos são impressos: set print array set print array em Pretty arrays de impressão. Este formato é mais conveniente de ler, mas usa mais espaço. O padrão é off. Set print array off Retorna ao formato compactado para arrays. Show print array Exibe se o formato compactado ou bonito é selecionado para exibir matrizes. Set print elements number-of-elements Define um limite de quantos elementos de uma matriz o GDB imprimirá. Se o GDB estiver imprimindo um array grande, ele pára a impressão depois de ter impresso o número de elementos definidos pelo comando set print elements. Este limite também se aplica à exibição de strings. Quando o GDB é iniciado, esse limite é definido como 200. Ajustar o número de elementos para zero significa que a impressão é ilimitada. Mostrar elementos de impressão Exibe o número de elementos de um array grande que o GDB imprimirá. Se o número for 0, a impressão é ilimitada. Set print null-stop Causa o GDB parar de imprimir os caracteres de uma matriz quando o primeiro NULL for encontrado. Isso é útil quando grandes matrizes realmente contêm somente seqüências de caracteres curtas. O padrão é off. set print pretty on Cause GDB to print structures in an indented format with one member per line, like this: set print pretty off Cause GDB to print structures in a compact format, like this: This is the default format. show print pretty Show which format GDB is using to print structures. set print sevenbit-strings on Print using only seven-bit characters if this option is set, GDB displays any eight-bit characters (in strings or character values) using the notation nnn. This setting is best if you are working in English (ASCII) and you use the high-order bit of characters as a marker or meta bit. set print sevenbit-strings off Print full eight-bit characters. This allows the use of more international character sets, and is the default. show print sevenbit-strings Show whether or not GDB is printing only seven-bit characters. set print union on Tell GDB to print unions which are contained in structures. This is the default setting. set print union off Tell GDB not to print unions which are contained in structures. show print union Ask GDB whether or not it will print unions which are contained in structures. For example, given the declarations These settings are of interest when debugging C programs: set print demangle set print demangle on Print C names in their source form rather than in the encoded (mangled) form passed to the assembler and linker for type-safe linkage. The default is on. show print demangle Show whether C names are printed in mangled or demangled form. set print asm-demangle set print asm-demangle on Print C names in their source form rather than their mangled form, even in assembler code printouts such as instruction disassemblies. The default is off. show print asm-demangle Show whether C names in assembly listings are printed in mangled or demangled form. set demangle-style style Choose among several encoding schemes used by different compilers to represent C names. The choices for style are currently: auto Allow GDB to choose a decoding style by inspecting your program. gnu Decode based on the GNU C compiler ( g ) encoding algorithm. Esse é o padrão. hp Decode based on the HP ANSI C ( aCC ) encoding algorithm. lucid Decode based on the Lucid C compiler ( lcc ) encoding algorithm. arm Decode using the algorithm in the C Annotated Reference Manual. Warning: this setting alone is not sufficient to allow debugging cfront - generated executables. GDB would require further enhancement to permit that. If you omit style. you will see a list of possible formats. show demangle-style Display the encoding style currently in use for decoding C symbols. set print object set print object on When displaying a pointer to an object, identify the actual (derived) type of the object rather than the declared type, using the virtual function table. set print object off Display only the declared type of objects, without reference to the virtual function table. This is the default setting. show print object Show whether actual, or declared, object types are displayed. set print static-members set print static-members on Print static members when displaying a C object. The default is on. set print static-members off Do not print static members when displaying a C object. show print static-members Show whether C static members are printed, or not. set print vtbl set print vtbl on Pretty print C virtual function tables. The default is off. (The vtbl commands do not work on programs compiled with the HP ANSI C compiler ( aCC ).) set print vtbl off Do not pretty print C virtual function tables. show print vtbl Show whether C virtual function tables are pretty printed, or not. 8.9 Convenience variables GDB provides convenience variables that you can use within GDB to hold on to a value and refer to it later. These variables exist entirely within GDB they are not part of your program, and setting a convenience variable has no direct effect on further execution of your program. That is why you can use them freely. Convenience variables are prefixed with . Any name preceded by can be used for a convenience variable, unless it is one of the predefined machine-specific register names (see section Registers ). (Value history references, in contrast, are numbers preceded by . See section Value history .) You can save a value in a convenience variable with an assignment expression, just as you would set a variable in your program. For example: would save in foo the value contained in the object pointed to by objectptr. Using a convenience variable for the first time creates it, but its value is void until you assign a new value. You can alter the value with another assignment at any time. Convenience variables have no fixed types. You can assign a convenience variable any type of value, including structures and arrays, even if that variable already has a value of a different type. The convenience variable, when used as an expression, has the type of its current value. show convenience Print a list of convenience variables used so far, and their values. Abbreviated show conv. One of the ways to use a convenience variable is as a counter to be incremented or a pointer to be advanced. For example, to print a field from successive elements of an array of structures: Repeat that command by typing RET. Some convenience variables are created automatically by GDB and given values likely to be useful. The variable is automatically set by the x command to the last address examined (see section Examining memory ). Other commands which provide a default address for x to examine also set to that address these commands include info line and info breakpoint. The type of is void except when set by the x command, in which case it is a pointer to the type of . The variable is automatically set by the x command to the value found in the last address examined. Its type is chosen to match the format in which the data was printed. exitcode The variable exitcode is automatically set to the exit code when the program being debugged terminates. On HP-UX systems, if you refer to a function or variable name that begins with a dollar sign, GDB searches for a user or system name first, before it searches for a convenience variable. 8.12 Memory region attributes Memory region attributes allow you to describe special handling required by regions of your targets memory. GDB uses attributes to determine whether to allow certain types of memory accesses whether to use specific width accesses and whether to cache target memory. Defined memory regions can be individually enabled and disabled. When a memory region is disabled, GDB uses the default attributes when accessing memory in that region. Similarly, if no memory regions have been defined, GDB uses the default attributes when accessing all memory. When a memory region is defined, it is given a number to identify it to enable, disable, or remove a memory region, you specify that number. mem address1 address2 attributes . Define memory region bounded by address1 and address2 with attributes attributes . . delete mem nums . Remove memory regions nums . . disable mem nums . Disable memory regions nums . . A disabled memory region is not forgotten. It may be enabled again later. enable mem nums . Enable memory regions nums . . info mem Print a table of all defined memory regions, with the following columns for each region. Memory Region Number Enabled or Disabled. Enabled memory regions are marked with y. Disabled memory regions are marked with n. Lo Address The address defining the inclusive lower bound of the memory region. Hi Address The address defining the exclusive upper bound of the memory region. Attributes The list of attributes set for this memory region. 8.13 Copy between memory and a file The commands dump. append. and restore are used for copying data between target memory and a file. Data is written into a file using dump or append. and restored from a file into memory by using restore. Files may be binary, srec, intel hex, or tekhex (but only binary files can be appended). dump binary memory filename startaddr endaddr Dump contents of memory from startaddr to endaddr into raw binary format file filename. append binary memory filename startaddr endaddr Append contents of memory from startaddr to endaddr to raw binary format file filename. dump binary value filename expression Dump value of expression into raw binary format file filename. append binary memory filename expression Append value of expression to raw binary format file filename. dump ihex memory filename startaddr endaddr Dump contents of memory from startaddr to endaddr into intel hex format file filename. dump ihex value filename expression Dump value of expression into intel hex format file filename. dump srec memory filename startaddr endaddr Dump contents of memory from startaddr to endaddr into srec format file filename. dump srec value filename expression Dump value of expression into srec format file filename. dump tekhex memory filename startaddr endaddr Dump contents of memory from startaddr to endaddr into tekhex format file filename. dump tekhex value filename expression Dump value of expression into tekhex format file filename. restore filename binary bias start end Restore the contents of file filename into memory. The restore command can automatically recognize any known bfd file format, except for raw binary. To restore a raw binary file you must use the optional argument binary after the filename. If bias is non-zero, its value will be added to the addresses contained in the file. Binary files always start at address zero, so they will be restored at address bias. Other bfd files have a built-in location they will be restored at offset bias from that location. If start and/or end are non-zero, then only data between file offset start and file offset end will be restored. These offsets are relative to the addresses in the file, before the bias argument is applied. Tutorial of gcc and gdb The graphical user interface (GUI) domainates the current operating environments for personal computing. However, there are still tons of powerful tools, such as gcc and gdb, using the traditional text-based interface. Now, lets turn on the terminal within Linux, FreeBSD, Mac OS X, or any other UNIX-like operating system to discover the power of command-line tools If you dont have any linux machine available, please try to login ieng6.ucsd. edu and ieng9.ucsd. edu with ssh clients. If you have problem login these machines, please contact Hung-Wei. Contents gcc gcc is the C and C compiler developed by GNU project. It is widely adopted as the default compiler of UNIX-like systems. If you are using a Mac, you may also get gcc by installing Xcode (Developer) Tools in the Mac OS X installation Disc 1. Basic Usage Assume that we have a C source file garbage. c with the content of shown below: The basic way of compiling garbage. c into an executable file called garbage is: gcc - o garbage garbage. c If the program is compiled without errors, you can execute the program by typing ./garbage followed by two numbers as its arguments. If you are interested about how the assembly code of garbage. c look like, you can also generate the assembly code by replacing the - o garbage option with - S as: gcc - S garbage. c The gcc will stop compiling the program after the garbage. s file is generated. You may use any text editor to browser the content of the assembly code. To figure out what the assembly code does, you may reference the following documents. Handout on x86 ISA . A good document on x86 ISA . A good document on x86 ISA . A good document on x86 ISA. Frequently Used Options In addition to the basic usage, gcc also provides options that help you optimize or debug your code. For example, you may: Compile your code with debugging information: gcc - g - o garbage garbage. c Compile your code with optimizations: gcc - O n - o garbage garbage. c Notice: n is usually a number through 1 to 3. The larger the number, the more optimizations are performed while compiling the code. The optimization options may differ in each platform. For example, the gcc under Mac OS also supports - Os and - Oz to allow optimization for code size. For other optimization/debug options, you may use man gcc under any UNIX-like system. gdb gcc is a debugger by GNU project. Gdb can step through your source code line-by-line or even instruction by instruction. You may also watch the value of any variable at run-time. In additon, it also helps to identify the place and the reason making the program crash. Basic Usage All program to be debugged in gdb must be compiled by gcc with the option - g turning on. Continue with the garbage example, if we want to debug the program garbage, we can simply start gdb by: gdb ./garbage Then, you will see the gdb environment similar as following:To start running and debugging the program, we can simply type the run command after the (gdb) prompt as below: If the program takes arguments such as garbage arg1 arg2, we may start running the program with these arguments as: Breaking Program To inspect the current state of program exeution, we need to break the execution of debugging program in gdb. At any point, we may use ctrl-c to interrupt the running program. However, ctrl-c is hard to help breaking our program at a specific point. Therefore, gdb provides the breakpoint function that allows us to break debugging program at the breakpoint set by ourselves. Gdb allows the breakpoint to be set to any source code line, function, or even any instruction. Break by line: to break the program at the beginning of a certain line, we can use the command break sourcefilename:linenumber. For example, if we want to break at the beginning of main function in garbage. c, we can do as below: Break by function: to break the program at the beginning of a certain function, we can use the command break sourcefilename:functionname(). For example, if we want to break at the beginning of main function in garbage. c, we can also try below: Break by instruction: to break the program at the beginning of a certain machine instruction, we can use the command break PC. For example, if we want to break at the beginning of main function in garbage. c, we can also try below: To show the current breakpoints we have, we may use the info breakpoint command as: To disable a breakpoint we have, we may use the disable breakpointnumber. To re-enable disabled breakpoint, we can turn it on by enable breakpointnumber. To remove a breakpoint, we can use delete breakpointnumber or replace the break with clear command as we create these breakpoints. To resume the exeution of the interrupted program, we can use the continue or c command. Stepping through program Once a running program is interrupted in gdb, we can step the program to inspect how the program is executed. Gdb provides several step commands to allow stepping program with different granularities: s: the debugger will step to the next line in the source code. For example, using the s command, the program will step through line 9 from line 8 after the program interrupted by breakpoint 1. si: the debugger will step to the next instruction in the compiled code. For example, using the si command, the program will step through PC 0x00001f91 from 0x00001f8e. n: the debugger will step to the next source line. Each function call will be treat as a single source code line. Inspect variables/register value Once a running program is interrupted in gdb, we can also inspect the value of a variable using the print command. If we are interested about the current value of variable a, we can simply print variablename. For example, after line 8 is executed, we can inspect if the atoi function correctly translate the characters to integer as below: Similiarly, if we are interested about the current value of a register, we can simply print registername. For example, after line 8 is executed, we can inspect eax as: If we are interested about all the register values, we can use info registers command to display the value in all registers.

No comments:

Post a Comment