|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
[assembly] Salti relativi
è un pò di tempo che non mi capacito di questa cosa...
qualcosa mi vieta di fare dei salti relativi in assembly? Mi spiego meglio... l'istruzione: Codice:
jmp 0x2a a me da segmentation fault. (su Ubuntu 9.10) ma lo spostamento che eseguo utilizzando il registro IP lo calcolato e non sconfina, perchè dunque non c'è modo di eseguire salti di questo tipo? Per essere sicuro di quello che dico ho fatto questa prova: un banale programma che stampa "Hello world!" con codice assembly funzionante: Codice:
;---> sintassi intel <---
section .data
section .text
hello db "Hello world!",0xa
global main
mov eax,4
mov ebx,1
mov ecx,hello
mov edx,13
int 80h
mov eax,1
mov ebx,0
int 80h
Codice:
section .data
section .text
hello db "Hello world!",0xa
global main
main:
mov eax,4
mov ebx,1
mov ecx,hello
mov edx,13
int 80h
jmp 0x5 ; <<- jmp è 5 bytes, quindi salta qui |
mov eax,1 ;<------------------------------------/
mov ebx,0
int 80h
Eventualmente posso postarvi anche la traccia del programma in esecuzione.... la mia esperienza in assembly è piuttosto breve ancora... che ne pensate? Grazie mille. Ultima modifica di Teo@Unix : 20-01-2010 alle 23:02. |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Non sai se l'assemblatore ti ha convertito la jmp in versione "short" (un byte per l'opcode, e uno per l'offset a 8 bit con segno) oppure ha lasciato quella "long" (quest'ultima non richiede un offset, ma l'indirizzo di memoria vero e proprio).
Assembly e linguaggio macchina sono diversi anche per questo: quando usi uno mnemonico, non hai la certezza assoluta di quale opcode verrà generato. Supponendo che ti abbia generato la versione "short" devi conoscere in che modo calcolare l'offset. Adesso su due piedi non ricordo se l'offset con x86 viene calcolato prendendo come riferimento la stessa istruzione o quella successiva (come capita con tante architetture). Nel primo caso dovresti mettere 2 come offset, mentre nel secondo 0. Se invece la versione utilizzata è quella "lunga", devi utilizzare un'etichetta, altrimenti ti sarà impossibile conoscere l'indirizzo fisico che verrà generato per l'istruzione successiva alla jmp.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
sono risalito alla dimensione della istruzione jmp con il metodo che avevo descritto, ovvero disassemblando con gdb.
In molti documenti in rete vi leggo che è affidabile... cmq, anche mettendo 2 il programma genera l'errore di memoria... se volessi provare con l'indirizzo di memoria? Non credo di avere modo si saperlo.... |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Non credo proprio.
Comunque riporta i byte che codificano l'opcode jmp, così vediamo intanto di cosa si tratta.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: May 2008
Messaggi: 533
|
■
Ultima modifica di rеpne scasb : 18-06-2012 alle 16:50. |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
Grazie ragazzi, allora ...cominzio a postare le prove che ho fatto ...
innanzi tutto con objdump -d hello.o ricavo la codifica del salto. istruzione: jmp 0x5: Codice:
21: cd 80 int $0x80 23: e9 01 00 00 00 jmp 29 <main+0x1c> 28: b8 01 00 00 00 mov $0x1,%eax Codice:
21: cd 80 int $0x80 23: e9 00 00 00 00 jmp 28 <main+0x1b> 28: b8 01 00 00 00 mov $0x1,%eax o mi sto imbrogliando? cmq si vede che anche se 3 sono nulli jmp è 5 bytes. Purtroppo in entrambi i casi SIGSEGV... ora faccio la prova dichiarando anche come ha specificato rеpne scasb... |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: May 2008
Messaggi: 533
|
■
Ultima modifica di rеpne scasb : 18-06-2012 alle 16:50. |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: May 2008
Messaggi: 533
|
■
Ultima modifica di rеpne scasb : 18-06-2012 alle 16:50. |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
ho ricontrollato per essere sicuro. la traduzione di jmp 0x4 è 09 00 00 00 00, quella cho ho riportato per intenderci.
l'assemblatore che ho usato è nasm versione: NASM version 2.05.01 compiled on Nov 5 2008 è incredibile ma il mio programma hello world arrivato a quella istruzione provoca segm. fault.... come se qualcosa mi impedisce di eseguire jmp relativi... provando invece con ciò che mi hai suggerito, l'assemblatore me lo vede come un add, guarda: nel file .asm ho messo al posto di jmp: db 4h,0h codifica: Codice:
23: 04 00 add $0x0,%al |
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: May 2008
Messaggi: 533
|
■
Ultima modifica di rеpne scasb : 18-06-2012 alle 16:50. |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
pardon...
non avevo capito che si trattava direttamente dell'opcode così funziona, sembra quindi che debba inserire i salti relativi direttamente come OPCODE in questo modo. Possibile? Ora proverò con il programma che mi dava problemi in principio, poi vi dico. edit: a! una cosa, un consiglio per ottenere i valori dei codici corretti da inserire pertemdo dall'istruzione presentata per prima? (ad esempio jmp 0x2a) Ultima modifica di Teo@Unix : 21-01-2010 alle 12:46. |
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
|
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
ma c'è ancora quacosa che non mi torna..... errore: "segmentation fault" ... credo che centri qualcosa la stringa "/bin/sh". Questo programma dovrebbe semplicemente eseguire una shell!! ma perchè mi dà SIGSEGV????? Codice:
void main() {
__asm__(
"jmp 0x25\n\t"
"popl %esi\n\t"
"movl %esi, 0x8(%esi)\n\t"
"xorl %eax, %eax\n\t"
"movb %eax, 0x7(%esi)\n\t"
"movl %eax, 0xc(%esi)\n\t"
"movb $0xb, %eax\n\t"
"movl %esi, %ebx\n\t"
"leal 0x8(%esi), %ecx\n\t"
"leal 0xc(%esi), %edx\n\t"
"int $0x80\n\t"
"movl $0x1, %eax\n\t"
"xorl %ebx, %ebx\n\t"
"int $0x80\n\t"
"call -0x22\n\t"
".string \"/bin/sh\"\n\t"
);
}
se volete anche compilarlo vi dico che io sto provando su Debian 5 e gcc 4.3.2 ci stò uscendo matto. EDIT: vi metto anche la versione assembly, stesso problema... e qui non ci sono salti relativi..... Codice:
.text .globl main main: jmp offset shellcode: popl %esi movl %esi, 0x8(%esi) //inserisco la stringa dopo il byte nullo xorl %eax, %eax //azzero eax mov %al, 0x7(%esi) //inserisco 0 alla fine della stringa mov %al, 0xc(%esi) //fine stringa movb $0xb, %al //n° interrupt movl %esi, %ebx //1°arg. - stringa "/bin/sh" leal 0x8(%esi),%ecx //2°arg. - indirizzo stringa leal 0xc(%esi),%edx //3°arg. - byte nullo int $0x80 //execve(name[0],name,NULL) // exit(0): xorl %ebx, %ebx movl $0x1, %eax int $0x80 offset: call shellcode .string "/bin/sh" Ultima modifica di Teo@Unix : 24-01-2010 alle 16:26. |
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
Codice:
popl %esi perchè debuggando non mi sembra. Il comando successivo che lavora su esi provoca l'errore |
|
|
|
|
|
#17 |
|
Member
Iscritto dal: Dec 2005
Messaggi: 44
|
|
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
no, credo che ' sia un carattere che gcc non digerisce per quanto riguarda l'assembly...
infatti il compilatore non lo riconosce. e non credo sia un problema di formattazione.... |
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Non sembra neppure a me. Hai modo di postare il dump degli opcode per quel pezzo di codice?
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#20 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
allora il problema l'ho risolto inserendo la stringa direttamente in codifica esadeciamale, evitando così di usare la call per salvare l'indirizzo della stringa seguente nello stack. Mi sembra dopo tutto una piu che buona soluzione...
Codice:
push $0x2f68732f //Inserisco la codifica di "/sh/" nello stack push $0x6e69622f //Inserisco la codifica di "/bin" nello stack mov %esp, %ebx //Prelevo dallo stack l'indirizzo della stringa "/bin/sh/" mov %al, 0x7(%ebx) //Inserisco il byte terminatore di stringa alla fine posto comunque (anche perchè mi piacerebbe capire perchè non funziona) il dump degli opcode relativo al modulo precedente: Codice:
shellcode.o: file format elf32-i386 Disassembly of section .text: 00000000 <main>: 0: eb 21 jmp 23 <offset> 00000002 <shellcode>: 2: 5e pop %esi 3: 89 76 08 mov %esi,0x8(%esi) 6: 31 c0 xor %eax,%eax 8: 88 46 07 mov %al,0x7(%esi) b: 88 46 0c mov %al,0xc(%esi) e: b0 0b mov $0xb,%al 10: 89 f3 mov %esi,%ebx 12: 8d 4e 08 lea 0x8(%esi),%ecx 15: 8d 56 0c lea 0xc(%esi),%edx 18: cd 80 int $0x80 1a: 31 db xor %ebx,%ebx 1c: b8 01 00 00 00 mov $0x1,%eax 21: cd 80 int $0x80 00000023 <offset>: 23: e8 da ff ff ff call 2 <shellcode> 28: 2f das 29: 62 69 6e bound %ebp,0x6e(%ecx) 2c: 2f das 2d: 73 68 jae 97 <offset+0x74> |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 23:40.




















