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