sexta-feira, 12 de junho de 2009

Por baixo dos panos: O Windows e Você!

Eu novamente com mais uma série de tutos, mas dessa vez explorando o windows completamente.
Você vai traçar APIs nativas, aventurar-se no ring 0 e eu prometo.. que se uma tela azul aparecer no seu computador por conta de qualquer erro, no final desse tuto você vai depura-la e saber o que causou esse erro.

Você pra ler esse tuto precisa de conhecimentos intermediário de C e se possível conhecimentos básicos de assembly.
Não tem?
Não leia.
Preguiça de ler?
Não leia pois eu acredito que o tuto todo possa formar mais de 2 ou 3 mil páginas de livro.

Avisos dados então..
Let's rock! =]

\---(BASEADO NO WINDOWS XP)---/



A primeira parte é sempre teórica.. vo mandar braza.. mora?
Então ta supimpa.

Um micro-processador possui básicamente quatro estágios.
O windows se aproveita de dois desses estágios.
O primeiro chamado de ring 0(zero) e o quarto chamado de ring 3.
Ao ring0 damos o nome de kernel-mode.
Ao ring3 damos o nome de user-mode.
O windows é um kernel-sided operational system, ou seja, o seu "código principal" está todo em kernel-mode(ring0).
O kernel do windows é o seu núcleo e ele é o dito "código principal" do sistema operacional.

O que está em user-mode não pode tocar nem ver o que está em kernel mode.
É um conceito bem antigo chamado de sand-box que impede que aplicações usuário danifiquem qualquer componente vital para o funcionamento do sistema. Por isso, se o seu programa der um erro, parar de responder ou qualquer outra coisa.. o sistema operacional será capaz de se recuperar e fechá-lo.

O micro-processador mantém-se alterando de tempo em tempo entre user-mode e kernel-mode.
Hora executa um trexinho de código daqui e hora executa um trecho de código dali.
O windows usa uma interrupção especial que força o processador a entrar no ciclo de kernel-mode.(ela é usada nas APIs por exemplo)

Mas o que são APIs?
Vamos voltar ao mundo real um pouquinho e deixar o ring0 e o ring3 de lado por um instante.

Você tem seu programa codado em C.
O compilador já passou pelos três estágios e gerou seu executável e vamos imaginar que ele só exiba a string "ola mundo!" na tela.
Mas me diga.. como seu programa sabe mostrar na tela as letras que você escreve?
Qual a resolução do seu monitor?
Quais pixels devem ser ascesos?(finjamos que pixels sejam mini-lampadas que ficam na tela do seu pc e que tudo seja tão simples assim)

É ai que entra o sistema operacional.
Ele faz todo o trabalho de se comunicar com o hardware por você.

VOCÊ --> HARDWARE --> WINDOWS -> SEU PROGRAMA

Você não precisa saber qual tipo de monitor está instalado e nem como "ligar" os pixels certos.
Você só diz o que quer escrever e manda o windows fazer o trabalho sujo por você.
Pros oriundos da programação orientada à objetos(POO), isso chama-se encapsulamento.
É a capacidade que um certo componente te dá de trabalhar com ele e com outros meios através dele, sem necessáriamente saber o funcionamento dele ou dos outros meios.

Pra quem já programou na IDE delphi sabe muito bem que você não precisa saber como a TForm aparece la ou aqueles componentes de envio de email.
Você só envia e ele encapsula toda a forma como as smtp requests são geradas e etc.

Mas apartir de agora, o que vai nos interessar, é justamente saber o que acontece por baixo dos panos do windows.

Então, como o printf do seu programa em C chega no hardware de vídeo?
Existem duas metades que se unem para isso acontecer.
O user-mode e o kernel-mode.
Vamos começar entendendo o user-mode.

O windows disponibiliza essas tais APIs.
Elas fazem várias operações e muitas vezes terminam levando as informações que você passa pra elas pra outras APIs que tratam as informações e por final, levam pra uma ultima API nativa da ntdll que chamará por fim a interrupção que fará o processador passar para ring0(kernel-mode).

