Skip to content

Instantly share code, notes, and snippets.

@lvzixun
Created January 16, 2015 06:58
Show Gist options
  • Save lvzixun/5feefd4bc120993b82ac to your computer and use it in GitHub Desktop.
Save lvzixun/5feefd4bc120993b82ac to your computer and use it in GitHub Desktop.
#include <sys/mman.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <string.h>
typedef void(*gen_func)();
typedef void(*call_func)();
#define write_ptr(code, offset, addr) do{*((uintptr_t*)(code + offset)) = (uintptr_t)(addr);}while(0)
static void*
_gen_call(uint8_t* code, size_t size) {
size_t* p = (size_t*)mmap(NULL, size + sizeof(size_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
assert(p != MAP_FAILED);
*p++ = size;
memcpy(p, code, size);
assert(mprotect(p-1, size + sizeof(size_t), PROT_EXEC | PROT_READ)==0);
return p;
}
static void
_free_call(void* p) {
size_t* _p = p;
_p--;
assert(munmap(_p, *_p)==0);
}
void
gen_x64(gen_func f) {
uint8_t code[] = {
0x55, // pushq %rbp
0x48, 0x89, 0xe5, // movq %rsp, %rbp
0x48, 0xb9, // movabsq #imm, %rcx
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // #imm
0xff, 0xd1, // callq *%rcx
0x5d, // popq %rbp
0xc3, // ret
};
write_ptr(code, 6, f);
gen_func p = _gen_call(code, sizeof(code));
p();
_free_call(p);
}
void
gen_x32(gen_func f) {
uint8_t code[] = {
0x55, // pushl %ebp
0x89, 0xe5, // movl %esp, %ebp
0x83, 0xec, 0x08, // subl $0x8, %esp
0xb8, // movl #imm, eax
0x00, 0x00, 0x00, 0x00, // #imm
0xff, 0xd0, // call eax
0x83, 0xc4, 0x08, // addl $0x8, %esp
0x5d, // popq %rbp
0xc3, // ret
};
write_ptr(code, 7, f);
gen_func p = _gen_call(code, sizeof(code));
p();
_free_call(p);
}
/*
static void
func(gen_func f) {
f();
}
*/
void
gen_arm64(gen_func f) {
uint32_t code[] = {
0xa9bf7bfd, // stp fp, lr, [sp, #-16]!
0x910003fd, // mov fp, sp
0xd10043ff, // sub sp, sp, #16
0xf90007e0, // str x0, [sp, #8]
0xf94007e0, // ldr x0, [sp, #8]
0xd63f0000, // blr x0
0x910003bf, // mov sp, fp
0xa8c17bfd, // ldp fp, lr, [sp], #16
0xd65f03c0, // ret
};
call_func p = (call_func)_gen_call((uint8_t*)code, sizeof(code));
p(f);
_free_call(p);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment