Ir para conteúdo
Faça parte da equipe! (2024) ×
Conheça nossa Beta Zone! Novas áreas a caminho! ×
  • Quem está por aqui   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.

Utilizando um debugger - OllyDbg


'Surfistinha
 Compartilhar

Posts Recomendados

INTRODUÇÃO

 

Seguindo a minha linha de tutoriais voltados a programação, vou tratar sobre um assunto que me interessa muito e talvez seja interessante para os programadores em geral: disassembler e debuggers.

 

Primeiramente seria interessante esclarecer um pouco sobre o que é um debugger e o que é um disassembler, pois apesar de andarem quase sempre juntos, possuem finalidades diferentes.

 

Disassembler é algo que consegue transformar linguagem de máquina para a linguagem assembly, transcrevendo as instruções enviadas ao processador para os seus mnemônicos em assembly (asm). Não deve ser confundido com um descompilador, que procura converter o código nativo em uma linguagem de mais alto nível como C, C++ ou Basic.

 

Debuggers são programas capazes de analisar, depurar e testar aplicações. Atualmente a maioria das IDEs de programação contam com um debugger embutido (Visual Studio, por exemplo). A principal utilidade deles é para a identificação e tratamento de erro, sendo que é possível rodar o código linha por linha (ou instrução por instrução) e analisar a mudança das variáveis e do comportamento do código. Os debuggers de binários já compilados - como os executáveis do Windows (EXE) - seguem o mesmo conceito dos depuradores normais, mas devido ao fato de o código já ter sido compilado, ele precisa ter um disassembler embutido no debugger para decodificar as instruções.

 

Atualmente existem dezenas de debuggers e disassemblers por aí, dentre os quais os mais famosos são: W32DASM, IDA, WinDbg, SoftICE e Ollydbg. Neste tutorial será utilizado o OllyDbg, pois é um dos melhores e mais poderosos debuggers (incluindo um disassembler) disponíveis no mercado. É também pequeno e gratuito

 

Site oficial do OllyDbg, com o link para download:

É necessário se cadastrar para acessar o conteúdo.

 

QUAL A UTILIDADE UM DEBUGGER?

 

Muita gente se pergunta do porquê de usar um debugger, sendo que na maioria dos casos você tem a acesso ao código fonte original (caso você tenha programado o aplicativo). Vou citar abaixo algumas das maiores utilidades de um debugger:

Tratamento de erro. Certamente uma das principais. Às vezes durante a programação de um aplicativo um pequeno erro passou despercebido, ocasionando mal funcionamento ou gerando uma operação ilegal. Em muitos casos é mais fácil você analisar o binário já compilado dentro de um debugger do que tentar encontrar o erro no código original. Dentro desse mesmo item podemos citar a correção de bugs de aplicações já descontinuadas (desde que com a autorização da empresa dona dos direitos).

Engenharia reversa. O processo de engenharia reversa de software não poderia ser feito de forma eficiente sem a utilização de um debugger/disassembler. Muitas pessoas tendem a confundir *****ing com engenharia reversa, sendo que são conceitos diferentes. A engenharia reversa por si só é uma atividade completamente legal, pois muito do que vemos hoje só foi possível devido à engenharia reversa. A criação de drivers para Linux de periféricos que antes só funcionavam com o Windows (WinModems) é um bom exemplo de como a engenharia reversa traz coisas boas para nós.

Aprendizado. O uso de debuggers e engenharia reversa é uma das melhores formas de se aprender a linguagem assembly. Você programa algo em uma linguagem de médio ou alto nível e posteriormente analisa o resultado do binário compilado dentro de um debugger. Com esse conhecimento é possível dominar melhor a linguagem e criar algoritmos mais otimizados e eficientes.

CONCEITOS NECESSÁRIOS

 

Para entender o funcionamento de um debugger é preciso saber um pouco sobre alguns conceitos ligados a informática, como o funcionamento da memória, processador, pilhas e endereços. O conhecimento básico de assembly também é necessário, já que essa é a linguagem que teremos de analisar. Caso não tenha experiência em assembly, fique tranqüilo, pois nos capítulos seguintes darei uma visão geral sobre ela, o suficiente para entender o nosso mini-aplicativo de estudo. Abaixo segue uma breve lista de conceitos:

