folgenden Anweisungen Ich habe es geschafft, nur 528 Bytes in der Größe a.out zu produzieren (wenn gcc main.c gab mir 8539 Bytes große Datei zunächst).binären Maschinencode aus C
main.c war:
int main(int argc, char** argv) {
return 42;
}
aber ich habe a.out aus dieser Assembly-Datei stattdessen gebaut:
main.s:
; tiny.asm
BITS 64
GLOBAL _start
SECTION .text
_start:
mov eax, 1
mov ebx, 42
int 0x80
mit:
[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
weil ich Maschine co. Brauche de ich tun:
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
Datei ist in Little-Endian-Konvention:
[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
jetzt ich dies wie folgt ausgeführt werden soll:
#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;
}
aber ich Segmentierungsfehler bekommen. Meine Frage ist: ist dieser Abschnitt des Textes
4000e0: b8 01 00 00 00 mov $0x1,%eax
4000e5: bb 2a 00 00 00 mov $0x2a,%ebx
4000ea: cd 80 int $0x80
(dieser Maschinencode) all wirklich benötige ich? Was mache ich falsch (endiannes ??), muss ich das vielleicht seit SIGSEGV anders nennen?
Sie können ein paar zufälliges Bytes als Funktion nicht nur behandeln. Sie müssen die Aufrufkonventionen des Compilers beachten und geeignete Funktionsprologe und Epiloge bereitstellen. –
natürlich, diese Opcodes sind mit dem gleichen Compiler generiert, und nicht zufällig, so sollte in Ordnung sein, wissen Sie, was genau soll ich tun? Warum kann ich es vom Terminal aus starten? – 4pie0
Zunächst müssen Sie sicherstellen, dass der Code im ausführbaren Speicher liegt. Versuchen Sie etwas wie "__attribute __ ((section," .text "))' oder ähnliches hinzuzufügen (siehe Handbuch). Und wie gesagt, stellen Sie sicher, dass Sie die korrekten Aufrufkonventionen implementieren. –