Warum ist der orig_eax
Mitglied enthalten sys/user.h
‘s struct user_regs_struct
?
Warum wird zusätzlich zu eax auch orig_eax bereitgestellt?
Matt Tischler
osgx
Weil es drin war struct pt_regs
welches ist …. http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/arch/x86/include/asm/user_32.h#L77
73 * is still the layout used by user mode (the new
74 * pt_regs doesn't have all registers as the kernel
75 * doesn't use the extra segment registers)
Daher erwarten viele User-Space-Dienstprogramme eine orig_eax
Feld hier, also ist es darin enthalten user_regs_struct
auch (um mit älteren Debuggern kompatibel zu sein und ptrace
rs)
Die nächste Frage lautet: „Warum ist die orig_eax
Mitglied enthalten struct pt_regs
?”.
Es wurde in Linux 0.95 hinzugefügt http://lxr.linux.no/#linux-old+v0.95/include/sys/ptrace.h#L44. Ich schlage vor, dies wurde nach einem anderen Unix mit getan pt_regs
Struktur. Kommentar in 0,95 sagt
29 * this struct defines the way the registers are stored on the
30 * stack during a system call.
Also der Ort von orig_eax
wird durch die Syscall-Schnittstelle definiert. Hier ist es http://lxr.linux.no/#linux-old+v0.95/kernel/sys_call.s
17 * Stack layout in 'ret_from_system_call':
18 * ptrace needs to have all regs on the stack.
19 * if the order here is changed, it needs to be
20 * updated in fork.c:copy_process, signal.c:do_signal,
21 * ptrace.c ptrace.h
22 *
23 * 0(%esp) - %ebx
...
29 * 18(%esp) - %eax
...
34 * 2C(%esp) - orig_eax
Warum müssen wir alte retten eax
zweimal? Da eax
wird für den Rückgabewert von syscall verwendet (gleiche Datei, etwas weiter unten):
96_system_call:
97 cld
98 pushl %eax # save orig_eax
99 push %gs
...
102 push %ds
103 pushl %eax # save eax. The return value will be put here.
104 pushl %ebp
...
117 call _sys_call_table(,%eax,4)
Ptrace muss in der Lage sein, sowohl den Status aller Register vor dem Systemaufruf als auch den Rückgabewert des Systemaufrufs zu lesen. aber der Rückgabewert wird geschrieben %eax
. Dann originell eax
, die vor dem Systemaufruf verwendet werden, gehen verloren. Um es zu speichern, gibt es eine orig_eax
aufstellen.
UPDATE: Dank R.. und großartigem LXR habe ich eine vollständige Suche durchgeführt orig_eax
unter linux 0.95.
Es wird nicht nur in Ptrace verwendet, sondern auch in do_signal beim Neustart eines Syscalls (wenn es einen Syscall gibt, endet mit ERESTARTSYS
)
158 *(&eax) = orig_eax;
UPDATE2: Linus sagte etwas interessantes dazu:
Es ist wichtig, dass ORIG_EAX auf einen bestimmten Wert eingestellt ist nicht eine gültige Systemrufnummer, damit die Systemruf-Neustartlogik (siehe Signalbehandlungscode) nicht auslöst.
UPDATE3: ptrace
r App (Debugger) kann sich ändern orig_eax
Anzurufende Systemrufnummer ändern: http://lkml.org/lkml/1999/10/30/82 (In einigen Versionen des Kernels war es EIO, in Ptrace ein ORIG_EAX zu ändern)
-
knackige Antwort auf eine (scheinbar) schwache Frage!
– sehen
24. Juni 2011 um 14:50 Uhr
-
Ich dachte, es hängt mit Systemaufrufen zusammen (und möglicherweise mit dem Neustart von Systemaufrufen). +1 für das Aufspüren der Details!
– R.. GitHub HÖR AUF, EIS ZU HELFEN
24. Juni 2011 um 16:18 Uhr
-
Beachten Sie, dass neuere Kernel das Feld in orig_ax umbenannt haben – wenn Sie eine LXR-Suche durchführen möchten, führen Sie sowohl orig_eax als auch orig_ax aus.
– osgx
24. Juni 2011 um 16:38 Uhr
-
Warum sollte es überhaupt orig_eax brauchen? Warum sollte es wichtig sein, welcher Systemaufruf es ist, nachdem der entsprechende aufgerufen wurde? Soweit ich weiß, wird der Rückgabewert des Systemaufrufs in den Stack geschrieben, wo wir ihn später ablegen und in eax speichern. Und orig_eax ist nur da, um sicherzustellen, dass wir den aufgerufenen sys-Aufruf nicht verlieren. Meine andere Frage, warum wird der Rückgabewert auf den Stapel geschrieben und nicht sofort nach eax?
– Tonyyyy
14. April 2018 um 22:05 Uhr