Processador/CPU: É o cérebro de todo computador. É ele que decodifica as instruções e executa os códigos operacionais. É composto basicamente por uma unidade lógico-aritmética (ALU), unidade de ponto flutuante (FPU), registradores, cachê, barramento e gerador de clock.

 

Memória RAM: Local de armazenamento temporário de dados (são apagados ao desligar o computador). Todo aplicativo se utiliza da memória para armazenar seus dados e estes são buscados e gerenciados pelo processador.

 

Endereçamento de memória: É uma faixa de valores que apontam para uma determinada posição de memória. Toda vez que você escreve ou lê algum dado da memória é necessário indicar o endereço de onde está aquele valor, para que o processador possa buscá-lo.

 

Pilha (Stack): É uma estrutura de dados. Sua principal característica é a forma de funcionamento, onde você apenas coloca ou retira os valores, sem indicar um endereço (LIFO – Last in, First Out – Último a entrar, primeiro a sair). Ela funciona de forma semelhante a uma pilha de livros em que você vai os empilhando. Quando precisar remover um deles, é necessário tirar todos os livros de cima.

 

Registradores: Pequenas partes de memória presentes dentro dos processadores (não confundir com memória RAM). Extremamente rápidas, sendo que a CPU as utiliza como forma temporária de armazenamento de dados e realização de operações. A quantidade de dados que podem ser armazenados vai depender do tipo de processador. Os processadores de 32 bits conseguem armazenar números de até 32 bits em cada registrador, sem precisar de rotinas de conversão.[/size]

 

UM POUCO DE ASSEMBLY

 

Para fazer o debug de binários compilados é necessário ter um conhecimento (ao menos básico) da linguagem assembly, já que é para ela que a linguagem de máquina é traduzida.

 

Assembly (ou asm, com é abreviada) é uma linguagem de baixo nível que basicamente interpreta os códigos operacionais (opcodes, veja abaixo) e os transcreve para seus mnemônicos. É literalmente uma tradução da linguagem de máquina. O uso da linguagem assembly pode ser bem variado, podendo fazer de tudo um pouco, mas é amplamente utilizada na programação básica de Kernels e em algoritmos que precisam ser altamente otimizados, onde asm é a linguagem ideal, já que é puramente linguagem de máquina traduzida.

 

Não pretendo agora explicar todo o funcionamento, estrutura e comandos da linguagem. Vou dar apenas um apanhado geral sobre alguns termos e uma breve descrição sobre os comandos mais básicos e corriqueiros que se encontra. Precisamos primeiramente definir o que são mnemônicos e o que são os opcodes.

 

Opcodes (traduzido em operational code, ou código de operação) é a instrução que é enviada e interpretada pelo processador. Cada opcode, ao ser interpretado pelo processador, vai realizar uma operação. Mnemônicos são as palavras ou combinação de letras utilizadas para representar um opcode, tornando a linguagem de máquina mais legível. Veja abaixo um exemplo de um mnemônico do comando MOV:

 

Código:

MOV EAX,1

Esse comando em assembly apenas move o valor 1 para o registrador EAX (veremos isso logo adiante na explicação dos comandos). Na hora de transformar isso em linguagem de máquina (por um asssembler), esse comando é traduzido para um conjunto de números que possa ser interpretado pelo processador:

 

Código:

B801000000

A teoria por trás de tradução de mnemônicos em opcode (e vice-versa) é um tanto complexa, principalmente para a plataforma Intel na arquitetura IA32. É um processo que deve ser realizado bit a bit e fugiria um pouco do contexto deste tutorial.

 

A principal dificuldade na linguagem assembly é certamente a sua estrutura, que foge do padrão de linguagens de mais alto nível como C ou Pascal. Nada de Ifs com múltiplas comparações, Switches, For ou While. Tudo é feito com comparações simples e saltos, perdendo a sua linearidade (semelhante aos GoTo do BASIC).

Felizmente hoje temos debuggers muito inteligentes que conseguem estruturar e identificar rotinas e repetições, facilitando muito o trabalho de interpretação. Mesmo com essas melhorias, ainda acho importante ter um papel e uma caneta ao lado, onde você pode fazer anotações e ir estruturando/convertendo o código na medida em que você os interpreta.

 

