Skip to content

Instantly share code, notes, and snippets.

@MrThanlon
Created October 16, 2023 06:03
Show Gist options
  • Save MrThanlon/382be9909f3c3104688150835a46a731 to your computer and use it in GitHub Desktop.
Save MrThanlon/382be9909f3c3104688150835a46a731 to your computer and use it in GitHub Desktop.
clousure_bind
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
void do_something(void* param) {
printf("%p\n", param);
}
void (*clousure_bind(void(* function)(void*), void* context))(void) {
int pagesize = getpagesize();
if (pagesize < 0) {
perror("getpagesize");
return NULL;
}
unsigned char* ret = memalign(pagesize, pagesize);
void (*oret)(void) = (void (*)(void))ret;
// push %rbq
// mov %rsp,%rbp
memcpy(ret, "\x55\x48\x89\xe5\x48\xbf", 6);
ret += 6;
// movabs %[context],%rdi
memcpy(ret, &context, 8);
ret += 8;
// movabs %[function],$rax
memcpy(ret, "\x48\xb8", 2);
ret += 2;
memcpy(ret, &function, 8);
ret += 8;
// callq *%rax
// nop
// pop %rbq
// retq
memcpy(ret, "\xff\xd0\x90\x5d\xc3", 5);
ret += 5;
if (mprotect(oret, pagesize, PROT_EXEC | PROT_WRITE | PROT_READ) < 0) {
perror("mprotect");
return NULL;
}
return oret;
}
int main(void) {
void (*fp1)(void) = clousure_bind(do_something, (void*)0x123456789abcdef0UL);
void (*fp2)(void) = clousure_bind(do_something, (void*)0x1145141919810UL);
if (fp1 != NULL) {
fp1();
}
if (fp2 != NULL) {
fp2();
}
free((void*)fp1);
free((void*)fp2);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment