/* -*- indent-tabs-mode: nil -*- * * This file is part of Funchook. * https://github.com/kubo/funchook * * Funchook is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 2 of the License, or (at your * option) any later version. * * As a special exception, the copyright holders of this library give you * permission to link this library with independent modules to produce an * executable, regardless of the license terms of these independent * modules, and to copy and distribute the resulting executable under * terms of your choice, provided that you also meet, for each linked * independent module, the terms and conditions of the license of that * module. An independent module is a module which is not derived from or * based on this library. If you modify this library, you may extend this * exception to your version of the library, but you are not obliged to * do so. If you do not wish to do so, delete this exception statement * from your version. * * Funchook is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License * along with Funchook. If not, see . */ #ifndef FUNCHOOK_INTERNAL_H #define FUNCHOOK_INTERNAL_H 1 #include "funchook.h" #include "os_func.h" #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif #ifdef WIN32 #ifdef _WIN64 #define SIZE_T_FMT "I64" #define SIZE_T_WIDTH "16" #else #define SIZE_T_FMT "" #define SIZE_T_WIDTH "8" #endif /* _WIN64 */ #else /* WIN32 */ #if defined(__LP64__) || defined(_LP64) #define SIZE_T_FMT "l" #define SIZE_T_WIDTH "16" #else #ifdef __APPLE__ #define SIZE_T_FMT "z" #else #define SIZE_T_FMT "" #endif #define SIZE_T_WIDTH "8" #endif /* defined(__LP64__) || defined(_LP64) */ #endif /* WIN32 */ #ifndef __GNUC__ #define __attribute__(arg) #endif #define ROUND_DOWN(num, unit) ((num) & ~((unit) - 1)) #define ROUND_UP(num, unit) (((num) + (unit) - 1) & ~((unit) - 1)) #if defined _M_AMD64 || defined __x86_64__ #define CPU_X86_64 #endif #define MAX_INSN_LEN 16 #define MAX_INSN_CHECK_SIZE 256 #define JUMP32_SIZE 5 #ifdef CPU_X86_64 #define JUMP64_SIZE 14 #endif #define TRAMPOLINE_SIZE (JUMP32_SIZE + (MAX_INSN_LEN - 1) + JUMP32_SIZE) /* This must be same with sysconf(_SC_PAGE_SIZE) on Unix * or the dwPageSize member of the SYSTEM_INFO structure on Windows. */ #undef PAGE_SIZE #define PAGE_SIZE 0x1000 /* 4k */ /* This must be same with the dwAllocationGranularity * member of the SYSTEM_INFO structure on Windows. */ #define ALLOCATION_UNIT 0x10000 /* 64k */ typedef struct { void *addr; size_t size; #ifdef WIN32 DWORD protect; #endif } mem_state_t; typedef struct { const uint8_t *dst_addr; intptr_t src_addr_offset; intptr_t pos_offset; } rip_displacement_t; typedef struct funchook_page funchook_page_t; /* Functions in funchook.c */ extern const size_t funchook_size; extern char funchook_debug_file[]; #ifdef CPU_X86_64 int funchook_page_avail(funchook_t *funchook, funchook_page_t *page, int idx, uint8_t *addr, rip_displacement_t *disp); #else #define funchook_page_avail(funchook, page, idx, addr, disp) (1) #endif void funchook_log(funchook_t *funchook, const char *fmt, ...) __attribute__((__format__ (__printf__, 2, 3))); void funchook_set_error_message(funchook_t *funchook, const char *fmt, ...) __attribute__((__format__ (__printf__, 2, 3))); /* Functions in funchook_linux.c & funchook_windows.c */ extern const size_t page_size; extern const size_t allocation_unit; /* windows only */ funchook_t *funchook_alloc(void); int funchook_free(funchook_t *funchook); int funchook_page_alloc(funchook_t *funchook, funchook_page_t **page_out, uint8_t *func, rip_displacement_t *disp); int funchook_page_free(funchook_t *funchook, funchook_page_t *page); int funchook_page_protect(funchook_t *funchook, funchook_page_t *page); int funchook_page_unprotect(funchook_t *funchook, funchook_page_t *page); int funchook_unprotect_begin(funchook_t *funchook, mem_state_t *mstate, void *addr, size_t len); int funchook_unprotect_end(funchook_t *funchook, const mem_state_t *mstate); void *funchook_resolve_func(funchook_t *funchook, void *func); const char *funchook_strerror(int errnum, char *buf, size_t buflen); /* Functions in funchook_x86.c */ int funchook_write_jump32(funchook_t *funchook, const uint8_t *src, const uint8_t *dst, uint8_t *out); #ifdef CPU_X86_64 int funchook_write_jump64(funchook_t *funchook, uint8_t *src, const uint8_t *dst); int funchook_within_32bit_relative(const uint8_t *src, const uint8_t *dst); int funchook_jump32_avail(const uint8_t *src, const uint8_t *dst); #endif int funchook_make_trampoline(funchook_t *funchook, rip_displacement_t *disp, const uint8_t *func, uint8_t *trampoline); void funchook_log_trampoline(funchook_t *funchook, const uint8_t *trampoline); #endif