Existem no entanto, algumas APIs que realizam todas as suas operações em user-mode mesmo.(que não acessam o hardware)
Nós conheceremos algumas delas no decorrer do tuto.

Então, levando em consideração o diagrama anterior, podemos muda-lo mais um pouco para:

VOCÊ <--> HARDWARE <--> WINDOWS <---> APIs <---> SEU PROGRAMA




Bem, eu vou ficar por aqui porque se não o pessoal fica com preguiça de ler..

O windows possui muitas coisas interessantes que poucas pessoas sabem, como um sub-sistema que por exemplo, é feito para permitir a compatibilidade com programas nix like.(interoperabilidade)

Vamos com o tempo conhecer isso tudo e entender porque no meu ponto de vista, o windows ainda é o sistema operacional mais completo existente.

Cya'round. =]

quarta-feira, 15 de abril de 2009

A enganação do décimo terceiro salário

Contudo, a mais escandalosa de todas as mentiras nacionais e justamente aquela que burramente os trabalhadores mais acreditam, é a safada invenção do Décimo Terceiro salário. Para os meus 38 leitores, que certamente foram muito além do curso primário, eis aqui uma modesta demonstração aritmética de como é fácil novamente enganar os trabalhadores.

Suponhamos que você ganha 400 Reais por mês. Multiplicando-se esse salário por doze meses, temos ao fim do ano R$4.800.00. Quando chega o Natal, o generoso e cristão patrão manda então pagar-lhe o conhecido Décimo Terceiro Salário ( de mais R$400.00 que somados ao que você recebeu no ano inteiro somam R$5.200.00) e você vai para casa todo feliz com o saboroso sorriso matreiro do patrão. Agora veja bem o que acontece quando o empregado, ao invés de ouvir as catilinárias dos Lulas e dos Vicentinhos, procura um simples professor de aritmética do Primeiro Grau e que lhe ensina que você sabiamente faça o seguinte :

Você vai ao seu patrão e lhe diz : Patrão, lamentavelmente meu salário é pequeno e como eu tenho que pagar contas de luz e gás durante esse período e não posso esperar até o fim desse mês para pagar contas atrasadas, rogo-lhe que, como meu salário é de R$400.00 mensais, pague-me R$100.00 por semana (o que dá na mesma coisa – 4 semanas a R$100.00 somam R$400.00 ). O distraído patrão concorda ( concorda porque por vezes ele também pode ser burro) e assim fica tudo acertado e você volta para casa tranquilo, porque afinal de contas seu patrão fez-lhe apenas um modesto favor que não lhe custa nada.

Mas aí é que está o engano. E eu pergunto aos meus 38 leitores: Quantas semanas tem um ano ? Resposta inteligente : 52 semanas! Já percebeu a jogada ? Ora, se o patrão lhe paga R$100.00 por semana ( ou seja R$400.00 por mês conforme vimos) multiplicando-se esse valor por 52 semanas, temos – voilá ! – R$5.200.00 ! Surpresa surpresa ? Onde está portanto o 13 Salário ? A explicação é simples, embora os nossos conhecidos líderes trabalhistas nunca se tenham dado conta desse fato simples.

A resposta é que o patrão lhe rouba uma parte do salário durante todo o ano, pela simples razão de que há meses com 30 dias, outros com 31 e também meses com cinco semanas. Pagando-lhe mensalmente, portanto, esse patrão sabido se apodera de um dinheiro que não lhe pertence e isso porque o salário é o mesmo tenha o mês cinco semanas, trinta ou trinta e um dias e depois, com um sorriso de crocodilo lhe presenteia um décimo terceiro, dinheiro que saiu do próprio bolso do trabalhador. Por outro lado, não tenham meus 38 leitores nenhuma dúvida da precisão da informação que explico nesta matéria, pela razão elementar de que, em 1945 acompanhei de perto a habilidade política e matreira do meu falecido e simpático amigo, o deputado Aarão Steinbruck de Niteroi, que com essa gloriosa mentira conseguiu se eleger várias vezes. Daí que, como palavra final para meus inteligentes 38 leitores, ai estão as duas maravilhosas mentiras nacionais. Não caiam no conto do vigário. Não existe nenhum Décimo Terceiro. O patrão apenas lhe devolve o que sorrateiramente lhe surrupiou do salário anual. Que é o que explica porque, quando da votação do projeto Steinbruck, a lei foi aprovada rapidamente pelos patrióticos deputados a serviço da classe dirigente de então, que é a mesma que hoje comanda nosso delicioso Brasil.




