Skip to content

Instantly share code, notes, and snippets.

@Sasasu
Last active Jul 28, 2019
Embed
What would you like to do?
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dlfcn.h>
#include <sys/mman.h>
#define GO_LIB "./hook.so"
#define SELF_OFFSET 0x000000000031f8c0
#define GO_OFFSET 0x000000000053dc50
static char REAL_PATH[255] = {};
static void* self_cgo_init = NULL;
static void* hook_cgo_init = NULL;
static void* self_get_addr = NULL;
static void* hook_get_addr = NULL;
void hook_self() {
printf("[Step 1] finding Go's http/net.Get\n");
void* self = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL);
if (self == NULL) {
printf("[ERR] dlopen: %s", dlerror());
exit(1);
}
self_cgo_init = dlsym(self, "x_cgo_init");
if (self_cgo_init == NULL) {
printf("[ERR] net/http.Get not find in this runtime: %s\n", dlerror());
exit(1);
}
Dl_info self_go_dl;
dladdr(self_cgo_init, &self_go_dl);
printf("self dl base %p\n", self_go_dl.dli_fbase);
self_get_addr = self_go_dl.dli_fbase + SELF_OFFSET;
printf("self func printer is %p\n", self_get_addr);
printf("[Step 2] finding hook's http/net.Get\n");
void* hook = dlopen(GO_LIB, RTLD_LAZY | RTLD_LOCAL);
if (hook == NULL) {
printf("[ERR] dlopen: %s\n", dlerror());
exit(1);
}
hook_cgo_init = dlsym(hook, "x_cgo_init");
if (hook_cgo_init == NULL) {
printf("[ERR] net/http.Get not find: %s\n", dlerror());
exit(1);
}
Dl_info hook_go_dl;
dladdr(hook_cgo_init, &hook_go_dl);
printf("hook dl base %p\n", hook_go_dl.dli_fbase);
hook_get_addr = hook_go_dl.dli_fbase + GO_OFFSET;
printf("hook func printer is %p\n", hook_get_addr);
}
void open_mem() {
printf("[Step 3] open memeory\n");
int pagesize = sysconf(_SC_PAGE_SIZE);
void* page_base = ((unsigned long long)self_get_addr / pagesize) * pagesize;
printf("self memeory page base is %p\n", page_base);
if (mprotect(page_base, pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) {
perror("[ERR] memprotect:");
exit(1);
}
printf("[Step 4] inject the code\n");
long long jump_offset = 0;
if(self_get_addr > hook_get_addr) {
jump_offset = (long long)self_get_addr - (long long)hook_get_addr;
} else {
jump_offset = (long long)hook_get_addr - (long long)self_get_addr;
}
jump_offset = jump_offset - 5;
printf("jump from %p to %p, offset = 0x%x ", self_get_addr, hook_get_addr, jump_offset);
int index = 0;
char* mem = (char*)self_get_addr;
// 0: 48 b8 cc cc cc cc cc movabs $0xcccccccccccccccc,%rax
// 7: cc cc cc
// a: 50 push %rax
// b: c3 retq
mem[index++] = 0x48;
mem[index++] = 0xb8;
mem[index++] = (0xFF00000000000000 & (unsigned long long) hook_get_addr) >> (8 * 7);
mem[index++] = (0x00FF000000000000 & (unsigned long long) hook_get_addr) >> (8 * 6);
mem[index++] = (0x0000FF0000000000 & (unsigned long long) hook_get_addr) >> (8 * 5);
mem[index++] = (0x000000FF00000000 & (unsigned long long) hook_get_addr) >> (8 * 4);
mem[index++] = (0x00000000FF000000 & (unsigned long long) hook_get_addr) >> (8 * 3);
mem[index++] = (0x0000000000FF0000 & (unsigned long long) hook_get_addr) >> (8 * 2);
mem[index++] = (0x000000000000FF00 & (unsigned long long) hook_get_addr) >> (8 * 1);
mem[index++] = (0x00000000000000FF & (unsigned long long) hook_get_addr) >> (8 * 0);
mem[index++] = 0x50;
mem[index++] = 0xc3;
printf("inject done.\n");
for(int i = 0;i< index;i++) {
printf("%d: %02x\n", i, mem[i] & 0xFF);
}
}
__attribute__((constructor)) static void setup(void) {
printf("I am C code, ");
readlink("/proc/self/exe", REAL_PATH, sizeof(REAL_PATH));
printf("at %s and ready to Go\n", REAL_PATH);
hook_self();
open_mem();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment