ich mit Pufferüberlauf bin experimentieren und versuchen, die Absenderadresse des Stapels mit einem bestimmten Eingang von fgetseinen Pufferüberlaufes mit fgets Verursachung
Dies ist der Code zu überschreiben:
void foo()
{
fprintf(stderr, "You did it.\n");
}
void bar()
{
char buf[20];
puts("Input:");
fgets(buf, 24, stdin);
printf("Your input:.\n", strlen(buf));
}
int main(int argc, char **argv)
{
bar();
return 0;
}
Auf einem normale Ausführung gibt das Programm nur Ihre Eingabe zurück. Ich möchte, dass es foo() ausgibt, ohne den Code zu ändern.
Meine Idee war, den Puffer von buf
durch Eingabe von 20 'A'
s überlaufen. Dies funktioniert und verursacht einen Segmentierungsfehler. Meine nächste Idee war es, die Adresse foo()
zu finden, die \x4006cd
ist und diese an die 20 'A'
s anhängen.
Aus meinem Verständnis sollte dies die Rücksprungadresse des Stapels überschreiben und es zu foo
springen lassen. Aber es verursacht nur einen segfault.
Was mache ich falsch?
Update: Assembler-Dumps Haupt
Dump of assembler code for function main:
0x000000000040073b <+0>: push %rbp
0x000000000040073c <+1>: mov %rsp,%rbp
0x000000000040073f <+4>: sub $0x10,%rsp
0x0000000000400743 <+8>: mov %edi,-0x4(%rbp)
0x0000000000400746 <+11>: mov %rsi,-0x10(%rbp)
0x000000000040074a <+15>: mov $0x0,%eax
0x000000000040074f <+20>: callq 0x4006f1 <bar>
0x0000000000400754 <+25>: mov $0x0,%eax
0x0000000000400759 <+30>: leaveq
0x000000000040075a <+31>: retq
End of assembler dump.
foo
Dump of assembler code for function foo:
0x00000000004006cd <+0>: push %rbp
0x00000000004006ce <+1>: mov %rsp,%rbp
0x00000000004006d1 <+4>: mov 0x200990(%rip),%rax # 0x601068 <[email protected]@GLIBC_2.2.5>
0x00000000004006d8 <+11>: mov %rax,%rcx
0x00000000004006db <+14>: mov $0x15,%edx
0x00000000004006e0 <+19>: mov $0x1,%esi
0x00000000004006e5 <+24>: mov $0x400804,%edi
0x00000000004006ea <+29>: callq 0x4005d0 <[email protected]>
0x00000000004006ef <+34>: pop %rbp
0x00000000004006f0 <+35>: retq
End of assembler dump.
bar:
Dump of assembler code for function bar:
0x00000000004006f1 <+0>: push %rbp
0x00000000004006f2 <+1>: mov %rsp,%rbp
0x00000000004006f5 <+4>: sub $0x20,%rsp
0x00000000004006f9 <+8>: mov $0x40081a,%edi
0x00000000004006fe <+13>: callq 0x400570 <[email protected]>
0x0000000000400703 <+18>: mov 0x200956(%rip),%rdx # 0x601060 <[email protected]@GLIBC_2.2.5>
0x000000000040070a <+25>: lea -0x20(%rbp),%rax
0x000000000040070e <+29>: mov $0x18,%esi
0x0000000000400713 <+34>: mov %rax,%rdi
0x0000000000400716 <+37>: callq 0x4005b0 <[email protected]>
0x000000000040071b <+42>: lea -0x20(%rbp),%rax
0x000000000040071f <+46>: mov %rax,%rdi
0x0000000000400722 <+49>: callq 0x400580 <[email protected]>
0x0000000000400727 <+54>: mov %rax,%rsi
0x000000000040072a <+57>: mov $0x400821,%edi
0x000000000040072f <+62>: mov $0x0,%eax
0x0000000000400734 <+67>: callq 0x400590 <[email protected]>
0x0000000000400739 <+72>: leaveq
0x000000000040073a <+73>: retq
End of assembler dump.
Haben Sie sich den entsprechenden Assembler (und damit Stacklayout) für diesen Code angeschaut? –
Wenn es nur so einfach wäre ... –
Sie sollten sich die entsprechende Baugruppe ansehen. Manchmal führt der Compiler mehr als 20 Bytes aus, die Sie für die Ausrichtung erstellt haben. Sie sollten auch das Layout des Stacks betrachten und wie Register/gespeicherte ret addrs in welcher Reihenfolge gespeichert werden. Machen Sie weiter und buchen Sie die Montage der Funktion und wir können Ihnen weiterhelfen. –