Reunião de aprendizagem [fechada]

102

Decidi aprender a linguagem Assembly. A principal razão para fazer isso é ser capaz de entender o código desmontado e talvez ser capaz de escrever partes de código mais eficientes (por exemplo, através de c ++), fazendo coisas como cavernas de código, etc. Eu vi que existem zilhões de sabores diferentes de montagem , então, para os fins que menciono, como devo começar? Que tipo de montagem devo aprender? Quero aprender fazendo primeiro alguns programas fáceis (por exemplo, uma calculadora), mas o objetivo em si será me acostumar com isso para que eu possa entender o código mostrado, por exemplo, por IDA Pro.

Estou usando o windows (se isso faz alguma diferença).

editar: Então, parece que todo mundo está apontando para MASM. Embora eu tenha entendido que ele tem recursos de alto nível, todos bons para o programador de código assembly, não é isso que estou procurando. Parece ter instruções if, invoke, etc. não mostradas em desmontadores populares (como IDA). Portanto, o que eu gostaria de ouvir, se possível, é a opinião de qualquer pessoa que use o ASM para os propósitos que estou pedindo (lendo o código exe desmontado no IDA), não apenas de programadores de assembly "gerais".

editar: OK. Já estou aprendendo montagem. Estou aprendendo MASM, não usando coisas de alto nível que não importam para mim. O que estou fazendo agora é testar meu código nas diretivas __asm ​​em c ++, para que eu possa experimentar as coisas muito mais rápido do que se tivesse que fazer tudo do zero com MASM.

elísio devorado
fonte
Pergunta semelhante a stackoverflow.com/questions/1355524/…
TrueWill
Sim, eu estava lendo esse também. Mas minha pergunta é um pouco mais "focada", eu diria.
devorado elysium
Se você estiver no Windows, o destino (ou seja, o processador e, portanto, o conjunto de instruções) é x86 ou x86-64. A menos que você obtenha outra máquina ou uma placa MCU ou use um emulador. Então, a questão é qual assembler devo usar? Ou você está realmente perguntando qual arquitetura visar? Pessoalmente, adoro a bela instrução ortogonal definida nos chips da série m68k, infelizmente.
dmckee --- ex-moderador gatinho
2
"Parece ter instruções if, invoke, etc" - Essas são macros (o 'M' em "MASM") e você não precisa usá-las, mesmo que o montador as suporte.
ChrisW
3
Foi uma decisão difícil dar à pergunta seu 65º voto positivo, 64 é um número tão bonito. . .
735 Tsla

Respostas:

40

Comece com MASM32 e, a partir daí, examine o FASM . Mas você vai se divertir com MASM.

Seda do meio-dia
fonte
Já ouvi falar da MASM. Se não me engano, ele tem muitos recursos de "alto nível", que não vejo quando vejo o código desmontado. Eu gostaria de ter que programar em algo que seja exatamente como o código de saída da maioria dos desmontadores, se isso fizer sentido.
devorado elysium
1
Isso seria basicamente como escrever códigos operacionais, o que realmente não faz sentido. Aprender MASM32 ajudará você a entender a aparência do código em um depurador. Você também pode conferir OllyDbg: ollydbg.de
Noon Silk
7
Você não entende de montagem. Você precisa entender isso. Um opcode é um número. Os depuradores tentarão resolver os opcodes de acordo com suas instruções (às vezes é difícil). Você precisa entender as instruções básicas. Aprender MASM o ajudará a fazer isso. Nada mais precisa ser dito.
Noon Silk,
5
Você não precisa usar todos os recursos do MASM apenas porque eles estão lá; você pode tornar as coisas tão difíceis de ler quanto quiser, se achar que aprenderá mais dessa forma.
JasonTrue,
3
MASM, com suas peculiaridades, bugs e os chamados recursos de alto nível, fez mais para confundir os programadores de montagem - iniciantes e especialistas - mais do que qualquer coisa que eu possa imaginar.
IJ Kennedy
44

Já fiz isso muitas vezes e continuo fazendo. Neste caso, onde seu objetivo principal é ler e não escrever assembler, acho que isso se aplica.

Escreva seu próprio desmontador. Não com o propósito de fazer o próximo grande desmontador, este é estritamente para você. O objetivo é aprender o conjunto de instruções. Esteja eu aprendendo assembler em uma nova plataforma, lembrando-me de assembler para uma plataforma que conheci. Comece com apenas algumas linhas de código, adicionando registradores, por exemplo, e fazendo pingue-pongue entre desmontar a saída binária e adicionar mais e mais instruções complicadas no lado da entrada:

