seguendo le istruzioni this Sono riuscito a produrre solo 528 byte in dimensione a.out (quando gcc main.c mi ha dato inizialmente un grande file 8539 byte).esegui codice macchina binaria da C
main.c era:
int main(int argc, char** argv) {
return 42;
}
ma ho costruito a.out da questo file assembly invece:
main.s:
; tiny.asm
BITS 64
GLOBAL _start
SECTION .text
_start:
mov eax, 1
mov ebx, 42
int 0x80
con:
[email protected]# nasm -f elf64 tiny.s
[email protected]# gcc -Wall -s -nostartfiles -nostdlib tiny.o
[email protected]# ./a.out ; echo $?
42
[email protected]# wc -c a.out
528 a.out
perché ho bisogno di macchina co de faccio:
objdump -d a.out
a.out: file format elf64-x86-64
Disassembly of section .text:
00000000004000e0 <.text>:
4000e0: b8 01 00 00 00 mov $0x1,%eax
4000e5: bb 2a 00 00 00 mov $0x2a,%ebx
4000ea: cd 80 int $0x80
># objdump -hrt a.out
a.out: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .note.gnu.build-id 00000024 00000000004000b0 00000000004000b0 000000b0 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 0000000c 00000000004000e0 00000000004000e0 000000e0 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
SYMBOL TABLE:
no symbols
file è in poco convenzione endian:
[email protected]# readelf -a a.out
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x4000e0
Start of program headers: 64 (bytes into file)
Start of section headers: 272 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 2
Size of section headers: 64 (bytes)
Number of section headers: 4
Section header string table index: 3
ora voglio eseguire questo come questo:
#include <unistd.h>
// which version is (more) correct?
// this might be related to endiannes (???)
char code[] = "\x01\xb8\x00\x00\xbb\x00\x00\x2a\x00\x00\x80\xcd\x00";
char code_v1[] = "\xb8\x01\x00\x00\x00\xbb\x2a\x00\x00\x00\xcd\x80\x00";
int main(int argc, char **argv)
{
/*creating a function pointer*/
int (*func)();
func = (int (*)()) code;
(int)(*func)();
return 0;
}
tuttavia ottengo segmentation fault. La mia domanda è: è questa sezione del testo
4000e0: b8 01 00 00 00 mov $0x1,%eax
4000e5: bb 2a 00 00 00 mov $0x2a,%ebx
4000ea: cd 80 int $0x80
(questo codice macchina) tutto quello che ho veramente bisogno? Cosa faccio di sbagliato (endiannes ??), forse ho solo bisogno di chiamare questo in modo diverso dal SIGSEGV?
non si può solo trattare un paio di byte casuali come una funzione. Devi rispettare le convenzioni di chiamata del compilatore e fornire prologhi ed epiloghi di funzione adeguati. –
naturalmente, questi codici operativi sono generati con lo stesso compilatore e non casuali, quindi dovrebbe essere OK, sai cosa dovrei fare esattamente? perché posso eseguirlo dal terminale? – 4pie0
Prima di tutto, è necessario assicurarsi che il codice risieda nella memoria eseguibile. Prova ad aggiungere qualcosa come '__attribute __ ((section," .text "))' o simili (vedi il manuale). E come ho detto, assicurati di implementare le convenzioni di chiamata corrette. –