Texto escrito por: Mario GiuDicelli
Publicado aqui.


domingo, 11 de janeiro de 2009

Da física à informática! parte 3


ps: elétrons são os vermelhos e o núcleo está em preto

A descoberta dos protons e eletrons(que ocorreu primeiro), foi uma revolução para a estrutura atômica.
E atualmente diz-se que os elétrons ficam do lado de fora do núcleo do âtomo, e os protons do lado de entro.

Os eletrons orbitam(giram em torno de) o núcleo do átomo em uma alta velocidade.

Bem, qualquer coisa que gira cria uma certa força sobre si que parte do centro do circulo imáginário formado pela rotação, para fora em direção ao objeto.

Essa força se chama força centrífuga... é a mesma força que empurra você contra os bancos do carrinho em uma montanha-russa quando está dentro de um loop.



A física é aplicada à todos os seres e objetos, inclusive aos elétrons.
Então se eles se mantém girando em uma órbita infinita.. o que os mantém dentro da orbita de um átomo?

Os prótons!

Os prótons dentro do núcleo "seguram" os elétrons dentro da sua órbita semi-constante.
Que não são completamente puxados para uma colisão com o núcleo por conta da força centrífuga.


Mas calma ae, protóns seguram os elétrons como?

Vamos entender isso, mas como a informação é bem chatinha mesmo, vou ficar por aqui..

Clique aqui para ler a continuação

segunda-feira, 5 de janeiro de 2009

Automação com CLP(controle lógico programável)

Eu acredito que o CLP seja o dispositivo mais odiado da história industrial.
Sabe quando aquele chefe tem milhares de funcionários para colocar tampas em canetas, embalá-las e depois mada-las para à venda?

Bem, acontece que um dia, a procura aumenta.. o que significa que a oferta também precisa fazer o mesmo.
Mas como se os funcionários são limitados?
Contratar mais funcionários?

Contratar mais funcionários é uma tarefa delicada, porque não são só os funcionários que precisam ser contratados.
Você precisa calcular despesas, você precisa contratar chefes e supervisores para essa gente toda e além de tudo, mais funcionários significam, maiores riscos de acidentes de trabalho.

Nesse ponto, ele resolve trocar homens por máquina.. e é ai que muitos perdem seus empregos.

Uma máquina faz mais rápido, mais precisamente e com menores custos, qualquer coisa que um homem faça.
Isso é, qualquer trabalho físico.

Cabe então à nós; pensar, e à elas; fazer.

Quando chefe de uma empresa resolve trocar seus milhares de homens por uma única máquina automatizada, essa decisão tende à afetar muitas pessoas.
Mas também não é culpa d'ele que seus funcionários não se atualizem.

O fato é, quando não se pode vencê-las.. Junte se a elas.
Então, para quê batalhar com as máquinas em uma luta já perdida?
Apenas aprenda à controlá-las.

E é isso que você aprenderá nessa série.

Você não precisa só automatizar máquinas enormes, você pode automatizar qualquer circuito elétrico.
Até mesmo, os aparelhos eletrônicos da sua casa.
Rádios, televisões, tudo!

E aqui, você vai entender como.
Let's have some fun..

terça-feira, 30 de dezembro de 2008

Da física à informática! parte 2, Conceitos Básicos.

É, agora a parte pesada começa.
Nós vamos começar revendo alguns conceitos básicos que você deve ter aprendido na quinta ou sexta série do ensino fundamental.



