Linux x86_64 gcc, .
?
, . JIT (Just-in-time). . this.
, .
, JavaScript, JIT-.
C- hello , . gcc, " " .
"Segmentation fault" .
:
int size = 10000;
x86_64 , gcc
hello, 17 :
0000000000400626 <hello>:
400626: 55 push %rbp
400627: 48 89 e5 mov %rsp,%rbp
40062a: bf 98 07 40 00 mov $0x400798,%edi
40062f: e8 9c fe ff ff call 4004d0 <puts@plt>
400634: 90 nop
400635: 5d pop %rbp
400636: c3 retq
, 10 000 ,
"Segmentation fault".
-, malloc,
, Linux x86_64,
"Segmentation fault".
malloc brk, sbrk mmap. , mmap PROT_EXEC.
-, gcc hello, , , .
, 4 hello
40062f: e8 9c fe ff ff call 4004d0 <puts@plt>
gcc puts printf,
.
x86 , , call
, , , , call , . Intel Vol, 2A 3-123, .
call.
, call e8 :
E8 - Call near, relative, displacement relative to next instruction. 32-bit displacement sign extended to 64-bits in 64-bit mode.
, .
, memcpy , call, , , , , "Segmentation fault".
, ? !
, :
- ,
printf , , gcc . - , , .
mmap PROT_EXEC.- Pass
printf heap_function,
gcc call.
:
#include "stdio.h"
#include "string.h"
#include <stdint.h>
#include <sys/mman.h>
typedef int (*printf_t)(char* format, char* string);
typedef int (*heap_function_t)(printf_t myprintf, char* str, int a, int b);
int heap_function(printf_t myprintf, char* str, int a, int b) {
myprintf("%s", str);
return a + b;
}
int heap_function_end() {
return 0;
}
int main(void) {
printf("%s", "Just including printf in binary\n");
size_t size = (size_t) ((intptr_t) heap_function_end - (intptr_t) heap_function);
char* buffer = (char*) mmap(0, (size_t) size,
PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
memcpy(buffer, (char*)heap_function, size);
heap_function_t fp = (heap_function_t) buffer;
int res = fp((void*) printf, "Hello world, from heap!\n", 1, 2);
printf("a + b = %i\n", res);
}
main.c :
gcc -o main main.c && ./main