$ cat > hello.S <<'EOF'
.data
.Lhello:
.ascii "Hello, world\n"
.text
.global _start
_start:
movl $1, %ebx
leal .Lhello, %ecx
movl $13, %edx
movl $4, %eax
int $0x80
movl $1, %eax
xorl %ebx, %ebx
int $0x80
EOF
$ gcc -m32 hello.S -nostdlib -o hello
$ ./hello
Hello, world
$
С голым машинным кодом будет сложнее, т.к. нужно будет согласовать адреса закодированные в нём с тем, что будет прописано в заголовках ELF. Можно сделать примерно такой исходник:
.text
.global _start
_start:
.incbin "code"
в файл code поместить голый машинный код. Компилировать как в первом случае.
Как вариант можно дамп вставить прямо в ассемблер:
.text
.global _start
_start:
.byte 0xbb, 0x01, 0x00, 0x00, 0x00, 0x8d, 0x0d, 0xb8,
.byte 0x80, 0x04, 0x08, 0xba, 0x0d, 0x00, 0x00, 0x00,
.byte 0xb8, 0x04, 0x00, 0x00, 0x00, 0xcd, 0x80, 0xb8,
.byte 0x01, 0x00, 0x00, 0x00, 0x31, 0xdb, 0xcd, 0x80,
.byte 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77,
.byte 0x6f, 0x72, 0x6c, 0x64, 0x0a
Можно зайти с другой стороны и научить линукс выполнять голые бинарники. См.
https://www.kernel.org/doc/Documentation/binfmt_mi...