Uma característica muito importante de qualquer animal, é a curiosidade.
Ela tem nos levado a lugares e descobertas.

Bem, uma das maiores curiosidades do homem, sempre foi saber do que algo é feito.
Se nós temos um muro, e o quebramos, nós descobrimos que ele é feito de tijolos.
Se quebrarmos os tijolos, descobriremos que eles são feitos de argila.


Mas a grande pergunta é, até onde podemos quebrar algo para encontrar sua matéria prima?
Será que existe um fim para esse processo?
Será que existe um ponto em que não se possa mais quebrar algo?

A resposta é sim e não.(?!)



O ÁTOMO


Os gregos foram os primeiros a admitir que existia um fim para esse ciclo.
Um ponto aonde um determinado objeto não poderia ser mais quebrado.
Uma particula única, indivisível(não quebrável) que seria a matéria prima de todas as matérias primas.(o0)
A partícula única comum a todos os seres.
Essa partícula(estrutura?) recebeu o nome de átomo.

O que eles propuseram foi que, tudo, absolutamente tudo, fosse feito de átomos.
Da lã daquela camisa feia que você ganhou de natal ao plástico do copo descartável cheio de cana-de-açúcar("caldo de cana") que você compra todo dia naquela pastelaria dos "chinas".
Até mesmo você!

"Leitor: Mas espera ai!
Leitor: Se tudo é feito de átomos, como tudo parece tão diferente?"

É ai que a química entra.

Vê aquela imagem ali em cima?
O átomo é teoricamente, a esfera central.

E as outras, o que são?
Para os gregos, naquela época, elas não existiam, somente o átomo central existia.
De fato, até meados do século 19, esse conceito perdurou até que admitiu-se a existencia de partículas menores ainda que o próprio átomo.

Essas partículas seriam entituladas: elétrons, neutrons e prótons..

Clique aqui para ler a continuação

segunda-feira, 20 de outubro de 2008

Da física à informática! parte 1 - introdução

Você já parou para olhar em volta?

O mundo muda e não é mais o que já foi.

Não, isso não é filosofia, é a realidade.

Uma realidade que se torna cada vez mais comum em nossas vidas, a tecnologia!

Neste momento eu mesmo estou escrevendo de um notebook.

Talvez você não tenha um notebook, mas deve ter uma televisão, um aparelho de dvd.. um celular?

Se sim, então você já faz parte do novo mundo em que as máquinas realizam e os homens pensam.

Mas você nunca parou para se perguntar como tudo isso pôde acontecer?

Como será que seu televisor funciona?

Como aquele programa em C++ que você codifica todo dia pode existir de verdade?

Não estou falando sobre kerneis de sistemas operacionais, nem tipos de memória.

Eu estou falando de algo mais profundo e antigo que a própria informática, que a tecnologia que nos rodeia... a física!

Sim, ela é a mãe de todas as ciências e nessa série você poderá aprender como a física gera a eletrônica, como a eletrônica gera a micro-eletrônica e como a micro-eletrônica gerou os primeiros computadores.

Você vai conhecer aonde tudo a sua volta se liga, de que forma sua televisão pode existir, de que forma você pode usar radio frequencias.

Mais do que aprender sobre a estrutura de um micro-processador é saber como ele é construído.

Já pensou em fazer robôs?

Nunca se perguntou como são feitos?

Eles também possuem micro-processadores, alguns bem parecidos com o que você tem em seu computador caseiro!

Nessa série, nós vamos quebrar as barreiras dos softwares e partir para um ponto em que tudo é possível.

Partiremos da física, exemplos eletrônicos, montar placas de circuitos, montar nossos mini-robos, manutenção de eletro-domésticos e por fim chegaremos na informática e então, você saberá como tudo isso foi possível, graças a pessoas capacitadas e autruístas.

Nós, como seres pensantes não precisamos ser subjulgados por nenhuma máquina, porque nós às criamos.

Saberemos o que um computador faz desde à sua essencia até o nosso software programado em uma IDE.

Clique aqui para ler a continuação

domingo, 19 de outubro de 2008

