struct workqueue_struct *__create_workqueue(const char *name, int singlethread) { static struct workqueue_struct *(*func)(const char *name, int singlethread); if (func == NULL) func = get_proc_addr("__create_workqueue"); return func(name, singlethread); }
int dtrace_xen_hypercall(int call, void *a, void *b, void *c) { #if DO_XEN static char *hypercall_page; static int (*hp)(void *, void *, void *); int ret; if (!dtrace_is_xen()) return 0; /***********************************************/ /* hypercall_page is GPL protected and is */ /* an assembly level parameter coming from */ /* <hypercall.h>, so work around that. We */ /* need to be low level to get to the Xen */ /* API (allow as much dtrace probing as */ /* possible), so we have to do what the */ /* kernel is doing (approximately). */ /***********************************************/ if (hypercall_page == NULL) hypercall_page = get_proc_addr("hypercall_page"); if (hypercall_page == NULL) return 0; hp = (void *) (hypercall_page + call * 32); ret = hp(a, b, c); return ret; #endif /* DO_XEN */ }
//------------------------------------------------------------------------------ void* hook_jmp(const char* dll, const char* func_name, void* hook) { void* func_addr; void* trampoline; // Get the address of the function we're going to hook. func_addr = get_proc_addr(dll, func_name); if (func_addr == NULL) { LOG_INFO("Failed to find function '%s' in '%s'", dll, func_name); return NULL; } LOG_INFO("Attemping jump hook."); LOG_INFO("Target is %s, %s @ %p", dll, func_name, func_addr); // Install the hook. trampoline = hook_jmp_impl(func_addr, hook); if (trampoline == NULL) { LOG_INFO("Jump hook failed."); return NULL; } LOG_INFO("Success!"); FlushInstructionCache(current_proc(), 0, 0); return trampoline; }
static void send_ipi_interrupt(cpumask_t *mask, int vector) { # if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) /***********************************************/ /* Theres 'flat' and theres 'cluster'. The */ /* cluster functions handle more than 8 */ /* cpus. The flat does not - since the APIC */ /* only has room for an 8-bit cpu mask. */ /***********************************************/ static void (*send_IPI_mask)(cpumask_t, int); if (send_IPI_mask == NULL) send_IPI_mask = get_proc_addr("cluster_send_IPI_mask"); if (send_IPI_mask == NULL) dtrace_printf("HELP ON send_ipi_interrupt!\n"); else send_IPI_mask(*mask, vector); # elif LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 28) /***********************************************/ /* Issue with GPL/inlined function. */ /***********************************************/ { void send_IPI_mask_sequence(cpumask_t mask, int vector); static void (*send_IPI_mask_sequence_ptr)(cpumask_t, int); if (send_IPI_mask_sequence_ptr == NULL) send_IPI_mask_sequence_ptr = get_proc_addr("send_IPI_mask_sequence"); send_IPI_mask_sequence_ptr(*mask, vector); } # elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28) send_IPI_mask(*mask, vector); # else if (x_apic == NULL) { static void (*flat_send_IPI_mask)(cpumask_t *, int); if (flat_send_IPI_mask == NULL) flat_send_IPI_mask = get_proc_addr("flat_send_IPI_mask"); if (flat_send_IPI_mask) { flat_send_IPI_mask(mask, vector); return; } dtrace_linux_panic("x_apic is null - giving up\n"); return; } x_apic->send_IPI_mask(mask, vector); # endif }
void Pure_gluNurbsCallbackDataEXT(GLUnurbs* arg0, void* arg1) { static void(APIENTRY*ptr)(GLUnurbs* arg0, void* arg1) = NULL; static const char name[] = "gluNurbsCallbackDataEXT"; if (!ptr) { ptr = (void(APIENTRY*)(GLUnurbs* arg0, void* arg1))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0, arg1); }
void Pure_gluEndTrim(GLUnurbs* arg0) { static void(APIENTRY*ptr)(GLUnurbs* arg0) = NULL; static const char name[] = "gluEndTrim"; if (!ptr) { ptr = (void(APIENTRY*)(GLUnurbs* arg0))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0); }
void Pure_gluTessProperty(GLUtesselator* arg0, unsigned int arg1, double arg2) { static void(APIENTRY*ptr)(GLUtesselator* arg0, unsigned int arg1, double arg2) = NULL; static const char name[] = "gluTessProperty"; if (!ptr) { ptr = (void(APIENTRY*)(GLUtesselator* arg0, unsigned int arg1, double arg2))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0, arg1, arg2); }
void Pure_gluTessEndPolygon(GLUtesselator* arg0) { static void(APIENTRY*ptr)(GLUtesselator* arg0) = NULL; static const char name[] = "gluTessEndPolygon"; if (!ptr) { ptr = (void(APIENTRY*)(GLUtesselator* arg0))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0); }
void Pure_gluSphere(GLUquadric* arg0, double arg1, int arg2, int arg3) { static void(APIENTRY*ptr)(GLUquadric* arg0, double arg1, int arg2, int arg3) = NULL; static const char name[] = "gluSphere"; if (!ptr) { ptr = (void(APIENTRY*)(GLUquadric* arg0, double arg1, int arg2, int arg3))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0, arg1, arg2, arg3); }
void Pure_gluQuadricTexture(GLUquadric* arg0, unsigned char arg1) { static void(APIENTRY*ptr)(GLUquadric* arg0, unsigned char arg1) = NULL; static const char name[] = "gluQuadricTexture"; if (!ptr) { ptr = (void(APIENTRY*)(GLUquadric* arg0, unsigned char arg1))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0, arg1); }
void osinit(void) { void *base; base = get_kernel_module(); GetProcAddress = get_proc_addr2(base, (byte*)"GetProcAddress"); LoadLibraryEx = get_proc_addr2(base, (byte*)"LoadLibraryExA"); CloseHandle = get_proc_addr("kernel32.dll", "CloseHandle"); CreateEvent = get_proc_addr("kernel32.dll", "CreateEventA"); CreateThread = get_proc_addr("kernel32.dll", "CreateThread"); ExitProcess = get_proc_addr("kernel32.dll", "ExitProcess"); GetModuleHandle = get_proc_addr("kernel32.dll", "GetModuleHandleA"); GetStdHandle = get_proc_addr("kernel32.dll", "GetStdHandle"); SetEvent = get_proc_addr("kernel32.dll", "SetEvent"); VirtualAlloc = get_proc_addr("kernel32.dll", "VirtualAlloc"); WaitForSingleObject = get_proc_addr("kernel32.dll", "WaitForSingleObject"); WriteFile = get_proc_addr("kernel32.dll", "WriteFile"); }
void Pure_gluNextContour(GLUtesselator* arg0, unsigned int arg1) { static void(APIENTRY*ptr)(GLUtesselator* arg0, unsigned int arg1) = NULL; static const char name[] = "gluNextContour"; if (!ptr) { ptr = (void(APIENTRY*)(GLUtesselator* arg0, unsigned int arg1))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0, arg1); }
GLUtesselator* Pure_gluNewTess() { static GLUtesselator*(APIENTRY*ptr)() = NULL; static const char name[] = "gluNewTess"; if (!ptr) { ptr = (GLUtesselator*(APIENTRY*)())get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(); }
GLUquadric* Pure_gluNewQuadric() { static GLUquadric*(APIENTRY*ptr)() = NULL; static const char name[] = "gluNewQuadric"; if (!ptr) { ptr = (GLUquadric*(APIENTRY*)())get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(); }
GLUnurbs* Pure_gluNewNurbsRenderer() { static GLUnurbs*(APIENTRY*ptr)() = NULL; static const char name[] = "gluNewNurbsRenderer"; if (!ptr) { ptr = (GLUnurbs*(APIENTRY*)())get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(); }
unsigned char const* Pure_gluGetString(unsigned int arg0) { static unsigned char const*(APIENTRY*ptr)(unsigned int arg0) = NULL; static const char name[] = "gluGetString"; if (!ptr) { ptr = (unsigned char const*(APIENTRY*)(unsigned int arg0))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0); }
void Pure_gluGetNurbsProperty(GLUnurbs* arg0, unsigned int arg1, float* arg2) { static void(APIENTRY*ptr)(GLUnurbs* arg0, unsigned int arg1, float* arg2) = NULL; static const char name[] = "gluGetNurbsProperty"; if (!ptr) { ptr = (void(APIENTRY*)(GLUnurbs* arg0, unsigned int arg1, float* arg2))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0, arg1, arg2); }
void Pure_gluPerspective(double arg0, double arg1, double arg2, double arg3) { static void(APIENTRY*ptr)(double arg0, double arg1, double arg2, double arg3) = NULL; static const char name[] = "gluPerspective"; if (!ptr) { ptr = (void(APIENTRY*)(double arg0, double arg1, double arg2, double arg3))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0, arg1, arg2, arg3); }
void Pure_gluQuadricCallback(GLUquadric* arg0, unsigned int arg1, void* arg2) { static void(APIENTRY*ptr)(GLUquadric* arg0, unsigned int arg1, void* arg2) = NULL; static const char name[] = "gluQuadricCallback"; if (!ptr) { ptr = (void(APIENTRY*)(GLUquadric* arg0, unsigned int arg1, void* arg2))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0, arg1, arg2); }
void mingw_goargs(void) { extern Slice os·Args; extern Slice os·Envs; void *gcl, *clta, *ges; uint16 *cmd, *env, **argv; String *gargv; String *genvv; int32 i, argc, envc; uint16 *envp; gcl = get_proc_addr("kernel32.dll", "GetCommandLineW"); clta = get_proc_addr("shell32.dll", "CommandLineToArgvW"); ges = get_proc_addr("kernel32.dll", "GetEnvironmentStringsW"); cmd = stdcall(gcl); env = stdcall(ges); argv = stdcall(clta, cmd, &argc); envc = 0; for(envp=env; *envp; envc++) envp += findnullw(envp)+1; gargv = malloc(argc*sizeof gargv[0]); genvv = malloc(envc*sizeof genvv[0]); for(i=0; i<argc; i++) gargv[i] = gostringw(argv[i]); os·Args.array = (byte*)gargv; os·Args.len = argc; os·Args.cap = argc; envp = env; for(i=0; i<envc; i++) { genvv[i] = gostringw(envp); envp += findnullw(envp)+1; } os·Envs.array = (byte*)genvv; os·Envs.len = envc; os·Envs.cap = envc; }
void Pure_gluTessVertex(GLUtesselator* arg0, double* arg1, void* arg2) { static void(APIENTRY*ptr)(GLUtesselator* arg0, double* arg1, void* arg2) = NULL; static const char name[] = "gluTessVertex"; if (!ptr) { ptr = (void(APIENTRY*)(GLUtesselator* arg0, double* arg1, void* arg2))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0, arg1, arg2); }
void Pure_gluDeleteQuadric(GLUquadric* arg0) { static void(APIENTRY*ptr)(GLUquadric* arg0) = NULL; static const char name[] = "gluDeleteQuadric"; if (!ptr) { ptr = (void(APIENTRY*)(GLUquadric* arg0))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0); }
void xcall_init(void) { if ((x_apic = get_proc_addr("apic")) == NULL) { /***********************************************/ /* This might be a problem. It might not. */ /***********************************************/ printk("init_xcall: cannot locate 'apic'\n"); return; } x_apic = *(void **) x_apic; }
void xcall_init(void) { int i; if ((x_apic = get_proc_addr("apic")) == NULL && (x_apic = get_proc_addr("apic_ops")) == NULL) { /***********************************************/ /* This might be a problem. It might not. */ /***********************************************/ printk("init_xcall: cannot locate 'apic'\n"); } if (x_apic) x_apic = *(void **) x_apic; for (i = 0; i < nr_cpus; i++) { xcalls[i] = kzalloc(nr_cpus * sizeof (struct xcalls), GFP_KERNEL); if (xcalls[i] == NULL) { dtrace_linux_panic("Cannot allocate xcalls[%d][%d] array.\n", nr_cpus, nr_cpus); return; } } }
/**********************************************************************/ # if !defined(WR_MEM_RECLAIM) /* Introduced in 2.6.37 */ struct workqueue_struct * __create_workqueue_key(const char *name, int singlethread, int freezeable, int rt, struct lock_class_key *key, const char *lock_name) { static void *(*func)(const char *name, int singlethread, int freezeable, int rt, struct lock_class_key *key, const char *lock_name); if (func == NULL) func = get_proc_addr("__create_workqueue_key"); if (func == NULL) return NULL; return func(name, singlethread, freezeable, rt, key, lock_name); }
int dtrace_is_xen(void) { static void **xen_start_info; static int first_time = TRUE; // return xen_domain(); if (first_time && xen_start_info == NULL) { xen_start_info = get_proc_addr("xen_start_info"); first_time = FALSE; } if (xen_start_info && *xen_start_info) return TRUE; return FALSE; }
//------------------------------------------------------------------------------ void* hook_iat( void* base, const char* dll, const char* func_name, void* hook, int find_by_name ) { void* func_addr; void* prev_addr; void** imp; LOG_INFO("Attempting to hook IAT for module %p", base); LOG_INFO("Target is %s,%s (by_name=%d)", dll, func_name, find_by_name); // Find entry and replace it. if (find_by_name) { imp = get_import_by_name(base, NULL, func_name); } else { // Get the address of the function we're going to hook. func_addr = get_proc_addr(dll, func_name); if (func_addr == NULL) { LOG_INFO("Failed to find function '%s' in '%s'", func_name, dll); return NULL; } imp = get_import_by_addr(base, NULL, func_addr); } if (imp == NULL) { LOG_INFO("Unable to find import in IAT (by_name=%d)", find_by_name); return NULL; } LOG_INFO("Found import at %p (value = %p)", imp, *imp); prev_addr = *imp; write_addr(imp, hook); FlushInstructionCache(current_proc(), 0, 0); return prev_addr; }
static void send_ipi_interrupt(cpumask_t *mask, int vector) { # if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) /***********************************************/ /* Theres 'flat' and theres 'cluster'. The */ /* cluster functions handle more than 8 */ /* cpus. The flat does not - since the APIC */ /* only has room for an 8-bit cpu mask. */ /***********************************************/ static void (*send_IPI_mask)(cpumask_t, int); if (send_IPI_mask == NULL) send_IPI_mask = get_proc_addr("cluster_send_IPI_mask"); if (send_IPI_mask == NULL) dtrace_printf("HELP ON send_ipi_interrupt!\n"); else send_IPI_mask(*mask, vector); # elif LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 28) send_IPI_mask_sequence(*mask, vector); # elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28) send_IPI_mask(*mask, vector); # else x_apic->send_IPI_mask(mask, vector); # endif }
int Pure_gluUnProject4(double arg0, double arg1, double arg2, double arg3, double const* arg4, double const* arg5, int const* arg6, double arg7, double arg8, double* arg9, double* arg10, double* arg11, double* arg12) { static int(APIENTRY*ptr)(double arg0, double arg1, double arg2, double arg3, double const* arg4, double const* arg5, int const* arg6, double arg7, double arg8, double* arg9, double* arg10, double* arg11, double* arg12) = NULL; static const char name[] = "gluUnProject4"; if (!ptr) { ptr = (int(APIENTRY*)(double arg0, double arg1, double arg2, double arg3, double const* arg4, double const* arg5, int const* arg6, double arg7, double arg8, double* arg9, double* arg10, double* arg11, double* arg12))get_proc_addr(name); if (!ptr) throw_unsupported(name); } return (*ptr)(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); }
void init_heap (bool use_dynamic_heap) { /* FIXME: Remove the condition, the 'else' branch below, and all the related definitions and code, including dumped_data[], when unexec support is removed from Emacs. */ if (use_dynamic_heap) { /* After dumping, use a new private heap. We explicitly enable the low fragmentation heap (LFH) here, for the sake of pre Vista versions. Note: this will harmlessly fail on Vista and later, where the low-fragmentation heap is enabled by default. It will also fail on pre-Vista versions when Emacs is run under a debugger; set _NO_DEBUG_HEAP=1 in the environment before starting GDB to get low fragmentation heap on XP and older systems, for the price of losing "certain heap debug options"; for the details see http://msdn.microsoft.com/en-us/library/windows/desktop/aa366705%28v=vs.85%29.aspx. */ data_region_end = data_region_base; /* Create the private heap. */ heap = HeapCreate (0, 0, 0); #ifndef MINGW_W64 unsigned long enable_lfh = 2; /* Set the low-fragmentation heap for OS before Vista. */ HMODULE hm_kernel32dll = LoadLibrary ("kernel32.dll"); HeapSetInformation_Proc s_pfn_Heap_Set_Information = (HeapSetInformation_Proc) get_proc_addr (hm_kernel32dll, "HeapSetInformation"); if (s_pfn_Heap_Set_Information != NULL) { if (s_pfn_Heap_Set_Information ((PVOID) heap, HeapCompatibilityInformation, &enable_lfh, sizeof(enable_lfh)) == 0) DebPrint (("Enabling Low Fragmentation Heap failed: error %ld\n", GetLastError ())); } #endif if (os_subtype == OS_9X) { the_malloc_fn = malloc_after_dump_9x; the_realloc_fn = realloc_after_dump_9x; the_free_fn = free_after_dump_9x; } else { the_malloc_fn = malloc_after_dump; the_realloc_fn = realloc_after_dump; the_free_fn = free_after_dump; } } else /* Before dumping with unexec: use static heap. */ { /* Find the RtlCreateHeap function. Headers for this function are provided with the w32 DDK, but the function is available in ntdll.dll since XP. */ HMODULE hm_ntdll = LoadLibrary ("ntdll.dll"); RtlCreateHeap_Proc s_pfn_Rtl_Create_Heap = (RtlCreateHeap_Proc) get_proc_addr (hm_ntdll, "RtlCreateHeap"); /* Specific parameters for the private heap. */ RTL_HEAP_PARAMETERS params; ZeroMemory (¶ms, sizeof(params)); params.Length = sizeof(RTL_HEAP_PARAMETERS); data_region_base = (unsigned char *)ROUND_UP (dumped_data, 0x1000); data_region_end = bc_limit = dumped_data + DUMPED_HEAP_SIZE; params.InitialCommit = committed = 0x1000; params.InitialReserve = sizeof(dumped_data); /* Use our own routine to commit memory from the dumped_data array. */ params.CommitRoutine = &dumped_data_commit; /* Create the private heap. */ if (s_pfn_Rtl_Create_Heap == NULL) { fprintf (stderr, "Cannot build Emacs without RtlCreateHeap being available; exiting.\n"); exit (-1); } heap = s_pfn_Rtl_Create_Heap (0, data_region_base, 0, 0, NULL, ¶ms); if (os_subtype == OS_9X) { fprintf (stderr, "Cannot dump Emacs on Windows 9X; exiting.\n"); exit (-1); } else { the_malloc_fn = malloc_before_dump; the_realloc_fn = realloc_before_dump; the_free_fn = free_before_dump; } } /* Update system version information to match current system. */ cache_system_info (); }