Para o assembly, a localização dos valores e variáveis é sempre baseada nos endereços que elas ocupam na memória. O nome que você define para uma variável durante a programação é substituído pelo endereço de memória que ela ocupa. Cada instrução também possui um endereço, que é utilizado para controlar o fluxo e a estrutura do código. Sempre que você faz um salto, é necessário indicar o endereço que o código deve ser direcionado, semelhante ao que ocorria nas numerações de linhas dos BASICs mais antigos. Veja um exemplo abaixo de como ficaria um código em C e o seu resultado compilado para assembly, utilizando apenas registradores comuns:

 

Código:

void main() {

int a = 4;

int b = 6;

int c;

 

if((a == 4) && (b == 6)) {

c = 5;

}

}

O código acima quando compilado pode se transformar em algo semelhante a isso (boa parte do código acima é inútil, estou utilizando somente para exemplificar):

 

Código:

00000000 MOV EAX,4h ;move o valor 4 para EAX

00000005 MOV EBX,6h ;move o valor 6 para EBX

0000000A CMP EAX,4h ;compara EAX com 4, se for verdadeiro: ZF = 1

0000000D JNE 00000019h ;se ZF != 1, pule para endereço 00000019h

0000000F CMP EBX,6h ;compara EBX com 6, se for verdadeiro: ZF = 1

00000012 JNE 00000019h ;se ZF != 1, pule para endereço 00000019h

00000014 MOV ECX,5h ;move o valor 5 para ECX

00000019 RETN ;finaliza execução e retorna

Pra entender o código acima é necessário entender sobre aquilo que compõe a linguagem assembly. Ela é basicamente composta por registradores, endereços e instruções (mnemônicos).

 

Os registradores foram explicados no capítulo anterior, mas vamos agora saber quem são eles. Os processadores da arquitetura Intel de 32 bits possuem basicamente nove registradores de 32 bits comuns: EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI e EIP. Teoricamente cada um desses registradores possui uma determinada “função padrão”, mas devido a sua escassez, muitas vezes eles são utilizados como registradores para qualquer propósito. Você pode criar um código usando livremente os oito primeiros registradores que não haverá muitos problemas (desde que saiba o que está fazendo/modificando). O último registrador, EIP, é quase sempre mantido intacto, pois ele é o responsável por contar as instruções e informar o endereço da próxima instrução. Alterar o seu valor pode desviar completamente o fluxo do aplicativo e provavelmente vai gerar uma falha de segmentação ou uma operação ilegal.

 

Esses registradores apresentados são todos de 32 bits. No entanto também é possível utilizar apenas 8 ou 16 bits, como mostra a tabela abaixo utilizando o EAX como exemplo (a teoria vale para os outros registradores também):

deb_1.png

Para o caso da porção de 8 bits, o registrador terminado em L são os 8 bits menos significantes de AX e o terminado em H são os 8 bits mais significantes de AX. Para a porção de 16 bits, são utilizados os 16 bits menos significantes da porção de 32 bits.

deb_2.png

Além dos registradores, também existem as Flags, que são bits utilizados como resultado de operações (verdadeiro ou falso, por exemplo). Elas são usadas principalmente para análise condicional em instruções como CMP e TEST. Dentre as diversas flags, as mais corriqueiras são: ZF (Zero Flag), CF (Carry Flag) e SF (Signal Flag). A ZF é setada sempre que uma operação resulta em zero (uma comparação entre dois números através do comando CMP subtrai seus operandos sem alterar valores e seta a ZF caso o resultado da subtração seja zero, indicando valores iguais). A flag CF é setada quando o resultado de uma operação estoura o valor máximo comportado pelo registrador/local sem considerar o sinal (overflow). Por último, tempos a SF, que é ativada sempre que o bit mais significativo de um operando for 1, indicando um valor negativo (pesquise sobre complemento de dois).

 

Os endereços na linguagem assembly são a base para o fluxo do aplicativo e para o armazenamento de dados. As variáveis que você usa durante a programação são substituídas por endereços que apontam para uma área da memória paginada com acesso a leitura e a escrita. Os destinos dos saltos (Jumps) também dependem dos endereços das instruções, pois é através deles que você informa o destino do salto.

O código abaixo demonstra apenas uma linha de assembly onde é possível ver o endereço da instrução (00401000) e o endereço para um byte de memória (00403000) para o qual o número nove está sendo movido:

 

