po this instrukcji Udało mi się wyprodukować tylko 528 bajtów o rozmiarze a.out (kiedy gcc main.c dał mi początkowo 8539 bajtów dużego pliku).Wykonaj kod maszyny binarnej z C
main.c było:
int main(int argc, char** argv) {
return 42;
}
ale ja zbudowałem a.out z tego pliku zespołu Zamiast:
main.s:
; tiny.asm
BITS 64
GLOBAL _start
SECTION .text
_start:
mov eax, 1
mov ebx, 42
int 0x80
z:
[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
ponieważ potrzebuję maszyny co de zrobić:
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
plik znajduje się w małej konwencji 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
teraz chcę wykonać to tak:
#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;
}
jednak otrzymuję winy segmentacji. Moje pytanie brzmi: czy jest to fragment tekstu
4000e0: b8 01 00 00 00 mov $0x1,%eax
4000e5: bb 2a 00 00 00 mov $0x2a,%ebx
4000ea: cd 80 int $0x80
(ten kod maszynowy) wszystko czego naprawdę potrzebujemy? Co robię źle (endiannes?), Może po prostu muszę to nazwać w inny sposób od SIGSEGV?
nie można traktować tylko kilka losowych bajtów jako funkcja. Musisz przestrzegać konwencji wywoływania kompilatora i dostarczać odpowiednich prologów funkcyjnych i epilogów. –
ofcourse, te kody opcyjne są generowane z tego samego kompilatora, a nie losowe, więc powinno być OK, czy wiesz co dokładnie powinienem zrobić? dlaczego mogę go uruchomić z terminala? – 4pie0
Po pierwsze, upewnij się, że kod znajduje się w pamięci wykonywalnej. Spróbuj dodać coś w rodzaju '__attribute __ ((section," .text ")) lub podobne (patrz instrukcja). Jak już powiedziałem, upewnij się, że implementujesz prawidłowe konwencje wywoływania. –