Pergunta

Eu tenho um arquivo executável (C ++, i386, compilado sob MacOS / X Tiger, se isso importa) que contém um bug. A correção para o bug é simples - há um lugar no código onde ele chama fork () e que não deveria. Porque a correção é simples, e porque recompilar o executável a partir do zero seria difícil neste momento (não pergunte), eu gostaria de apenas corrigir o arquivo executável / binário diretamente.

Como um primeiro passo para isso, eu corri "otool -TV MyExecutableName" no meu executável, e voila, eu encontrei este na saída desmontagem:

./MyExecutableName:
(__TEXT,__text) section
[... many lines omitted ...]
0002ce0d        subl    $0x10,%esp
0002ce10        calll   0x0051adac
0002ce15        movzbl  0x14(%ebp),%esi
0002ce19        calll   0x00850ac9      ; symbol stub for: _fork
0002ce1e        cmpl    $0x00,%eax
0002ce21        jll     0x0002cf02
0002ce27        jle     0x0002ce34
[... many more lines omitted ...]

Então, o que eu gostaria de fazer é substituir o código de operação na linha 0002ce19, de modo que em vez de calll'ing _fork, ele simplesmente salta incondicionalmente para o caso de falha (ou seja, deve agir como se fork () tinha retornado -1 )

Infelizmente, eu sou um novato completo a desmontagem patching / binário, então eu não tenho certeza de como vai fazer sobre isso. Em particular, minhas perguntas são:

1) Qual bytes que eu deveria escrever em locais 0002ce19 através 0002xe1d para conseguir o que eu quero? Eu suponho que seria o equivalente montado de "jmp 0x0002cf02", mas como faço para descobrir o que os bytes são?

2) Os deslocamentos impressos por "otool -TV" parecem ser as compensações para o segmento __TEXT do executável. Como posso descobrir o byte-delta entre os deslocamentos impressos e na parte superior do arquivo, para que eu possa editar / corrigir os bytes corretas dentro do arquivo?

Obrigado por qualquer conselho que você pode dar!

Foi útil?

Solução

Eu não estou familiarizado com o MacOS / X, mas eu posso lhe dar algumas dicas.

A maneira correta de corrigi-lo, é usar um desmontador para corrigir seu arquivo.

0002ce19        calll   0x00850ac9

pode ser substituída por

0002ce19        movl   eax, -1 ; mov eax, 0xFFFFFFFF

Os deslocamentos que você vê são relativas, então você não pode encontrá-los no arquivo.
Por exemplo, jll 0x0002cf02 é realmente jll 0x000000DF

Se eu estiver correto, a seguir bloco de código

0002ce19        calll   0x00850ac9      ; symbol stub for: _fork
0002ce1e        cmpl    $0x00,%eax
0002ce21        jll     0x0002cf02
0002ce27        jle     0x0002ce34

terá esta forma montada (20 bytes):

0x  E8   AB3C8200
    83F8 00
    0F8C DF000000
    0F84 0B000000

Se essa seqüência é único no arquivo, então você pode tentar mudar o E8AB3C8200 para B8FFFFFFFF, se você não pode usar um desmontador.

Outras dicas

Provavelmente o mais fácil seria colocar mov $-1, %eax no lugar da chamada. Você pode descobrir o que bytes que corresponde a, colocando-o em um arquivo .s, compilá-lo e descarregar o resultado, preenchimento com nops se for mais curto do que o local patch. Eu recebo "b8 ff ff ff ff", que só se encaixa.

Você pode encontrar o início da __TEXT executando otool -l e olhando para o deslocamento.

OTX e Hex Fiend serão seus amigos. OTX lhe dará uma desmontagem com deslocamentos de arquivo-relativa e Hex Fiend vai deixar você corrigir o salto. Lembre-se que 0x90 é o (x86) código de operação para NOP, de modo 9090909090 é um substituto adequado para a chamada fork (). (Basta ter em mente que não irá gerar um valor de retorno, de modo algo estranho pode acabar em eax.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top