Questão:
Qual é o propósito de 'mov edi, edi'?
Mellowcandle
2013-03-25 14:56:00 UTC
view on stackexchange narkive permalink

Vejo essa instrução no início de vários programas do Windows. Ela está copiando um registro para si mesmo, então basicamente, isso funciona como um nop . Qual é o propósito desta instrução?

The Essence: É um NOP de dois bytes. Portanto, você pode corrigir dois bytes atomicamente sem que o processador carregue uma instrução incompleta / incorreta quando ele tentar executar esta parte do código enquanto você o altera.
Em x86-64 `mov edi, edi` não é um NOP. Em x86-64, zera os 32 bits principais de `rdi`. No código de 32 bits `mov edi, edi` pode ser usado como um NOP.
Trzy respostas:
QAZ
2013-03-25 15:03:13 UTC
view on stackexchange narkive permalink

Raymond Chen (Microsoft) tem uma postagem no blog discutindo isso em detalhes:

https://devblogs.microsoft.com/oldnewthing/20110921-00/?p=9583> / p>

Você provavelmente deve adicionar uma nota sobre os 5 bytes vazios que precedem a instrução `mov edi, edi`.
Por que não um NOP de 2 bytes real como `66 90`? Isso seria mais eficiente: nenhum uop de back-end necessário, nenhuma latência extra para EDI (no caso de ser importante), nenhum registro físico necessário para renomear a saída. Talvez seja uma "assinatura" que as ferramentas podem reconhecer como não ocorrendo naturalmente, exceto no código de hotpatch?
@PeterCordes: Raymond Chen discute que https://devblogs.microsoft.com/oldnewthing/20130102-00/?p=5663 "a decisão de usar MOV EDI, EDI como a instrução NOP de dois bytes veio após consultar os fabricantes de CPU para seus recomendações para o melhor NOP de dois bytes "
@BenSchwehn: Huh, provavelmente essa decisão remonta aos dias do Pentium P5, onde um prefixo `66` fez a instrução levar um ciclo extra para decodificar. É lamentável para CPUs posteriores do P6 em diante. Também é lamentável que tenha que ser um NOP, ao invés de ser opcionalmente uma instrução útil como uma codificação de 2 bytes de `push ebp` para funções que usam um ponteiro de quadro. (Usando a forma `push r / m32` com um byte modrm, não a forma abreviada de 1 byte.) Mas isso é um pouco menos simples de manusear e precisa de uma alternativa para não pessimizar funções que não querem empurrar nada.
peter ferrie
2013-03-30 03:59:49 UTC
view on stackexchange narkive permalink

A intenção é pular para um local específico , 5 bytes antes da instrução mov. A partir daí, você tem 5 bytes que devem ser modificados para um salto longo para algum outro lugar no espaço de memória de 32 bits. Observe que durante o hot-patching, esse salto de 5 bytes deve ser colocado primeiro e, em seguida, o mov pode ser substituído. Indo no sentido contrário, você corre o risco de o mov-jmp substituído rodar primeiro e pular para os 5 bytes de qualquer coisa que esteja lá (é tudo nops por padrão, mas você nunca sabe).

[adição a seguir ]

Em relação a escrever o salto de 5 bytes - há também o problema de haver apenas uma instrução que permitirá que você escreva mais de 4 bytes atomicamente - cmpxchg8b, e essa não é uma instrução ideal para o propósito. Se você escrever 0xe9 primeiro e depois um dword, terá uma condição de corrida se 0xe9 for executado antes de colocar o dword. Mais uma razão para escrever primeiro o salto em distância.

É NOPs ou INT3's, geralmente.
Certo, mas no caso dos INT3s, você definitivamente não quer executá-los por acidente.
E no caso da função * já * ter sido desviada, escrever o endereço de destino de salto de 4 bytes primeiro substituirá atomicamente qualquer `rel32` que o` jmp` anterior tinha. (Supondo que o dword esteja alinhado com 4 bytes, o que acontecerá se as funções estiverem alinhadas com 8 ou 16 bytes. Termina no início de uma função.)
rebel87
2015-10-03 12:54:27 UTC
view on stackexchange narkive permalink
Apresentação do

courtsey Hotpatching and the Rise ofThird-Party Patches no BlackHat USA 2006 por Alexander Sotirov

O que é Hotpatching? Hotpatching é um método para modificar o comportamento de um aplicativo, modificando seu código binário em tempo de execução. É uma técnica comum com muitos usos:

• depuração (pontos de interrupção de software)

• instrumentação em tempo de execução

• enganchando funções da API do Windows

• modificar a execução ou adicionar nova funcionalidade a aplicativos de código-fonte bloqueado

• implementar atualizações de software sem reinicializar

• corrigir vulnerabilidades de segurança

Hotpatches são gerados por uma ferramenta automatizada que compara os binários originais e os corrigidos. As funções que foram alteradas são incluídas em um arquivo com extensão .hp.dll. Quando a DLL de hotpatch é carregada em um processo em execução, a primeira instrução da função vulnerável é substituída por um salto para o hotpatch.

O A opção do compilador / hotpatch garante que a primeira instrução de cada função seja uma instrução mov edi, edi que pode ser sobrescrita com segurança pelo hotpatch. Versões mais antigas do Windows não são compiladas com esta opção e não podem ser hotpatched.



Estas perguntas e respostas foram traduzidas automaticamente do idioma inglês.O conteúdo original está disponível em stackexchange, que agradecemos pela licença cc by-sa 3.0 sob a qual é distribuído.
Loading...