следующие this инструкции Мне удалось создать только 528 байт размером a.out (когда gcc main.c дал мне 8539 байт большого файла изначально).выполнить двоичный код машины от C
main.c был:
int main(int argc, char** argv) {
return 42;
}
, но я построил a.out из этого сборочного файла вместо:
main.s:
; tiny.asm
BITS 64
GLOBAL _start
SECTION .text
_start:
mov eax, 1
mov ebx, 42
int 0x80
с:
[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
потому что мне нужна машина co де я:
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
файл находится в небольшой 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
теперь я хочу, чтобы выполнить это так:
#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;
}
однако я получаю ошибку сегментации. Мой вопрос: этот раздел текста
4000e0: b8 01 00 00 00 mov $0x1,%eax
4000e5: bb 2a 00 00 00 mov $0x2a,%ebx
4000ea: cd 80 int $0x80
(это машинный код) все, что мне действительно нужно? Что я делаю неправильно (endiannes ??), может быть, мне просто нужно назвать это по-другому с SIGSEGV?
Вы не можете рассматривать несколько случайных байт в качестве функции. Вы должны уважать соглашения о вызовах компилятора и предоставлять подходящие прологи и эпилоги. –
, конечно, эти коды кода генерируются с помощью одного и того же компилятора, а не случайные, так что должно быть хорошо, знаете ли вы, что именно я должен делать? почему я могу запустить его с терминала? – 4pie0
Прежде всего, вам нужно убедиться, что код находится в исполняемой памяти. Попробуйте добавить что-то вроде '__attribute __ ((раздел," .text "))' или аналогичный (см. Руководство). И, как я сказал, обязательно выполните правильные соглашения о вызовах. –