linux-l: Buffer-Overflow
Thomas Knop
t.knop at isv-gmbh.de
Mi Apr 26 08:58:07 CEST 2000
On, Die, 25 Apr 2000, Steffen Solyga wrote:
gekürzt ...
> Dem Compiler auf der Spur... sehr aufschlußreich!
> Ich habe in das Progrämmchen an einigen Stellen stack dumps eingefügt, um
> zu sehen, was wann wo dort landet (siehe attachment). Dabei habe ich fest-
> gestellt, daß die 4 Bytes, die Du als (char *s) kommentiert hast, jedoch
> nicht die bezüglich buffer_overflow() lokale Variable s beherbergen -- diese
> kommt erst nach der Rücksprungadresse. Anscheinend handelt es sich um einen
> stackpointer, denn er enthält die erste nicht mehr zu main() gehörende
> Stapeladresse. Wer braucht die?
> In buffer_overflow() sieht der stack folgendermaßen aus:
> buffer (20 bytes)
> -- fraglicher Zeiger (4 bytes)
> | Rücksprungadresse (4 bytes)
> | s (4 bytes)
> | str (28 bytes)
> -> weiterer fraglicher Zeiger (4 bytes)
> ...
>
> Erinnert sich noch einer an das Monitor-Programm vom C64, das man so schön
> als schnellen Assembler/Disassembler verwenden konnte? Bei dem waren die
> Aufrufe der einzelnen Komponenten mit PUSH+RET realisiert...
Mir get ein Licht auf!
Jede Subroutine fängt normalerweise (compilergeneriert) mit
push ebp
mov ebp,esp
... und dann ...
sub esp, <Größe der lokalen Variablen>
an, damit dann über [esp-<Offset>] auf die lokalen Variablen zugegriffen
werden keann ....
ich hab's ja angedeute ohne Assembler ist da nix zu holen ;-)
Die vier Bytes sind also der gesicherte Stackpointer - hätte ich auch
vorher drauf kommen können ... sozusagen (hallo Jens) "Glück" gehabt mit
den 4 Bytes ;-)
So könnte "test2" als asm aussehen (ohne garantie/nicht getestet!):
push ebp ; ebp sichern
mov ebp, esp ; stackpointer holen
sub esp, 20 ; 20 bytes für "buffer" auf dem stack resavieren
mov ebx, ebp ; alte stack adress hole
push [ebp-28] ; adresse von "s" auf den stack
sub ebx, 24 ; adresse von "buffer" nach ebx
push ebx ; adresse von "buffer" auf den stack
call strcpy ; string copy aufrufen
add esp, 20 ; stack wieder herstellen
ret ; zurück -> im Bsp. sprung auf test1
Der Stack sieht dann so aus (genau umgekehrt wie oben)
?-0 : function main "str"
?-28: ge-push-te addresse von "str" (char *)s
?-32: rücksprung addresse
?-36: gesicherter wert von EBP
?-56: function test2 "buffer"
Gruß Thomas
PS: Mehr Progammierkurs machen jetzt aber nit, ok ?
--
Thomas Knop Tel: +49-30-53433408
ISV GmbH Berlin Fax: +49-30-53433435
Am Treptower Park 75 t.knop at isv-gmbh.de
12435 Berlin http://www.isv-gmbh.de
Mehr Informationen über die Mailingliste linux-l