1) aprender o conjunto de instruções para o processador específico

2) aprender as nuances de como escrever código em montagem para o referido processador de modo que você possa mexer cada bit de opcode em cada instrução

3) você aprende o conjunto de instruções melhor do que a maioria dos engenheiros que usam esse conjunto de instruções para ganhar a vida

No seu caso, há alguns problemas, eu normalmente recomendo o conjunto de instruções ARM para começar, há mais produtos baseados em ARM vendidos hoje do que qualquer outro (computadores x86 incluídos). Mas a probabilidade de você estar usando o ARM agora e não conhecer o montador suficiente para escrever código de inicialização ou outras rotinas sabendo o ARM pode ou não ajudar no que você está tentando fazer. A segunda e mais importante razão para o ARM primeiro é porque os comprimentos das instruções são de tamanho fixo e alinhados. Desmontar instruções de comprimento variável como x86 pode ser um pesadelo como seu primeiro projeto, e o objetivo aqui é aprender o conjunto de instruções para não criar um projeto de pesquisa. O terceiro ARM é um conjunto de instruções bem executado, os registros são criados iguais e não possuem nuances especiais individuais.

Portanto, você terá que descobrir com qual processador deseja começar. Eu sugiro o msp430 ou ARM primeiro, depois o ARM primeiro ou segundo e então o caos do x86. Não importa a plataforma, qualquer plataforma que valha a pena usar tem planilhas de dados ou manuais de referência de programadores gratuitos do fornecedor que incluem o conjunto de instruções, bem como a codificação dos opcodes (os bits e bytes da linguagem de máquina). Com o propósito de aprender o que o compilador faz e como escrever código com o qual o compilador não precisa se esforçar, é bom conhecer alguns conjuntos de instruções e ver como o mesmo código de alto nível é implementado em cada conjunto de instruções com cada compilador com cada otimização configuração. Você não quer otimizar seu código apenas para descobrir que o tornou melhor para um compilador / plataforma, mas muito pior para todos os outros.

Oh, para desmontar conjuntos de instruções de comprimento variável, em vez de simplesmente começar do início e desmontar cada palavra de quatro bytes linearmente através da memória como faria com o ARM ou a cada dois bytes como o msp430 (O msp430 tem instruções de comprimento variável, mas você ainda pode sobreviver passando linearmente pela memória se você começar nos pontos de entrada da tabela de vetores de interrupção). Para comprimento variável, você deseja encontrar um ponto de entrada com base em uma tabela de vetores ou conhecimento sobre como o processador inicializa e seguir o código na ordem de execução. Você tem que decodificar cada instrução completamente para saber quantos bytes são usados, então se a instrução não for um desvio incondicional, assuma que o próximo byte após essa instrução é outra instrução. Você também deve armazenar todos os endereços de ramificação possíveis e assumir que esses são os endereços de byte iniciais para obter mais instruções. A única vez que tive sucesso, fiz várias passagens pelo binário. Começando no ponto de entrada, marquei aquele byte como o início de uma instrução e então decodifiquei linearmente através da memória até atingir um desvio incondicional. Todos os alvos de ramificação foram marcados como endereços iniciais de uma instrução. Fiz várias passagens pelo binário até não encontrar nenhum novo destino de ramificação. Se a qualquer momento você encontrar, digamos, uma instrução de 3 bytes, mas por alguma razão você marcou o segundo byte como o início de uma instrução, você tem um problema. Se o código foi gerado por um compilador de alto nível, isso não deve acontecer a menos que o compilador esteja fazendo algo mal, se o código tiver um assembler escrito à mão (como, digamos, um antigo jogo de arcade), é bem possível que haja desvios condicionais que nunca podem acontecer como r0 = 0 seguido por um salto, senão zero. Você pode ter que editar manualmente aqueles fora do binário para continuar. Para seus objetivos imediatos, que suponho que serão em x86, não acho que você terá problemas.

