Domanda

Ho un file eseguibile (C ++, i386, compilato sotto MacOS / X Tiger, se è importante) che contiene un bug. La correzione per il bug è semplice: c'è un posto nel codice in cui si chiama fork () e non dovrebbe. Poiché la correzione è semplice e poiché la ricompilazione dell'eseguibile da zero sarebbe difficile a questo punto (non chiedere), vorrei solo patchare direttamente il file eseguibile / binario.

Come primo passo verso quello, ho corso " otool -tV MyExecutableName " sul mio eseguibile e voilà, l'ho trovato nell'output di smontaggio:

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

Quindi quello che mi piacerebbe fare è sostituire il codice operativo alla riga 0002ce19, in modo che invece di chiamare _fork, salti semplicemente incondizionatamente al caso di errore (cioè dovrebbe agire come se fork () avesse restituito -1 )

Sfortunatamente, sono un principiante completo al disassemblaggio / patch binario, quindi non sono sicuro di come procedere. In particolare, le mie domande sono:

1) Quali byte devo scrivere nelle posizioni da 0002ce19 a 0002xe1d per ottenere quello che voglio? Presumo che sarebbe l'equivalente assemblato di "jmp 0x0002cf02", ma come faccio a capire quali sono questi byte?

2) Gli offset stampati da " otool -tV " sembrano essere offset nel segmento __TEXT dell'eseguibile. Come posso capire il delta-byte tra gli offset stampati e la parte superiore del file, in modo da poter modificare / patchare i byte corretti all'interno del file?

Grazie per qualsiasi consiglio tu possa dare!

È stato utile?

Soluzione

Non ho familiarità con MacOS / X ma posso darti alcuni suggerimenti.

Il modo corretto per risolverlo è utilizzare un disassemblatore per correggere il file.

0002ce19        calll   0x00850ac9

può essere sostituito con

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

Gli offset che vedi sono relativi, quindi non puoi trovarli nel file.
Ad esempio, jll 0x0002cf02 è in realtà jll 0x000000DF

Se ho ragione, il seguente blocco di codice

0002ce19        calll   0x00850ac9      ; symbol stub for: _fork
0002ce1e        cmpl    
0x  E8   AB3C8200
    83F8 00
    0F8C DF000000
    0F84 0B000000
x00,%eax 0002ce21 jll 0x0002cf02 0002ce27 jle 0x0002ce34

avrà questo modulo assemblato (20 byte):

<*>

Se quella sequenza è unica nel file, puoi provare a cambiare E8AB3C8200 in B8FFFFFFFF , se non puoi usare un disassemblatore.

Altri suggerimenti

Probabilmente il più semplice sarebbe mettere mov $ -1,% eax al posto della chiamata. Puoi scoprire a quali byte corrisponde inserendolo in un file .s, compilandolo e scaricando il risultato, riempiendo con nops se è più corto della posizione della patch. Ottengo " b8 ff ff ff ff " ;, che si adatta perfettamente.

Puoi trovare l'inizio di __TEXT eseguendo otool -l e cercando l'offset.

otx e Hex Fiend saranno i tuoi amici. otx ti darà uno smontaggio con offset relativi al file e Hex Fiend ti consentirà di correggere il salto. Ricordare che 0x90 è il codice operativo (x86) per NOP, quindi 9090909090 è un sostituto appropriato per la chiamata fork (). (Tieni presente che non genererà un valore di ritorno, quindi qualcosa di strano potrebbe finire in eax.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top