Vamos tentar. Aqui está um programa C trivial:
#include <stdio.h>
int main(int argc, char **argv) {
puts("/usr/tmp");
}
Vamos construir isso em test
:
$ cc -o test test.c
Se o executarmos, será impresso "/ usr / tmp".
Vamos descobrir onde " /usr/tmp
" está no binário:
$ strings -t d test | grep /usr/tmp
1460 /usr/tmp
-t d
imprime o deslocamento em decimal no arquivo de cada string que encontrar.
Agora vamos criar um arquivo temporário com apenas " /tmp
": dd
$ printf "/tmp\x00" > tmp
Então agora temos o binário, sabemos onde a string que queremos mudar é, e temos um arquivo com a string de substituição nela.
Agora podemos usar tmp
:
$ dd if=tmp of=test obs=1 seek=1460 conv=notrunc
Isto lê dados de /tmp
(nosso arquivo " %code% "), escrevendo em nosso binário, usando um tamanho de bloco de saída de 1 byte, pulando para o offset que encontramos anteriormente antes de escrever qualquer coisa, e explicitamente não truncando o arquivo quando terminar. /tmp
dd
tmp%code%
Podemos executar o executável corrigido:
$ ./test
/tmp
A string literal que o programa imprime foi alterada, então agora contém " %code% ", mas as funções de string param assim que vêem o primeiro byte nulo. Esse patch só permite tornar a string mais curta ou com o mesmo tamanho, e não mais, mas é adequada para essas finalidades.
Portanto, não só podemos corrigir as coisas usando %code% , como acabamos de fazer.