Eu recomendo as ferramentas gcc, mingw32 é uma maneira fácil de usar as ferramentas gcc no Windows se x86 for seu destino. Senão, o mingw32 plus msys é uma plataforma excelente para gerar um compilador cruzado a partir de fontes binutils e gcc (geralmente muito fácil). mingw32 tem algumas vantagens sobre o cygwin, como programas significativamente mais rápidos e você evita o inferno do cygwin dll. gcc e binutils permitirão que você escreva em C ou assembler e desmonte seu código e há mais páginas da web do que você pode ler, mostrando como fazer qualquer um ou todos os três. Se você vai fazer isso com um conjunto de instruções de comprimento variável, eu recomendo fortemente que você use um conjunto de ferramentas que inclui um desmontador. Um desmontador de terceiros para x86, por exemplo, será um desafio de usar, pois você nunca sabe realmente se ele foi desmontado corretamente. Parte disso também depende do sistema operacional; o objetivo é compilar os módulos em um formato binário que contenha instruções de marcação de informações dos dados para que o desmontador possa fazer um trabalho mais preciso. Sua outra escolha para esse objetivo principal é ter uma ferramenta que possa compilar diretamente no assembler para sua inspeção e, em seguida, esperar que, ao compilar para um formato binário, crie as mesmas instruções.

A resposta curta (ok, ligeiramente mais curta) para sua pergunta. Escreva um desmontador para aprender um conjunto de instruções. Eu começaria com algo RISCy e fácil de aprender como o ARM. Uma vez que você conhece um conjunto de instruções, outros se tornam muito mais fáceis de entender, geralmente em poucas horas, no terceiro conjunto de instruções, você pode começar a escrever código quase imediatamente usando a folha de dados / manual de referência para a sintaxe. Todos os processadores que valem a pena usar têm uma folha de dados ou manual de referência que descreve as instruções até os bits e bytes dos opcodes. Aprenda um processador RISC como ARM e um CISC como x86 o suficiente para sentir as diferenças, coisas como ter que passar por registros para tudo ou ser capaz de executar operações diretamente na memória com menos ou nenhum registro. Instruções de três operandos versus dois, etc. Conforme você ajusta seu código de alto nível, compilar para mais de um processador e comparar a saída. A coisa mais importante que você aprenderá é que não importa quão bom o código de alto nível seja escrito, a qualidade do compilador e as escolhas de otimização feitas fazem uma grande diferença nas instruções reais. Eu recomendo llvm e gcc (com binutils), nenhum produtoótimo código, mas eles são multiplataformas e alvos múltiplos e ambos têm otimizadores. E ambos são gratuitos e você pode construir compiladores cruzados facilmente a partir de fontes para vários processadores de destino.

old_timer
fonte
Obrigado pela resposta. Mas eu nem sei escrever um desmontador.
devorado elysium
8
"Escreva seu próprio desmontador" - concordo, é como eu o aprendi melhor. (O que há com "Mas eu nem sei escrever um desmontador"?) LOL.
slashmais de
Eu estou indo com você! Acabei de comprar um MSP430 e um livro sobre ele ... :)
Pepe
1
Eu tenho alguns exemplos msp430 github.com/dwelch67 além de alguns simuladores de conjunto de instruções para experimentar, incluindo conjunto de aprendizagem, etc.
old_timer
Eu realmente gosto dessa ideia.
Millie Smith
33

A montagem que você escreveria à mão e a montagem gerada por um compilador costumam ser muito diferentes quando vistas de um alto nível. É claro que as entranhas do programa serão muito semelhantes ( a = b + cafinal, existem apenas tantas maneiras diferentes de codificar ), mas eles não são o problema quando você está tentando fazer a engenharia reversa de algo. O compilador irá adicionar uma tonelada de código clichê até mesmo para executáveis ​​simples: da última vez que comparei, "Hello World" compilado pelo GCC tinha cerca de 4kB, enquanto se escrito à mão em assembly tem cerca de 100 bytes. É pior no Windows: a última vez que comparei (na verdade, isso foi no século passado) o menor "Hello World" que consegui gerar com meu compilador do Windows da época era 52kB! Normalmente, esse clichê é executado apenas uma vez, se é que é executado, então não afeta muito a velocidade do programa - como eu disse acima, o núcleo do programa, a parte onde a maior parte do tempo de execução é gasto, geralmente é muito semelhante, seja compilado ou escrito à mão.

No final das contas, isso significa que um programador de montagem especialista e um desmontador especialista são duas especialidades diferentes. Normalmente, eles são encontrados na mesma pessoa, mas são realmente separados, e aprender a ser um excelente programador de montagem não ajudará muito a aprender a engenharia reversa.