Código:

00401000 MOV BYTE PTR DS:[00403000], 09h

Por último temos as instruções, que nada mais são do que os opcodes traduzidos em um mnemônico, como demonstrado e exemplificado alguns parágrafos acima.

Abaixo eu vou por uma pequena lista mostrando algumas das instruções mais utilizadas, pois seria inviável colocar todas elas (são aproximadamente 130 instruções bases para a arquitetura Intel).

MOV destino, origem

Move o valor do campo origem para o destino. Essa instrução possui diversas variações, por isso ela pode aparecer de diversas formas diferentes (pode-se trabalhar com constantes, memória, pilha, etc). Alguns exemplos:

 

MOV EAX, 10h

MOV AX, WORD PTR DS:[00403000]

MOV BYTE PTR DS:[00403002], 1Ch

 

CMP arg1, arg2

Realiza uma comparação entre os dois operandos. A comparação é feita simplesmente subtraindo os dois operandos e caso o resultado for zero (valores iguais), ele seta a ZF para 1. Vale lembrar que essa operação não altera os valores dos operandos, apenas as flags.

 

CMP EAX, 04h

 

JMP endereço

Faz um salto incondicional e obrigatório para o endereço indicado.

 

JMP 00401008h

 

JZ endereço / JE endereço

Faz um salto condicional. Caso o valor da zero flag seja 1, ele realiza o salto. Normalmente utilizado junto com um CMP para realizar um desvio caso a comparação seja verdadeira.

 

JE 0040101Ah

 

JNZ endereço / JNE endereço

Semelhante ao item acima, mas realiza o salto somente quando a zero flag não foi setada (ZF = 0).

 

JNZ 0040102Ch

ADD destino, arg1

Adiciona o valor de arg1 ao destino. Também possui diversas variações, pelas mesmas razões do comando MOV. Se o resultado estourar o limite do destino, a CF é setada.

 

ADD EBX, 04h

ADD EBX, DWORD PTR DS:[00403032]

 

SUB destino, arg1

Realiza uma subtração dos operandos. As variações e características são as mesmas do comando ADD.

 

SUB ECX, 2Ah

 

PUSH valor

Coloca o valor no topo da pilha (Stack). O comando PUSH é amplamente utilizado nas chamadas de funções (CALL), pois é através da pilha que a função busca seus argumentos.

 

PUSH 08h

 

POP destino

Remove o valor do topo da pilha e o armazena no destino.

 

POP EAX

 

CALL local

Faz chamada a uma função. É possível passar o local de diversas formas para o comando CALL, desde uma constante, registrador ou até mesmo uma função externa dentro de uma DLL. O comando CALL usa a pilha para indicar o endereço para o qual a função deve retornar depois de finalizada a sua execução.

 

CALL User32!GetDlgItemTextA

CALL 0040115Fh

 

Essas são as instruções mais comuns dentro de um binário compilado. Claro que existe mais de uma centena delas, mas eu procurei colocar aqui apenas aquelas que serão utilizadas no aplicativo de aprendizado. Para uma lista completa com uma explicação mais profunda dos opcodes, recomendo ver a lista apre******* neste endereço:

É necessário se cadastrar para acessar o conteúdo.

INTERFACE DO OLLY DEBUGGER

 

Após uma boa parte teórica, chegou a hora de por em prática aquilo que acabamos de estudar. Neste capítulo vou apresentar um pouco da interface do OllyDbg, que apesar de intuitiva, merece esclarecimentos.

 

Para o nosso estudo, eu criei um simples aplicativo que iremos depurar mais a frente. Ele é necessário neste já neste capítulo (não para depuração, mas para a apresentação dos itens do Olly). Você pode baixar o arquivo executável juntamente com o seu código fonte (programado em assembly na sintaxe MASM32 utilizando o WinAsm Studio como IDE) no link abaixo:

É necessário se cadastrar para acessar o conteúdo.

 

O OllyDbg pode ser baixado gratuitamente através do site

É necessário se cadastrar para acessar o conteúdo.
. É bem pequeno e não necessita instalação, basta extrair o conteúdo para uma pasta qualquer.

 

