Dopo tanto tempo e pensieri, ho finalmente risolto il problema. La risorsa che mi ha aiutato a risolvere questo problema è Stack smashing code not working on Linux kernel 2.6.38.7... Please help
Il più grande cambiamento che mi ha aiutato a risolvere questo era usando disassembly-flavor intel
per gdb
.
codice
Disassembled (per riferimento):
0804840c <function>:
804840c: 55 push ebp
804840d: 89 e5 mov ebp,esp
804840f: 83 ec 10 sub esp,0x10
8048412: 8d 45 f7 lea eax,[ebp-0x9]
8048415: 83 c0 14 add eax,0x14
8048418: 89 45 fc mov DWORD PTR [ebp-0x4],eax
804841b: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]
804841e: 8b 00 mov eax,DWORD PTR [eax]
8048420: 8d 50 05 lea edx,[eax+0x5]
8048423: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]
8048426: 89 10 mov DWORD PTR [eax],edx
8048428: c9 leave
8048429: c3 ret
0804842a <main>:
804842a: 55 push ebp
804842b: 89 e5 mov ebp,esp
804842d: 83 e4 f0 and esp,0xfffffff0
8048430: 83 ec 20 sub esp,0x20
8048433: c7 44 24 1c 00 00 00 mov DWORD PTR [esp+0x1c],0x0
804843a: 00
804843b: c7 44 24 08 03 00 00 mov DWORD PTR [esp+0x8],0x3
8048442: 00
8048443: c7 44 24 04 02 00 00 mov DWORD PTR [esp+0x4],0x2
804844a: 00
804844b: c7 04 24 01 00 00 00 mov DWORD PTR [esp],0x1
8048452: e8 b5 ff ff ff call 804840c <function>
8048457: c7 44 24 1c 01 00 00 mov DWORD PTR [esp+0x1c],0x1
804845e: 00
804845f: 8b 44 24 1c mov eax,DWORD PTR [esp+0x1c]
8048463: 89 44 24 04 mov DWORD PTR [esp+0x4],eax
8048467: c7 04 24 18 85 04 08 mov DWORD PTR [esp],0x8048518
804846e: e8 7d fe ff ff call 80482f0 <[email protected]>
8048473: c9 leave
8048474: c3 ret
8048475: 66 90 xchg ax,ax
8048477: 66 90 xchg ax,ax
8048479: 66 90 xchg ax,ax
804847b: 66 90 xchg ax,ax
804847d: 66 90 xchg ax,ax
804847f: 90 nop
C'erano due problemi con la mia comprensione su questo:
A) Il mio primo problema era trovare la quantità di byte di invadere ret
all'interno function
. Ancora; Ho fatto questo utilizzando la sintassi Intel per lo smontaggio e ha scoperto che:
Per impostare ret
presso lo spazio corretto in memoria ret
deve essere impostato al EIP
quando la funzione è stato chiamato. Lo spazio indirizzo 8048412
si sposta in basso nello stack 0x9
. Perché questo è un codice a 32 bit; per arrivare a ret
aggiungiamo quindi un ulteriore 0x4
byte per la dimensione della parola. Per arrivare a ret
significa che ret
è impostato su 0x9 + 0x4
che è 13 in decimale.
Questo risolve il primo problema di arrivare a ret
.
B) Il secondo problema è saltare la posizione di memoria 0x8048457
. Questo viene fatto aggiungendo 7 byte a (*ret)
che fa saltare ed eseguire il programma a 0x804845e
che è 00
(NUL
). Questo è solo inefficiente; così ho aggiunto il byte aggiuntivo ed eseguito 8 byte nello stack; quindi risultante in x = 0
;
Ho trovato la quantità esatta di byte 8 (c7 44 24 1c 01 00 00
è 7 byte) e 00
è un byte. Questo ha risolto il mio ultimo problema.
Il mio codice C modificata:
void function(int a, int b, int c) {
char buffer1[5];
int *ret;
ret = buffer1 + 13; //tried 11, 14, 20, 40, 38, 43
(*ret) += 8; // tried 5, 8, 12; 8 is correct value!
}
void main() {
int x;
x = 0;
function(1,2,3);
x = 1;
printf("%d\n", x);
}
Trasferirsi in StackOverflow su richiesta dell'utente. (+1, buona domanda.) –
Se sottrai gli indirizzi proprio come in quell'articolo, ottieni 10 byte :) controlla i collegamenti alla fine della mia risposta, l'offset è sbagliato. – iabdalkader
C'era una risposta che diceva che ora è stata rivista. Ecco l'ultima [revisione] (https://avicoder.me/2016/02/01/smashsatck-revived/) – NathanOliver