O que você quer fazer é pegar os manuais de arquitetura IA-32 e AMD64 (ambos são cobertos juntos) da Intel e AMD e olhar as primeiras seções sobre instruções e opcodes. Talvez leia um tutorial ou dois sobre a linguagem assembly, apenas para obter os fundamentos da linguagem assembly. Então pegue um pequenoprograma de amostra no qual você está interessado e desmontá-lo: percorra seu fluxo de controle e tente entender o que ele está fazendo. Veja se você pode consertá-lo para fazer outra coisa. Em seguida, tente novamente com outro programa e repita até se sentir confortável o suficiente para tentar alcançar um objetivo mais útil. Você pode se interessar por coisas como "crackmes", produzidos pela comunidade de engenharia reversa, que são desafios para pessoas interessadas em fazer engenharia reversa e, com sorte, aprender algo ao longo do caminho. Eles variam em dificuldade do básico (comece aqui!) Ao impossível.

Acima de tudo, você só precisa praticar . Como em muitas outras disciplinas, com a engenharia reversa, a prática leva à perfeição ... ou pelo menos melhor .

Kquinn
fonte
Eu sei que quando você compila qualquer coisa com uma linguagem de alto nível, você obterá muito código "lixo" que não seria necessário se fosse codificado diretamente em assembly. Eu também entendo que há uma diferença entre um programador de montagem especialista e um desmontador especialista. Mas o mesmo pode ser dito sobre quase tudo o mais.
devorado elysium
3
Minha preocupação é que, embora em teoria eu pudesse ler os jornais e entender o que eles significam, até que eu mesmo comece a escrever coisas, não acredito que realmente entenderei. Você diz que posso começar alterando pequenas partes do código, mas, para fazer isso, primeiro preciso saber que tipo de assembly "sabor" IDA pro, por exemplo, usa.
devorado elysium
Além disso, o que o MSVC ++ usa para o código de montagem embutido? MASM?
devorou ​​elysium
15

Vou contra a tendência da maioria das respostas e recomendo a variante MMIX de Knuth da arquitetura MIPS RISC. Não será tão útil quanto as linguagens de montagem x86 ou ARM (não que elas sejam tão cruciais na maioria dos trabalhos da vida real hoje em dia ... ;-), mas IRÁ desbloquear para você a magia da última versão de Knuth versão da maior obra-prima de todos os tempos sobre compreensão de baixo nível de algoritmos e estruturas de dados - TAOCP , "The Art of Computer Programming". Os links dos dois URLs que citei são uma ótima maneira de começar a explorar essa possibilidade!

Alex Martelli
fonte
12

(Eu não sei sobre você, mas eu estava animado com a montagem)

Uma ferramenta simples para experimentar a montagem já está instalada no seu pc.

Vá para o menu Iniciar-> Executar e digitedebug

depurar (comando)

debug é um comando no DOS, MS-DOS, OS / 2 e Microsoft Windows (somente versões x86, não x64) que executa o programa debug.exe (ou DEBUG.COM em versões anteriores do DOS). O Debug pode atuar como um programa assembler, disassembler ou hex dump, permitindo aos usuários examinar interativamente o conteúdo da memória (em linguagem assembly, hexadecimal ou ASCII), fazer alterações e executar seletivamente COM, EXE e outros tipos de arquivo. Ele também possui vários subcomandos que são usados ​​para acessar setores específicos do disco, portas de E / S e endereços de memória. O MS-DOS Debug é executado em um nível de processo de 16 bits e, portanto, é limitado a programas de computador de 16 bits . O FreeDOS Debug tem uma versão "DEBUGX" que também suporta programas DPMI de 32 bits.

Tutoriais:


Se quiser entender o código que vê no IDA Pro (ou OllyDbg ), você precisará aprender como o código compilado é estruturado. Eu recomendo o livro Reversing: Secrets of Reverse Engineering

Experimentei algumas semanas com debugquando comecei a aprender montagem (15 anos atrás).
Observe que debugfunciona no nível da máquina básica, não há comandos de montagem de alto nível.

E agora um exemplo simples:

apara começar a escrever código assembly - digite o programa abaixo - e finalmente dê gpara executá-lo.

texto alternativo


( INT 21exibe na tela o caractere ASCII armazenado no DLregistro se o AHregistro estiver definido para 2- INT 20termina o programa)

Nick Dandoulakis
fonte
Tive que apertar ctrl-c antes de inserir "g".
ericp
2
@ericp, você não precisa apertar ctrl-c. Por exemplo, você digita a& [enter] para começar a escrever o código assembly. Se você pressionar [Enter] duas vezes, você sairá do modo de montagem. g& [enter] para executá-lo (deslocamento 100 por padrão).
Nick Dandoulakis
isso realmente causa um estouro de pilha ou apenas grava na tela?
Janus Troelsen
1
@user, basta escrever o nome deste site :-)
Nick Dandoulakis
@JanusTroelsen esses números (53, 74, 61, etc) são os códigos ASCII para 'S' 't' 'a' ... Cada chamada Int21 está imprimindo um caractere por vez! É por isso que a montagem NÃO é mais rápida :)
doug65536
8