Após extraído, abra o Olly, vá em “File->Open” e abra o nosso arquivo de estudo (adivinhe.exe). Rapidamente o Olly vai interpretar o arquivo e mostrar o disassembly na janela principal. Vamos deixar essa parte mais frente, já que o objetivo deste capítulo é apenas mostrar a interface, sem depurar o aplicativo por enquanto. A tela deve ser semelhante a essa:deb_3.png

 

A interface do aplicativo é composta por poucos botões. O segredo do Olly é o botão direito do mouse. A maioria das funções existentes no aplicativo pode ser acessada através do botão direito do mouse, sendo que os itens exibido no menu de popup variam de acordo com o local onde foi dado o clique (dependendo da coluna e da região).

 

Eu numerei as principais regiões da tela de 1 a 4.

 

Região 1

 

Esta é a tela principal do programa, onde é apresentado o disassembly do aplicativo. Ela é dividida em quatro colunas:

 

Coluna 1 – Address. Ela nos mostra o endereço virtual das instruções (para saber mais sobre esse endereçamento, veja meu artigo sobre o funcionamento dos executáveis). Você pode reparar que os endereços não são em intervalos iguais para cada instrução. Isso ocorre devido ao fato de que o tamanho das instruções ser variável, como podemos observar na segunda coluna.

 

Coluna 2 – Hex Dump. Aqui temos o código da instrução no seu formato hexadecimal (a cada 2 caracteres, temos 1 byte). São esses valores que ficam armazenados dentro do arquivo executável e que são passados para o processador. Como mencionado no parágrafo anterior, as instruções variam de tamanho, sendo que o endereço da próxima instrução é dado pelo endereço da instrução atual mais a soma dos bytes da instrução. Veja o exemplo do nosso aplicativo de exemplo. Ele começa no endereço 00401000 (padrão do Windows) e a sua primeira instrução é composta por 2 bytes (6A 00). O endereço da próxima instrução (na linha de baixo) vai ser o endereço atual somado com o tamanho da instrução (00401000+2) = 00401002.

 

Coluna 3 – Disassembly. Essa coluna nada mais é do que a interpretação e a tradução para assembly das instruções presentes na segunda coluna. A análise do aplicativo é feita quase que inteiramente nela.

 

Coluna 4 – Comments. Essa coluna não influencia no aplicativo, ela é utilizada apenas para comentários e informações. O Olly a utiliza para identificar as chamadas de função juntamente com os seus argumentos (você pode ver que ele identifica as chamadas da API do Windows em vermelho e lhe mostra os argumentos, facilitando e muito a interpretação).

Região 2

 

Essa área mostra todos os registradores e flags que nós vimos anteriormente (juntamente com diversos outros valores). A cada instrução essa tela é atualizada, mostrando o estado atual de cada um dos itens. Caso algum desses itens tenha sido modificado de uma instrução para outra, o Olly as colore com outra cor (nesse caso é o vermelho). As flags são mostradas logo abaixo dos registradores, abreviadas com a letra C (Carry Flag), Z (Zero Flag) e S (Signal Flag)

 

Região 3

 

Essa região nos mostra a memória física (RAM) destinada ao aplicativo. É possível observar o valor de cada byte de memória dentro do espaço reservado ao aplicativo. É composta por três colunas:

Coluna 1 – Address. Mostra os endereços virtuais de memória.

 

Coluna 2 – Hex Dump. Este espaço contém o valor de cada byte da memória. Por padrão o Olly coloca 8 bytes por linha e por essa razão a coluna de endereços cresce de 8 em 8 bytes.

 

Coluna 3 – ASCII. Essa coluna pode ser utilizada para exibir de formas diferentes os valores contidos na memória. Por padrão o Olly opta por exibir a representação ASCII desses valores. O modo de representação pode ser alterado utilizando o botão direito do mouse.

 

Região 4

 

Mostra o estado atual da pilha (stack). Como visto anteriormente, a pilha é amplamente utilizada durante as chamadas de função. O VisualBasic é uma linguagem que faz um uso muito grande da pilha, principalmente pela quantidade de funções que são utilizadas pelo aplicativo. Também é dividida em 3 colunas :

Coluna 1 – Address. Cumpre o mesmo papel das outras colunas de endereço. Nota-se que o endereço cresce de quatro em quatro bytes, pois cada posição da pilha é ocupada por um tipo DWORD (4 bytes)

 

