Wie kann ich den Standort von demontierten Code innerhalb eines ausführbaren bestimmen?
-
22-07-2019 - |
Frage
Ich habe eine ausführbare Datei bekommt (C ++, i386, unter MacOS / X Tiger kompilierte, wenn es darauf ankommt), die einen Fehler enthält. Das Update für den Fehler ist einfach - es gibt eine Stelle im Code, wo es ruft fork () und soll es nicht. Da das Update einfach ist, und weil die ausführbare Datei von Grund auf neu zu kompilieren an dieser Stelle schwierig sein würde (nicht fragen), würde Ich mag einfach direkt die ausführbare Datei / Binär-Datei patchen.
Als erster Schritt in diese Richtung, lief ich „otool -TV MyExecutableName“ auf meiner ausführbaren Datei, und voila, ich fand diese bei der Demontage Ausgabe:
./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 ...]
Also, was ich tun möchte ist, den Opcode an der Linie 0002ce19, zu ersetzen, so dass statt calll'ing _fork, es ist einfach bedingungslos dem Fehlerfall springt (dh sollte es tun, als ob fork () zurückgekehrt war -1 )
Leider bin ich ein kompletter Neuling bei der Demontage / Binär-Patching, also bin ich nicht sicher, wie dies zu tun gehen. Insbesondere meine Fragen sind:
1) Welche Bytes sollte ich in Orten schreiben 0002ce19 durch 0002xe1d zu bekommen, was ich will? Ich nehme an, es würde das zusammengesetzte Äquivalent von „jmp 0x0002cf02“ sein, aber wie kann ich herausfinden, was dieser Bytes ist?
2) die Offsets gedruckt von "otool -TV" erscheinen Versätze in das __TEXT Segment der ausführbaren Datei zu sein. Wie kann ich feststellen, welches Byte-Delta zwischen den gedruckten Versetzungen und dem Anfang der Datei aus, so dass ich bearbeiten / in der Datei das richtige Bytes patchen?
Vielen Dank für jede Beratung geben kann!
Lösung
Ich bin nicht vertraut mit dem MacOS / X, aber ich kann Ihnen einige Hinweise geben.
Der richtige Weg, es zu beheben, ist einen Disassembler zu verwenden, um Ihre Datei zu patchen.
0002ce19 calll 0x00850ac9
ersetzt werden kann
0002ce19 movl eax, -1 ; mov eax, 0xFFFFFFFF
Die Offsets Sie sehen, sind relativ, so dass Sie sie nicht in der Datei finden.
Zum Beispiel wird jll 0x0002cf02
tatsächlich jll 0x000000DF
Wenn ich mich richtig, der folgende Codeblock
0002ce19 calll 0x00850ac9 ; symbol stub for: _fork
0002ce1e cmpl $0x00,%eax
0002ce21 jll 0x0002cf02
0002ce27 jle 0x0002ce34
wird diese zusammengebauter Form hat (20 Byte):
0x E8 AB3C8200
83F8 00
0F8C DF000000
0F84 0B000000
Wenn diese Sequenz in der Datei eindeutig ist, dann können Sie versuchen, die E8AB3C8200
zu ändern B8FFFFFFFF
, wenn Sie keine Disassembler verwenden können.
Andere Tipps
Wahrscheinlich wäre die einfachste mov $-1, %eax
anstelle des Anrufs zu setzen. Sie können herausfinden, was die Bytes, dass entspricht, indem sie in einer .s-Datei setzen, Kompilieren und Dumping das Ergebnis, Polsterung mit nops, wenn sie kürzer als der Patch-Speicherort ist. Ich erhalte "b8 ff ff ff ff", was gerade passt.
Sie können den Beginn der __TEXT
finden von otool -l
laufen und suchen nach dem Offset.
otx und Hex Fiend wird Ihre Freunde. otx wird Ihnen eine Demontage mit datei relativen Offsets und Hex Fiend werden Sie den Sprung Patch heraus lassen. Denken Sie daran, dass 0x90 ist die (x86) Opcode für NOP, so 9090909090 ist ein geeigneter Ersatz für die fork () Aufruf. (Denken Sie daran, dass es keinen Rückgabewert erzeugen, so etwas seltsam in EAX kann am Ende.)