ShellCoding parte 3 > 3.2 Um novo debugger, um novo ponto de vista... o mesmo programa. > 3.3 A base dos Shellcodes

O que me levou ao ollydbg foi a sua simplicidade... eu sou mais familiarizado com outro debugger, o windbg.
Apesar dele ser “mais complexo”, foi o primeiro que eu aprendi a mexer por influencia de alguns amigos, uma ótima influência.

O ollydbg é bem simples, mas nós somos machos certo?*coça o saco*
Então vamos mostrar como somos machos e que não temos medo de cara/interface feia e vamos aprender a mexer um pouco no windbg =]
Eu não me sentiria bem se passasse esse tutorial todo sem pelo menos fazer um “overview” do windbg... e aqui está ele. 


O windbg é muito poderoso e é usado pelo próprio time de programadores da Microsoft entre outras coisas, para desenvolver o Windows!

Sim, ele permite a depuração de drivers e afins.

Algumas afirmações que eu fiz para vocês, foram bem mastigadas, muito mesmo.
Agora vamos usar esse debugger poderoso para complementar essas informações.

Ele é gratuito e você não terá que gastar nenhum centavo, apenas alguns minutos fazendo o download do pacote de debugging da Microsoft.
Onde encontrá-lo?
Aqui:
http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx

Escolha a instalação com base na versão do SO que você tem(32 ou 64 bits).
Instale.

O pacote vem com entre outros aplicativos, o logger que é usado para identificar quais APIs um programa está usando, logview utilizado para visualizar os logs gerados pelo logger.exe ,KD que é um kernel debbuger e etc... por último mas não menos importante o windbg, o pacote também vem com outros debuggers user-mode application como o CDB mas não entraremos em detalhes. 




Agora, abra o windbg na pasta que você instalou o pacote de debugging tools for Windows.
Você vai ter uma tela meio feinha de começo com somente a command bar à mostra.

O que você vai fazer é pressionar “CTRL + E” e abrir aquele assembly program que nós debugamos com o olly, se lembra?