Coluna 2 – Value. Valor armazenado naquele endereço da pilha

 

Coluna 3 – Comment. Utilizado para comentários e mostrar informações relevantes sobre aquele endereço. O Olly identifica diversos itens da pilha (como endereços de retorno) e adiciona essas informações na coluna de comentários.

Além das regiões nós temos a barra de ferramentas:

deb_4.png

Abaixo uma descrição de cada botão, da esquerda para a direita.

Open - Abre o executável para depuração

Restart – Recarrega o aplicativo atual

Close – Fecha a aplicação carregada

 

Play – Inicia a execução e depuração do aplicativo. Caso nenhum breakpoint tenha sido posicionado (veremos adiante), o programa será executado normalmente.

Pause – Pausa o aplicativo em andamento

 

Step Into – Caso um breakpoint tenha sido colocado em uma chamada de função, esse botão lhe permite fazer a depuração do conteúdo dessa função.

Step Over – O contrário do item anterior. Ele simplesmente não “entra” dentro da chamada (mas ainda assim a executa), continuando a depuração na próxima instrução.

Trace Into – Utilizado apenas quando está se faz backtracing. Ele registra as ações e endereços em um log, registrando também o conteúdo das funções chamadas.

Trace Over – Semelhante ao item acima, mas não faz o registro do conteúdo das chamadas.

 

Execute Till Return – Executa as instruções até encontrar o primeiro comando de retorno (RETN).

 

Go to Address – Permite ao usuário especificar um endereço do código para visualizar.

Após os comandos básicos de depuração, temos os botões das janelas:

L – Show Log Window: exibe um log, no qual o Olly registra algumas ações como carregamento de plugins, etc.

E – Show Modules Window: exibe todos os módulos e funções externas utilizados pelo programa (DLLs). Com o menu direito é possível acessar uma gama de opções dentro dessa janela (o mesmo vale para todas as outras janelas que forem mencionadas). Essa janela de módulos é muito importante para configurar breakpoints nas APIs do Windows, facilitando a aproximação em determinada região do código.

M – Show Memory Window: mostra o estado da memória que está sendo utilizado pelo aplicativo, incluindo as seções do executável e tabelas de importação/exportação. Para um detalhamento byte a byte da memória, deve se utilizar a região de memória física mostrada na janela principal do aplicativo.

T – Show Threads: exibe o estado de cada thread contida no aplicativo. Em aplicações multi-threading é possível, através dessa janela, ter um controle sobre cada uma das threads.

W – Show Windows: mostra a estrutura e configuração das janelas carregadas pelo aplicativo (definida pelo WinProc). Os dados só são mostrados com o programa em execução e precisa ser atualizada manualmente pelo usuário (através do botão direito do mouse).

H – Show Handles: exibe uma informação detalhada sobre os handles (referência a um objeto) que estão sendo utilizados pelo aplicativo. Quando o aplicativo abre um arquivo, é retornado um handle, que é utilizado para fazer a leitura e escrita, por exemplo.

C – Show CPU: janela padrão do aplicativo, que é aberta automaticamente na hora de carregar o alvo. O seu conteúdo já foi explicado nos itens anteriores (onde as regiões foram numeradas de 1 a 4).

/ - Show Patches: as modificações feitas no executável ficam registradas nessa janela, facilitando a modificação ou o retorno à instrução original.

K – Show Call Stack: mostra uma pilha de todas as chamadas de função até então feitas pelo aplicativo.

B – Show Breakpoints Window: exibe todos os breakpoints setados no programa alvo.

R – Show references: exibe todas as referências encontradas durante uma busca (seja ela uma constante, instrução, string). Veremos mais sobre elas adiante.

... – Run Trace: nessa janela é mostrado o resultado da operação de tracing (mencionada quando falamos de Trace Into/Over). Tracing é um processo um pouco complicado, por isso a sua explicação detalhada será apre******* mais a frente (é possível encontrar uma boa explicação na própria ajuda do Olly).

S – Show Source: quando o aplicativo alvo é compilado com as informações de debug, normalmente o código assembly resultante também é armazenado. Nesse caso essa janela exibe esse código e mostra em tempo real o local no código fonte original que está sendo executado no momento. Muito útil para comparar o código assembly escrito e o compilado.