Achei Hacking: The Art of Exploitation uma maneira interessante e útil de abordar este tópico ... não posso dizer que já usei o conhecimento diretamente, mas não foi exatamente por isso que o li. Ele fornece uma apreciação muito mais rica das instruções para as quais seu código é compilado, o que ocasionalmente tem sido útil para entender bugs mais sutis.

Não desanime pelo título. A maior parte da primeira parte do livro é "Hacking" no sentido de Eric Raymond da palavra: maneiras criativas, surpreendentes, quase furtivas de resolver problemas difíceis. Eu (e talvez você) estava muito menos interessado nos aspectos de segurança.

mblackwell8
fonte
7

Eu não me concentraria em tentar escrever programas em assembly, pelo menos não no início. Se você estiver no x86 (o que eu presumo que esteja, já que está usando o Windows), existem toneladas de casos especiais estranhos que é inútil aprender. Por exemplo, muitas instruções assumem que você está operando em um registro que você não nomeia explicitamente, e outras instruções funcionam em alguns registros, mas não em outros.

Gostaria de aprender apenas o suficiente sobre a arquitetura pretendida para que você entenda o básico e, em seguida, comece imediatamente e tente entender a saída de seu compilador. Arme-se com os manuais da Intel e mergulhe direto na produção do seu compilador. Isole o código de interesse em uma pequena função, para que você possa ter certeza de entender a coisa toda.

Eu consideraria o básico como:

  • registradores: quantos são, quais são seus nomes e quais são seus tamanhos?
  • ordem do operando: add eax, ebxsignifica "Adicionar ebx a eax e armazenar o resultado em eax".
  • FPU: aprenda o básico da pilha de ponto flutuante e como converter de / para fp.
  • modos de endereçamento: [base + deslocamento * multiplicador], mas o multiplicador só pode ser 1, 2 ou 4 (ou talvez 8?)
  • convenções de chamada: como os parâmetros são passados ​​para uma função?

Muitas vezes será surpreendente o que o compilador emite. Faça um quebra-cabeça de descobrir por que diabos o compilador achou que isso seria uma boa ideia. Isso vai te ensinar muito.

Provavelmente também ajudará a se armar com os manuais da Agner Fog , especialmente o que lista de instruções. Ele dirá aproximadamente o quanto cada instrução é cara, embora seja mais difícil de quantificar diretamente nos processadores modernos. Mas ajudará a explicar por que, por exemplo, o compilador sai tão longe de seu caminho para evitar a emissão de uma idivinstrução.

Meu único outro conselho é sempre usar a sintaxe Intel em vez da AT&T quando você tiver escolha. Eu costumava ser bastante neutro nesse ponto, até o dia em que percebi que algumas instruções são totalmente diferentes entre as duas (por exemplo, movslqna sintaxe da AT&T é movsxdna sintaxe da Intel). Uma vez que os manuais são escritos usando a sintaxe Intel, continue com ela.

Boa sorte!

Josh Haberman
fonte
3

Comecei aprendendo MIPS, que é uma arquitetura de 32 bits muito compacta. É um conjunto de instruções reduzido, mas é o que torna mais fácil de entender para os iniciantes. Você ainda será capaz de entender como a montagem funciona sem ficar sobrecarregado com a complexidade. Você pode até baixar um pequeno IDE legal, que permitirá que você compile seu código MIPS: clicky Depois de pegar o jeito, acho que seria muito mais fácil passar para arquiteturas mais complexas. Pelo menos foi o que pensei :) Neste ponto, você terá o conhecimento essencial de alocação e gerenciamento de memória, fluxo lógico, depuração, teste e etc.


fonte
3

A sugestão de usar o debug é divertida, muitos truques interessantes podem ser feitos com isso. No entanto, para um sistema operacional moderno, aprender o assembly de 16 bits pode ser um pouco menos útil. Considere, em vez disso, usar ntsd.exe. Ele está integrado ao Windows XP (ele foi puxado no Server 2003 e superior, infelizmente), o que o torna uma ferramenta conveniente para aprender, já que está amplamente disponível.

Dito isso, a versão original do XP apresenta vários bugs. Se você realmente deseja usá-lo (ou cdb ou windbg, que são interfaces essencialmente diferentes com a mesma sintaxe de comando e back-end de depuração), você deve instalar o pacote de ferramentas de depuração gratuito do Windows .

O arquivo debugger.chm incluído nesse pacote é especialmente útil ao tentar descobrir a sintaxe incomum.

A melhor coisa sobre o ntsd é que você pode colocá-lo em qualquer máquina XP que estiver perto e usá-lo para montar ou desmontar. É uma ferramenta de aprendizado de montagem / great / X86. Por exemplo (usando cdb, já que está embutido no prompt do DOS, de outra forma é idêntico):

(erros de símbolo ignorados, pois são irrelevantes - também, espero que a formatação funcione, esta é minha primeira postagem)

C:\Documents and Settings\User>cdb calc

Microsoft (R) Windows Debugger Version 6.10.0003.233 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: calc
Symbol search path is: *** Invalid ***
Executable search path is:
ModLoad: 01000000 0101f000   calc.exe
ModLoad: 7c900000 7c9b2000   ntdll.dll
ModLoad: 7c800000 7c8f6000   C:\WINDOWS\system32\kernel32.dll
ModLoad: 7c9c0000 7d1d7000   C:\WINDOWS\system32\SHELL32.dll
ModLoad: 77dd0000 77e6b000   C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f02000   C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77fe0000 77ff1000   C:\WINDOWS\system32\Secur32.dll
ModLoad: 77f10000 77f59000   C:\WINDOWS\system32\GDI32.dll
ModLoad: 7e410000 7e4a1000   C:\WINDOWS\system32\USER32.dll
ModLoad: 77c10000 77c68000   C:\WINDOWS\system32\msvcrt.dll
ModLoad: 77f60000 77fd6000   C:\WINDOWS\system32\SHLWAPI.dll
(f2c.208): Break instruction exception - code 80000003 (first chance)
eax=001a1eb4 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4
eip=7c90120e esp=0007fb20 ebp=0007fc94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
ntdll!DbgBreakPoint:
7c90120e cc              int     3
0:000> r eax
eax=001a1eb4
0:000> r eax=0
0:000> a eip
7c90120e add eax,0x100
7c901213
0:000> u eip
ntdll!DbgBreakPoint:
7c90120e 0500010000      add     eax,100h
7c901213 c3              ret
7c901214 8bff            mov     edi,edi
7c901216 8b442404        mov     eax,dword ptr [esp+4]
7c90121a cc              int     3
7c90121b c20400          ret     4
ntdll!NtCurrentTeb:
7c90121e 64a118000000    mov     eax,dword ptr fs:[00000018h]
7c901224 c3              ret
0:000> t
eax=00000100 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4
eip=7c901213 esp=0007fb20 ebp=0007fc94 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
ntdll!DbgUserBreakPoint+0x1:
7c901213 c3              ret
0:000>`

Além disso - enquanto estiver jogando com o IDA, certifique-se de verificar o IDA Pro Book de Chris Eagle (desvinculado, pois StackOverflow não quer me deixar postar mais de dois links para meu primeiro post). É sem dúvida a melhor referência que existe.

Jordânia
fonte
1
1 para o livro de Chris Eagle. Tenho que colocar um pouco de amor lá para o Sk3wl de r00t;)
mrduclaw
3

Recentemente, tive uma aula de sistemas de computador. Um dos tópicos foi a montagem como ferramenta de comunicação com o hardware.

Para mim, o conhecimento de montagem não estaria completo sem entender os detalhes de como funcionam os sistemas de computador. Entender isso traz uma nova compreensão de por que as instruções de montagem em uma arquitetura de processador são ótimas, mas são terríveis em outra arquitetura.

Diante disso, estou inclinado a recomendar meu livro de aula:

Sistemas de computador: a perspectiva de um programador .

Sistemas de computador: a perspectiva de um programador
(fonte: cmu.edu )

Ele cobre o assembly x86, mas o livro é muito mais amplo do que isso. Ele cobre o revestimento do processador e a memória como cache, o sistema de memória virtual e muito mais. Tudo isso pode afetar como a montagem pode ser otimizada para os recursos fornecidos.

Frank v
fonte
2

Eu acho que você quer aprender os mnemônicos do opcode ASCII-ized (e seus parâmetros), que são produzidos por um desmontador e que são compreendidos por (podem ser usados ​​como entrada para) um montador.

Qualquer montador (por exemplo, MASM) faria.

E / ou talvez seja melhor você ler um livro sobre isso (há livros recomendados sobre o SO, não me lembro quais).

ChrisW
fonte
2

Você está fazendo outro trabalho de desenvolvimento no Windows? Em qual IDE? Se for VS, não há necessidade de um IDE adicional apenas para ler o código desmontado: depure seu aplicativo (ou anexe a um aplicativo externo) e abra a janela de desmontagem (nas configurações padrão, Alt + 8). Avance e observe a memória / registros como faria com o código normal. Você também pode querer manter uma janela de registros aberta (Alt + 5 por padrão).

A Intel oferece manuais gratuitos , que fornecem tanto uma visão geral da arquitetura básica (registros, unidades de processador, etc.) quanto uma referência completa de instruções. Conforme a arquitetura amadurece e fica mais complexa, os manuais de 'arquitetura básica' ficam cada vez menos legíveis. Se você conseguir obter uma versão mais antiga, provavelmente terá um lugar melhor para começar (mesmo os manuais P3 - eles explicam melhor o mesmo ambiente básico de execução).

Se você deseja investir em um livro, aqui está um bom texto introdutório. Pesquise na Amazon por 'x86' e você obterá muitos outros. Você pode obter várias outras direções de outra pergunta aqui .

Finalmente, você pode se beneficiar bastante de ler alguns baixo - nível blogs. Esses bits de informação de tamanho de byte funcionam melhor para mim, pessoalmente.

Ofek Shilon
fonte
2

Isso não o ajudará necessariamente a escrever um código eficiente!

Os códigos op i86 são mais ou menos um formato "legado" que persiste devido ao grande volume de código e binários executáveis ​​para Windows e Linux que existem.

É um pouco como os antigos estudiosos que escreviam em latim, um falante de italiano como Galileu escreveria em latim e seu artigo poderia ser compreendido por um falante de polonês como Copérnico. Essa ainda era a maneira mais eficaz de se comunicar, embora niether fosse particularmente bom em latim, e o latim é uma linguagem ruim para expressar ideias matemáticas.

Portanto, os compiladores geram código x86 por padrão e os chips modernos lêem os códigos op anteriores e transalam o que veem em instruções risc paralelas, com execução reordenada, execução especulativa, pipelining etc., além de fazerem uso total dos registros 32 ou 64 do processador realmente tem (ao contrário do patético 8 que você vê nas instruções x86).

Agora, todos os compiladores de otimização sabem que isso é o que realmente acontece, então eles codificam sequências de códigos OP que eles sabem que o chip pode otimizar com eficiência - embora algumas dessas sequências parecessem ineficientes para um programador de .asm por volta de 1990.

Em algum ponto, você precisa aceitar que os 10s de milhares de anos de trabalho que os redatores de compiladores fizeram valeram a pena, e confie neles.

A maneira mais simples e fácil de obter um tempo de execução mais eficiente é comprar o compilador Intel C / C ++. Eles têm um nicho de mercado para compiladores efficeint e têm a vantagem de poder perguntar aos designers de chips o que se passa lá dentro.

James Anderson
fonte
Sua história sugere que os processadores CISC se tornaram internamente processadores RISC. Posso ter entendido mal, mas isso simplesmente não é verdade. E o patético 8? Os processadores modernos (digamos, desde 1999) incluem muitos mais: 10 gpr: EAX-EFLAGS, 80 bits FP0-FP7, 64 bits MMX0-MMX7, 128 bits XMM0-XMM7, segmento: CS-GS, especiais: CR0-CR4 , DR0-DR7, TR3-TR7, GDTR, IDTR, LDTR, MSRs e em x86-64 também R8-R15. Nem todos eles são acessíveis a partir do ring-3, mas a maioria é e é usada por compiladores GCC / VC ++ recentes (pós-2006). Ao todo, um pouco mais do que o "8 patético";).
Abel,
2

Para fazer o que você quer fazer, peguei apenas a Referência do conjunto de instruções da Intel (pode não ser exatamente a que usei, mas parece suficiente) e alguns programas simples que escrevi no Visual Studio e comecei a colocá-los no IDAPro / Windbg . Quando eu desenvolvi meus próprios programas, o software da crackmes foi útil.

Presumo que você tenha algum conhecimento básico de como os programas são executados no Windows. Mas, realmente, para ler o assembly, há apenas algumas instruções para aprender e alguns sabores dessas instruções (por exemplo, há uma instrução de salto, salto tem alguns sabores como salto-se-igual, salto-se-ecx-for-zero , etc). Depois de aprender as instruções básicas, é muito simples obter a essência da execução do programa. A visualização do gráfico do IDA ajuda, e se você estiver rastreando o programa com o Windbg, é muito simples descobrir o que as instruções estão fazendo se você não tiver certeza.

Depois de jogar um pouco assim, comprei Hacker Disassembly Uncovered . Geralmente, eu evito livros com a palavra "Hacker" no título, mas eu realmente gostei de como este foi realmente aprofundado sobre como o código compilado parecia desmontado. Ele também analisa as otimizações do compilador e algumas coisas interessantes sobre eficiência.

Na verdade, tudo depende de quão profundamente você deseja compreender o programa também. Se você estiver fazendo engenharia reversa de um alvo em busca de vulnerabilidades, se estiver escrevendo código de exploração ou analisando malwares compactados em busca de recursos, precisará de mais tempo de aceleração para realmente fazer as coisas funcionarem (especialmente para o malware mais avançado ) Por outro lado, se você quer apenas ser capaz de mudar o nível do seu personagem no seu videogame favorito, você deve estar bem em um período de tempo relativamente curto.

Mrduclaw
fonte
1

Uma das linguagens de montagem pedagógicas padrão que existe é o MIPS. Você pode obter simuladores MIPS (spim) e vários materiais de ensino para isso.

Pessoalmente, não sou fã. Eu gosto bastante do IA32.

Paul Nathan
fonte
MIPS é bom. 68000 também, e se você aprender 68000, poderá escrever binários que rodam em MAME. :-)
Nosredna,
1

Meu favorito pessoal é NASM, principalmente porque é multiplataforma, e compila MMX, SSE, 64 bits ...

Comecei a compilar alguns arquivos-fonte C simples com gcc e "trans-codificar" a instrução assembler do formato gcc para o formato NASM. Em seguida, você pode alterar pequenas partes do código e verificar a melhoria de desempenho que ele traz.

A documentação do NASM é realmente completa, nunca precisei buscar informações em livros ou outras fontes.

GB
fonte
0

Muitas respostas boas aqui. Programação de baixo nível, montagem, etc. são populares na comunidade de segurança, portanto, vale a pena procurar dicas e sugestões lá quando você começar. Eles até têm alguns bons tutoriais como este sobre montagem x86 .

Brian Lyttle
fonte
0

Para realmente atingir seu objetivo, você pode considerar começar com o IDE em que está. A janela geralmente é um desmontador, então você pode fazer uma única etapa no código. Geralmente há algum tipo de visualização que permite ver os registros e examinar as áreas da memória.

O exame de código c / c ++ não otimizado ajudará a construir um link para o tipo de código que o compilador gera para suas fontes. Alguns compiladores possuem algum tipo de palavra reservada ASM que permite inserir instruções de máquina em seu código.

Meu conselho seria brincar um pouco com esse tipo de ferramenta, molhar os pés e depois subir? baixa? para código assembler direto em qualquer plataforma em que você está executando.

Existem muitas ferramentas excelentes por aí, mas você pode achar mais divertido evitar a curva de aprendizado íngreme no início.

EvilTeach
fonte
0

Aprendemos a montagem com um kit de desenvolvimento de microcontrolador (Motorola HC12) e uma folha de dados espessa.

ti
fonte
0

Eu sei, fora do assunto, mas como você é um programador do Windows, não posso deixar de pensar que pode ser um uso mais apropriado e / ou melhor do seu tempo para aprender MSIL. Não, não é montagem, mas provavelmente é mais relevante nesta era do .NET.

slf
fonte
0

Saber o assembly pode ser útil para depuração, mas eu não ficaria muito animado em usá-lo para otimizar seu código. Compiladores modernos geralmente são muito melhores em otimizar que um ser humano atualmente.

Adam Pierce
fonte
Hmm. Você ainda pode extrair um pouco mais de montagem de codificação, mas é mais trabalhoso vencer o compilador do que antes.
Nosredna,
0

Você pode conferir o curso em vídeo xorpd x86 Assembly . (Eu escrevi). O curso em si é pago, mas os exercícios são de código aberto, no github. Se você tem alguma experiência em programação, acho que deveria ser capaz de trabalhar apenas com os exercícios e entender tudo.

Observe que o código é para a plataforma Windows e foi escrito usando o montador Fasm . O curso e os exercícios não contêm nenhuma construção de alto nível, no entanto, você pode usar o Fasm para criar macros muito complicadas, se quiser.

xorpd
fonte