Imediatamente ele nos mostra os módulos carregados e o estado dos registradores.(módulo é de certa forma só um outro nome para image file names(nome das “imagens” de arquivos /carregados/)



Existe um módulo em especial que sempre será carregado, é a DLL Kernel32.
Todos os programas que você tentar debuggar verá que essa DLL está presente.

Você quer saber por que isso te interessa?

Quando um processo é iniciado, o Windows cria um tipo de “header” para o processo.
Esse header se chama PEB(process enviroment block)¹.
Nele estão contidas todas as informações de um processo, inclusive os módulos carregados por ordem de loading.

Para nós, o conhecimento desse bloco é importante pois no Windows, nossos exploits precisam chamar APIs diferentemente de sistemas nix like que podemos chamar diretamente sys calls que estão sempre paradinhas la esperando por você, no entanto nós nem sempre sabemos o endereço em que uma DLL foi carregada e queremos que nosso exploit chame uma função da user32 por exemplo, o que fazemos?!

Bem como o kernel32 é sempre carregado e é um dos primeiros módulos carregados, ele está sempre no mesmo lugar dentro do PEB de um processo.

E esse módulo tem duas APIs importantíssimas para podermos usar qualquer uma que quisermos... São as LoadLibrary* e GetProcessAdress* que respectivamente carregam um módulo e pegam o endereço de uma API contida nele.

Mas você ainda não vai construir um exploit agora... só que a partir de agora, as informações que antes eu disse que foram “filtradas/mastigadas” não serão mais tão mastigadas, então se prepare para uma enxurrada controlada de nomes estranhos aparecendo na sua tela. =P

¹:http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/PEB.html



Voltemos ao Windbg com nosso tuto.exe carregado, aperte “ALT + F7” para ver o disassembly.
E repare em uma coisa, nós estamos antes mesmo do programa começar, esse não é o código do nosso processo!
Então cadê ele?

O Windows ainda está por chamar o nosso programa mas se quisermos encontrar aonde começa o código dele é simples... vamos encontrar o entry point do módulo tuto.exe.

Entry point é basicamente aonde o código do programa começa, ele denota a parte do image file para o qual nós iremos dar um long jump, ou seja, a primeira função executada de um determinado processo.
Hoje em dia é normal que os programas só tenham um entry point, por exemplo o int WinMain() que nós vemos todo dia em nossos programas win app C++/C.

Image File ou imagem do arquivo, é a imagem que é criada na memória de um determinado arquivo.
Quando você executa um determinado programa, por exemplo, o nosso tuto.exe, o Windows copia ele todo para a memória, essa cópia ganha o nome de image file.

Mas não para por ai, não pense que memória é sinônimo de memória RAM física não.

Cada processo tem uma determinada quantidade de memória que é chamada de memória virtual.
Essa memória virtual é endereçável(lógico) mas o seu endereço é relativo, ou seja, nem sempre corresponde ao endereço REAL na memória física.
Isso quer dizer que uma variável de um programa pode estar claramente no endereço 0x0012ffaa, outro programa ter uma variável no mesmo endereço e no entanto, elas podem sim ter valores diferentes... isso porque os processos(normalmente) não compartilham sua memória virtual com outros, eles podem ter claramente o mesmo endereço virtual, sendo que o endereço virtual é mapeado(transformado) para um físico no momento de execução do processo.
Cada processo pode ter até 2GB de memória virtual, mas nem toda ela é alocável, parte é reservada pelo sistema e os endereços vão de 0x00000000e16 à 0x7FFFFFFFe16.(‘e16’ é notação científica)

Lembra-se que eu disse que a stack poderia chegar ao endereço 0x00 e o sistema falaria que falta memória?
 Aquilo ajudou a entender que a memória cresce do maior endereço para o menor, mas eu coloquei aquele “hipoteticamente falando” justamente porque isso não é possível, o endereço virtual 0x00 é reservado para o sistema e se sobrescrito possivelmente quebra o programa.
E sim, no win32 a stack faz parte da memória virtual de um processo e hoje em dia tem fronteiras bem definidas ao contrário das suas antigas versões.

O mundo era mais bonito quando o céu só podia ser azul não é?

Mas a vida real não é assim e as coisas são mais complicadas do que isso, então se concentre e não perca o foco porque eu ainda não comecei a parte mais complicada.




Aprendemos o que é o entry point, então vamos achá-lo?

O windbg vem com várias extensões muito úteis e vamos usar uma delas.
Na command bar digite “!dlls”.
Pronto!
Agora você está vendo informações específicas dos módulos carregados.



E está ai também o entry point do tuto.exe certo?
Então já sabemos seu endereço(401000), vamos colocar um breakpoint nesse endereço e mandar o windbg deixar o programa correr livre leve e solto até encontrar o que nós queremos.

Digite .cls para limpar a tela(so fresco mesmo =P)
Agora digite:
 
BP /1 401000 “.echo =============|| ENTRY POINT ||=================” [enter]


BP, seta um breakpoint.
/1 diz que assim que esse break point for executado uma vez, ele será deletado.
401000 é o endereço.
O que segue entre aspas é o comando que será executado quando esse breakpoint for encontrado.
No nosso caso, o echo vai exibir a string “...ENTRY P...” na tela.

Se aparecer o status “busy” ao lado da command bar, espere até o status voltar ao normal.

Agora digite ‘g’(sem aspas) que significa “oh baby, let’s Go” ou só “GO” se você preferir. =P

Ele vai rodar e vai para justamente aonde começa o nosso código tão conhecido. =]

(posteriormente você poderá substituir essa ação toda por "g @$exentry")

 

3.3 A base dos Shellcodes.


Novo capítulo, mas nós vamos continuar com aquele nosso debugger(windbg) e no ponto aonde paramos, mas desta vez, a idéia não é explicar o que vai acontecer com o programa e sim entender talvez o último ponto necessário para começarmos a construir nossos exploits.

Só para recapitular:



A primeira coisa que quero que você faça após encontrar o entry point de tuto.exe é apertar f10, o debugger vai dar uma “passo” a frente colocando 00000008 na stack.
Ok, isso nós já sabemos.
O windbg já mostra o estado dos registradores, a próxima instrução a ser executada e etc, normal.

Vamos agora fazer um dump ou seja, ver o valor que está em certo local da memória virtual do nosso processo.

A função ‘d’ do windbg é responsável por fazer o dump da memória virtual de um processo.
Ela funciona com diferentes tamanhos.
Por exemplo, se você escrever ‘db *endereço*’ ela vai te mostrar o dump hexadecimal em bytes(8 bits) do endereço desejado.

Bem, nós sabemos que esp aponta para o topo da stack certo?
Então como nós já sabemos que o 0~8 já deve estar na stack, vamos ver essa função em ação passando para ela o endereço que está em esp.

Digite ‘dd esp’ e logo você verá isso:
0012ffa0 00000008 76373833 7ffdd000 0012ffec
0012ffb0 77a5a9bd 7ffdd000 00129e72 00000000
0012ffc0 00000000 7ffdd000 00000000 00000000
0012ffd0 00000000 0012ffb8 00000000 ffffffff
0012ffe0 77a28bf2 77a69096 00000000 00000000
0012fff0 00000000 00401000 7ffdd000 00000000
00130000 78746341 00000020 00000001 00003008
00130010 000000dc 00000000 00000020 00000000

Percebe o 8 no topo?
Repare que dd faz ele exibir em Double words ou seja, de 32 em 32 bits ou 8 caracteres hexadecimais/4 bytes.

Repare também que ele exibe 5 colunas, a primeria é o endereço do valor da segunda coluna na memória vitual do processo.

Nós podemos obrigá-la a exibir apenas uma coluna, assim:

‘dd /c 1 esp’
Assim nós visualizaremos como se estivéssemos no ollydbg, de quatro em quatro bytes e seus respectivos endereços ao lado.

0012ffa0 00000008
0012ffa4 76373833
0012ffa8 7ffdd000
0012ffac 0012ffec
0012ffb0 77a5a9bd
0012ffb4 7ffdd000
0012ffb8 00129e72
0012ffbc 00000000
0012ffc0 00000000
0012ffc4 7ffdd000
0012ffc8 00000000
0012ffcc 00000000
0012ffd0 00000000
0012ffd4 0012ffb8
0012ffd8 00000000
0012ffdc ffffffff
0012ffe0 77a28bf2
0012ffe4 77a69096
0012ffe8 00000000
0012ffec 00000000
0012fff0 00000000
0012fff4 00401000
0012fff8 7ffdd000
0012fffc 00000000
00130000 78746341
00130004 00000020
00130008 00000001
0013000c 00003008
00130010 000000dc
00130014 00000000
00130018 00000020
0013001c 00000000

Nós podemos visualizar de byte em byte ao invés de 4 em 4 como antes.
Usando o db como foi dito antes e podemos ainda mais, podemos dizer apartir de qual endereço da memória nós queremos ver e até qual.
Assim:
‘db esp esp+3’
0:000> db esp esp+3
0012ffa0 08 00 00 00

Ou seja, ele vai exibir esp(12ffa0) até esp+3(12ffa43) em outras palavras ele vai exibir o 
12ffa0
12ffa1
12ffa2
12ffa3

Ou seja, um double Word(4 bytes) só que de byte em byte.

Agora, se lembra que eu falei que as instruções asm são representações para os opcodes¹ e que esses sim é que rodam e fazem algo?
Bem, o programa já foi compilado e esses opcodes já estão na memória virtual do processo, o disassembly só reconverte esses opcodes para código asm novamente o que não é nada difícil.

¹: tem um tuto mto bom que explica como são feitos, ele foi feito pelo alucard e está aqui>http://alucard.dxs.googlepages.com/Tutorial_OpCode.html

Bem, se esses opcodes estão no endereço em que vemos o disassembly, então nós podemos “ripalos”.
Ou seja, nós podemos ver quais são esses opcodes e colocar em outro programa.