Por último temos os botões de configuração e ajuda.

Debugging Options – Exibe a janela de configuração do Olly. A princípio não é necessário alterar nada para fazer a depuração, a não ser que você tenha noção de onde está mexendo.

Appearence – Permite configurar o esquema de cores. Recomendo alterar essas configurações para algo que lhe agrade, fazendo um “syntax highlighting” do código, facilitando a leitura.

Help – Mostra a janela de ajuda do Olly. A ajuda está em Inglês.

Estas foram as opções contidas na barra de ferramentas. O Olly também conta com um menu tradicional, que contém basicamente as mesmas funções da barra de ferramentas. Um dos itens do menu que vale a pena mencionar é o de plugins. O Olly suporta a criação de plugins, sendo alguns deles muito úteis. Por padrão ele vêm apenas com dois plugins, um de bookmarks e outro de comandos, que adiciona uma caixa de texto no rodapé do programa onde você pode entrar com ações e comandos de forma semelhante ao SoftICE.

 

No rodapé do Olly fica uma pequena barra de status, que além de mostrar o estado atual do alvo (finalizado, pausado ou em execução), serve como um informativo.

 

FORMAS DE APROXIMAÇÃO

 

Uma das maiores dificuldades em debugging de baixo nível (em assembly) é identificar o local onde se encontra aquele trecho de código de deseja analisar. Existem diversas manhas para convergir ao local correto, sendo que vou citar duas das mais utilizadas.

 

A primeira delas consiste em buscar em buscar por strings. Na maioria dos casos todo o texto presente em um aplicativo fica armazenado em uma string table (tabela de strings), cada uma com seu número identificador. Normalmente quem decide o que vai para a tabela de strings ou o que é referenciado diretamente no código é o compilador, por isso esse método nem sempre é totalmente funcional, mas costuma ter bons resultados.

 

Certo, mas que strings devemos procurar? Nós queremos é encontrar o local onde é feita a comparação do número digitado com o número correto. Se o número não for aquele que você digitou, ele vai exibir uma mensagem, que contém um título e um texto. Isso é bastante interessante, pois a provável lógica do programa é verificar pelo número digitado e caso ele seja incorreto, nos mostrar a MessageBox. Se nós encontrarmos o local onde o texto é utilizado pela MsgBox, sabemos que estamos pertos e um pouco adiante de onde foi feita a verificação.

 

Há uma maneira bem direta de descobrir o local onde está a chamada para a MsgBox, mas vou focar mais no sistema de busca por string. Vamos lá. Entre com um valor qualquer (maior que 0 e menor que 21) e mande verificar.

 

Irei por mas turtorias

 

Flw

Link para o comentário
Compartilhar em outros sites

Ajuda! script

 

Não sei se estou postando no lugar certo..se tiver peço desculpa...sou novo no forum!

 

fui em open lá e adicionei uma coisa, ai fui no quadrado esquerdo superior e queria add uma Script, mais naum tinha o lugar lá pra add um script...como faço?

versão 1.10

Obrigado!

Link para o comentário
Compartilhar em outros sites

Não sei se estou postando no lugar certo..se tiver peço desculpa...sou novo no forum!

 

fui em open lá e adicionei uma coisa, ai fui no quadrado esquerdo superior e queria add uma Script, mais naum tinha o lugar lá pra add um script...como faço?

versão 1.10

Obrigado!

 

 

Depende se for Script de hack pra jogo esta no lugar errado

 

Mas se for relacionado a programação poste Outras linguagens

 

flw

Link para o comentário
Compartilhar em outros sites

Poste na area TIBIA

 

Flw

 

 

Mais não é nada sobre tibia kkk

não tenho nenhuma duvida com tibia!

 

Só quero saber como adiciono um script no Ollydbg

clicando no quadrado superior esquerdo, Scripts (S) > Loading.

 

Quem souber, peço ajuda!

Obrigado!

Link para o comentário
Compartilhar em outros sites

  • 2 meses depois...
  • 3 meses depois...
Este tópico está impedido de receber novos posts.
 Compartilhar

×
×
  • Criar Novo...

Informação Importante

Nós fazemos uso de cookies no seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies , caso contrário, vamos supor que você está bem para continuar.