Tentando não-op uma instrução
-
16-09-2019 - |
Pergunta
É possível usar ferramentas GNU (gcc, binutils, etc.) para modificar todas as ocorrências de uma instrução de montagem em um não-op? Especificamente, o gcc com a opção -pg gera o seguinte conjunto (ARM):
0x0: e1a0c00d mov ip, sp
0x4: e92dd800 stmdb sp!, {fp, ip, lr, pc}
0x8: e24cb004 sub fp, ip, #4 ; 0x4
0xc: ebfffffe bl 0 <mcount>
Eu quero gravar o endereço desta última instrução, e, em seguida, alterá-lo para um nop como no código a seguir
0x0: e1a0c00d mov ip, sp
0x4: e92dd800 stmdb sp!, {fp, ip, lr, pc}
0x8: e24cb004 sub fp, ip, #4 ; 0x4
0xc: e1a00000 nop (mov r0,r0)
O kernel Linux pode fazer algo semelhante a esta em tempo de execução, mas eu estou procurando uma solução em tempo de compilação.
Solução
Este será certamente mais fácil com um formato de instrução de comprimento fixo RISC-ish do que para por exemplo x86.
Deve ser relativamente simples de usar libelf (bom tutorial aqui: http : //people.freebsd.org/~jkoshy/download/libelf/article.html ) ou libbfd ( http://sourceware.org/binutils/docs-2.19/bfd/index.html ) para abrir o arquivo objeto, modificar instruções dentro da seção .text, e escrevê-lo novamente usando APIs fornecidas. Se vale a pena o esforço ou não vai depender de considerações não-técnicos (eu sou um curioso embora pouco ...).
Vale a pena mencionar que pode haver algumas rugas com o uso libelf ou libbfd se Isso precisa trabalhar em um ambiente de desenvolvimento de cruz.
Outras dicas
Você pode compilar o código com gcc -S
a saída de uma lista montador, em vez de compilar plenamente em um arquivo de objeto ou executável. Em seguida, basta substituir as instruções desejadas sem-ops (por exemplo, usando sed
), e continuar a compilação de lá.
Se você também quer fazer isso para arquivos objeto ou bibliotecas que você não tem o código-fonte original para, você, em vez tem que usar uma ferramenta como o objdump(1)
para desmontá-los e obter os endereços das instruções que você deseja substituir. Em seguida, analisar os cabeçalhos de arquivo objeto para encontrar os deslocamentos dentro do arquivo dessas instruções, e depois substituir as instruções de máquina sem-ops diretamente nos arquivos de objeto. Este é um pouco mais complicado, mas factível.