Easy OpenGL hooking [Linux]

Hexui Undetected CSGO Cheats PUBG Accounts

NTvalk

Hacker
Meme Tier VIP
Jul 6, 2013
499
3,108
8
For people looking for a very easy way to hook OpenGL in linux: use dlsym().

C++:
#define _GNU_SOURCE

/* These libraries are necessary for the hook */
#include <dlfcn.h>
#include <stdlib.h>
#include <GL/gl.h>

/* "Injected" stuff */
#include <stdio.h>
#include <stdint.h>
#include <string.h>

static int framecnt = 0;

// our detour function
void HackFrame() {
        // do our stuff
	framecnt++;
	
	printf("frame %d... \n", framecnt);
}

// hook glClear
void glClear(GLbitfield mask) {
		static void (*lib_glClear)(GLbitfield mask) = NULL;
	void* handle;
	char* errorstr;

	if(!lib_glClear) {
		/* Load real libGL */
		handle = dlopen("/usr/lib/i386-linux-gnu/libGL.so", RTLD_LAZY);
		if(!handle) {
			fputs(dlerror(), stderr);
			exit(1);
		}
		/* Fetch pointer of real glClear() func */
		lib_glClear = dlsym(handle, "glClear");
		if( (errorstr = dlerror()) != NULL ) {
			fprintf(stderr, "dlsym fail: %s\n", errorstr);
			exit(1);
		}
	}

	/* Woot */
	HackFrame();

	/* Call real glClear() */
	lib_glClear(mask);
}
It is very easy to use and also very powerful.
Use it with:
C++:
LD_PRELOAD=./our_library ./our_game

If you are hooking a game that uses wine:
C++:
#define _GNU_SOURCE
#include <dlfcn.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <GL/gl.h>
#include <GL/glx.h>

void hookfunc();

/* 
 * Unfortunately WINE needs to be patched to allow hooking this via
 * LD_PRELOAD.
 *
 * 1) Instead of using the default RTLD loader, WINE retrieves the address
 *    for glXGetProcAddressARB directly from the OpenGL library.
 *    This is done to enable binary compatibility to systems with or without
 *    OpenGL.
 *
 *    Solution: patch WINE to use the default loader
 *
 * 2) WINE gets the pointers to glx functions via glXGetProcAddressARB
 *    
 *    => I'm hooking glXGetProcAddressARB and return my own
 *       pointer to glXSwapBuffers.
 *
 */

typedef __GLXextFuncPtr (*fp_glXGetProcAddressARB) (const GLubyte*);
typedef __GLXextFuncPtr (*fp_glXSwapBuffers)(Display* dpy, GLXDrawable drawable);

// glXSwapBuffers
fp_glXSwapBuffers real_glXSwapBuffers;

void my_glXSwapBuffers(Display* dpy, GLXDrawable drawable) {
	real_glXSwapBuffers(dpy, drawable);
	hookfunc();
}

// glXGetProcAddressARB
__GLXextFuncPtr glXGetProcAddressARB (const GLubyte* procName)
{
	__GLXextFuncPtr result;
	printf("* hook-glx.c: glXGetProcAddressARB(\"%s\")\n", procName);

	// Fetch pointer of actual glXGetProcAddressARB() function
	static fp_glXGetProcAddressARB lib_getprocaddr = NULL;
	if(!lib_getprocaddr)
	{
		char* errorstr;
		lib_getprocaddr = (fp_glXGetProcAddressARB) 
			dlsym(RTLD_NEXT, "glXGetProcAddressARB");
		if( (errorstr = dlerror()) != NULL )
		{
			fprintf(stderr, "dlsym fail: %s\n", errorstr);
			exit(1);
		}
	}
	result = lib_getprocaddr(procName);

	// Return our own function pointers
	if( strcmp( (const char*) procName, "glXSwapBuffers" ) == 0 )
	{
		real_glXSwapBuffers = (fp_glXSwapBuffers) result;
		return (__GLXextFuncPtr) my_glXSwapBuffers;
	}
	
	// Return default function pointer
	return lib_getprocaddr(procName);
}
You will also need to patch wine:
C++:
diff -Nru wine-1.1.39.orig/dlls/winex11.drv/opengl.c wine-1.1.39/dlls/winex11.drv/opengl.c
--- wine-1.1.39.orig/dlls/winex11.drv/opengl.c	2010-02-27 02:21:02.973526893 +0100
+++ wine-1.1.39/dlls/winex11.drv/opengl.c	2010-02-27 02:27:11.231401387 +0100
@@ -412,7 +412,7 @@
         return FALSE;
     }
 
-    pglXGetProcAddressARB = wine_dlsym(opengl_handle, "glXGetProcAddressARB", NULL, 0);
+    pglXGetProcAddressARB = wine_dlsym(RTLD_DEFAULT, "glXGetProcAddressARB", NULL, 0);
     if (pglXGetProcAddressARB == NULL) {
         ERR("Could not find glXGetProcAddressARB in libGL, disabling OpenGL.\n");
         goto failed;
We basicly get a pointer to the glXSwapBuffers function by hooking glXGetProcAddressARB. We do this because wine uses glXGetProcAddressARB to do it, so thats the best way.

credits:
RoKFenris WINE patch
Sednogmah glswapbuffer hook
NOTE: the address to the libGL library may vary on different systems. "/usr/lib/i386-linux-gnu/libGL.so" for me (ubuntu 32bit).
 
Last edited:

c5

Kim Kong Trasher
Dank Tier VIP
Dank Tier Donator
Jul 19, 2012
1,187
19,938
76
Sweet, thanks for sharing :)
 

c5

Kim Kong Trasher
Dank Tier VIP
Dank Tier Donator
Jul 19, 2012
1,187
19,938
76
i hope more people will make hacks for linux..
I think Linux is just for enthusiast, if you want job to be done, stick with windows :)
 

NTvalk

Hacker
Meme Tier VIP
Jul 6, 2013
499
3,108
8
I think Linux is just for enthusiast, if you want job to be done, stick with windows :)
But why? i think you just need to get used to the OS, which takes some time but once you understand how to use it, you dont go back to windows.
 
Community Mods