Buffer Overflow Problem
-
Ich habe folgeden Code aus http://insecure.org/stf/smashstack.html:
Der Code soll nach 0x08048398 springen.void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret; ret = buffer1 + 12; (*ret) += 8; } void main() { int x; x = 0; function(1,2,3); x = 1; printf("%d\n",x); }Die Distanzen scheinen zu stimmen:
(gdb) disas main Dump of assembler code for function main: 0x08048372 <main+0>: lea 0x4(%esp),%ecx 0x08048376 <main+4>: and $0xfffffff0,%esp 0x08048379 <main+7>: pushl -0x4(%ecx) 0x0804837c <main+10>: push %ebp 0x0804837d <main+11>: mov %esp,%ebp 0x0804837f <main+13>: push %ecx 0x08048380 <main+14>: sub $0x14,%esp 0x08048383 <main+17>: movl $0x0,-0x8(%ebp) 0x0804838a <main+24>: push $0x3 0x0804838c <main+26>: push $0x2 0x0804838e <main+28>: push $0x1 0x08048390 <main+30>: call 0x8048354 <function> 0x08048395 <main+35>: add $0xc,%esp 0x08048398 <main+38>: movl $0x1,-0x8(%ebp) 0x0804839f <main+45>: sub $0x8,%esp 0x080483a2 <main+48>: pushl -0x8(%ebp) 0x080483a5 <main+51>: push $0x8048480 0x080483aa <main+56>: call 0x80482b8 <printf@plt> 0x080483af <main+61>: add $0x10,%esp 0x080483b2 <main+64>: mov -0x4(%ebp),%ecx 0x080483b5 <main+67>: leave 0x080483b6 <main+68>: lea -0x4(%ecx),%esp 0x080483b9 <main+71>: ret End of assembler dump. (gdb) disas function Dump of assembler code for function function: 0x08048354 <function+0>: push %ebp 0x08048355 <function+1>: mov %esp,%ebp 0x08048357 <function+3>: sub $0x20,%esp 0x0804835a <function+6>: lea -0x9(%ebp),%eax 0x0804835d <function+9>: add $0xc,%eax 0x08048360 <function+12>: mov %eax,-0x4(%ebp) 0x08048363 <function+15>: mov -0x4(%ebp),%eax 0x08048366 <function+18>: mov (%eax),%eax 0x08048368 <function+20>: lea 0x8(%eax),%edx 0x0804836b <function+23>: mov -0x4(%ebp),%eax 0x0804836e <function+26>: mov %edx,(%eax) 0x08048370 <function+28>: leave 0x08048371 <function+29>: ret End of assembler dump.Und trotzdem bekomme ich ein Segmentation fault.
gcc version 4.2.3
HOffe jemand kann mir helfen .
Danke
-
Habe vergessen zu sagen wo der bof eintritt:
Program received signal SIGSEGV, Segmentation fault.
0x08048398 in main ()
Dort will ich ja hin springen laut tutorial , aber trotzdem der bof.
Dnake
-
Hey,
damit hatte ich kürzlich auch Probleme, ich bin mir aber nicht sicher ob es sich dabei wirklich um einen Fehler handelt oder um eine gewollt "Falsche Angabe" im Source. Da ich annehme das letzteres der Fall ist, möchte ich dir nicht direkt helfen. Trotzdem kleiner Tip: Schau dir einmal den Stack an, also wie die Variablen etc. genau organisiert sind, dann wirst du das Problem vielleicht finden
lg elefant1990
-
seaht schrieb:
void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret; ret = buffer1 + 12; (*ret) += 8; } void main() { int x; x = 0; function(1,2,3); x = 1; printf("%d\n",x); }Mit char buffer1[5] sucht das Betriebssystem für dich irgendwo einen zusammenhängenden Arbeitsspeicher von der größe 5 Byte.
Durch buffer1+12 bist du aber außerhalb von dem revervierten Speicherbereich, denn dieses geht schließlich nur von buffer1+0 bis buffer1+4.
Naja, dann zeigt ret also auf irgendwas im Arbeitsspeicher.
Und nun sagst du mit (*ret) += 8; :Addiere zu dem Irgendwas eine 8.
-
jeder "normale" compiler hat da ein 4 byte alignment also wird aus dem
5 byte array ein 8 byte array (intern nur)
buffer1 + 8 würde über das ende des arrays auf ebp zeigen
und buffer1 + 12 auf eip
sofern ist das richtig
-
helferlein schrieb:
jeder "normale" compiler hat da ein 4 byte alignment also wird aus dem
5 byte array ein 8 byte array (intern nur)
buffer1 + 8 würde über das ende des arrays auf ebp zeigen
und buffer1 + 12 auf eip
sofern ist das richtigWieso sollte der Compiler denn mehr adressieren wollen (buffer1+12) als nötig ist?
Bzw. so oder so: buffer1 ist nicht initialisiert und mit *ret = *ret + 8 versucht er einem unbekannten Wert eine 8 hinzuzuaddieren.
-
johny_legend schrieb:
helferlein schrieb:
jeder "normale" compiler hat da ein 4 byte alignment also wird aus dem
5 byte array ein 8 byte array (intern nur)
buffer1 + 8 würde über das ende des arrays auf ebp zeigen
und buffer1 + 12 auf eip
sofern ist das richtigWieso sollte der Compiler denn mehr adressieren wollen (buffer1+12) als nötig ist?
Bzw. so oder so: buffer1 ist nicht initialisiert und mit *ret = *ret + 8 versucht er einem unbekannten Wert eine 8 hinzuzuaddieren.
Nein, der Wert ist nicht unbekannt, siehe das ASM Listings.
Um Plattformunabhängigkeit geht es hier nicht.
-
buffer1 muss auch nicht initialisiert werden, er dient nur dazu eine addresse zu bekommen.
arbeitsspeicher: /-------------------------------------------------\ | buffer2 | buffer1 | alter ebp | returnaddresse | \-------------------------------------------------/ buffer1-12 |buffer1 |buffer1+8 |buffer1+12kann sein dass dein compiler da noch zusätzliche befehle einfügt
(push esi und sowas)ist der dump den du gepostet hast wirklich der von dem code ?
-
buffer1 + 12Das ist schlicht undefiniert.
Will man sich auf solche Dinge einlassen, gibt es bessere Möglichkeiten.
Ist die Aufrufkonvention bekannt und kann man den Compiler irgendwie dazu zwingen, keine Inlinesubstitution durchzuführen (andernfalls ist die Frage nach der Rücksprungadresse sowieso sinnlos), bietet sich die Adresse der Funktionsparameter als Ausgangspunkt an. Denn an dieser Stelle kann der Compiler dann nicht (unter diesen Voraussetzungen) beliebig optimieren.
Beivoid function(int a, int b, int c) { void* ret = (void**)&a - 1; ... }besteht eine gewisse Chance, das gesuchte Ergebnis zu erhalten.
-
http://insecure.org/stf/smashstack.html
Von dort ist das ganze und jetzt funkt es auch , ich musste einfach buffer1[] um 13 erhöhen nicht bloss um 12.void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret; ret = buffer1 + 13; (*ret) += 8; } void main() { int x; x = 0; function(1,2,3); x = 1; printf("%d\n",x); }buffer1 muss auch nicht initialisiert werden, er dient nur dazu eine addresse zu bekommen.
Meines Wissens nach ist das absolt korekt und wird so auch in smashthestack gesagt.
Bei dem Tutorial ist eine umfassende Erklärung wie man auf den wert kommt ,
sucht einfach nach example3 .
Danke an alle.