Vamos dumpar todo o código do nosso tuto.exe.

Digite ‘dd 401000 40100b’

401000 é o endereço do entry point do nosso módulo como já vimos, e 40100b é o endereço da sua última instrução(ret).
A saída desse dump é:
00401000 ffb9086a 49ffffff c358fd75

A primeira coluna é um endereço como já sabemos e as 3 seguintes são o dump dessa área da memória.

Se lembra que nosso programa põe o 8 na stack e depois o coloca em eax?
Se lembra que eu também disse que eax é usado para retornar valores de funções.

Logo, imagine esse código:


int soma()
{
 int eax = 8, ecx = 0xFFFFFFFF;
 for(;ecx>0;ecx--);
 return eax;
}
 

Pois bem, o nosso programa é a completa representação desse código C.

Ele põe 8 na stack, cria um loop de 0xFFFFFFFF até 0x00(uma espécie de delay hardcoded) põe 8 em eax e ret retorna para o ponto aonde o processo chamador parou tirando da stack o endereço pra próxima instrução e colocando em eip, como eax é usado para retornar valores e resultados de funções então logo a nossa função retorna um número, o 8.

Bem, nós já temos os opcodes, que tal colocarmos ele em um programa e ver se roda? 

Bem, vamos primeiro visualizá-lo como um programa C completo:

#include  stdio.h


int soma()
{
  int eax = 8, ecx = 0xFFFFFFFF;

  for (;ecx > 0; ecx--);

  return eax;
}

int main()
{
  printf("Valor: %d", soma() );

}

Isso nós já sabemos né?

Então que tal colocarmos aqueles opcodes e ver se tem o mesmo resultado?

Vamos fazer isso, repare que temos 3 colunas de 4 bytes de dados.
4 bytes = int

Então vamos criar um array de 3 int’s e vamos forçar o nosso programa C a chamá-lo como se fosse uma função...

Primeiro vamos copiar essas 3 colunas de opcodes e transformar em um array de ints.

int OpCodes[] = {0xffb9086a, 0x49ffffff, 0xc358fd75};

Veja que eu coloco o ‘0x’ na frente para o compilador saber que são valores hexadecimais.

Agora que nós temos o tal array vamos forçar o compilador a chamá-lo como uma função que retornar um inteiro:

((int (*) ())OpCodes)()

 

Não se assuste, olhe por um lado, nós temos o array OpCodes.

Vamos usar um cast de uma função que retorna um inteiro n’ele:


( int (*)() ) <- esse é o cast

Envolvemos o cast e o endereço do primeiro elemento de Opcodes entre parênteses:

((int) (*) ()) OpCodes)

E agora que já o transformamos em uma função que retorna um inteiro, vamos chamar essa função:

((int) (*) ()) OpCodes) () 

Bem, vamos colocar isso tudo num printf para que ele exiba o valor 8:

#include stdio.h


int main()
{
  int OpCodes[] = {0xffb9086a, 0x49ffffff, 0xc358fd75};

  printf("Valor: %d", ((int (*) ())OpCodes)() );

}  

Vê?!

Alguns preferem fazer a mesma coisa só que com uma string.

Strings em C são simples arrays de bytes... isso significa que nós iremos ter que colocar um ‘\x’¹ para cada byte(2 dígitos hex), no final o resultado é o mesmo, a diferença é quem escreve mais:

#include


int main()
{
  int OpCodes[] = {0xffb9086a, 0x49ffffff, 0xc358fd75};

  char szOpCodes[] =
  "\x6a\x08\xb9\xff"
  "\xff\xff\xff\x49"
  "\x75\xfd\x58\xc3";


  printf("Valor: %d", ((int (*) ())szOpCodes)() );

}

Repare que eu só adicionei um ‘sz’² e troquei a ordem dos bytes.

Você já vai saber o porque dessa ordem trocada... mas por hoje é só, cya. =]


¹: indica que o próximo byte não deve ser interpretado como caracter
²: notação húngara indicando uma string terminada em zero.