Fox1942
Fox1942

Reputation: 366

How to intercept Opengl API calls with LD_PRELOAD?

I would like to hook shaders coming from OpenGL API with LD_PRELOAD method on Android 14. I built a shader library with NDK and copied it to my phone and also set the LD_PRELOAD environment variable to it. Unfortunately, I could not get the file. According to adb logcat, the shared library is loaded. When the glShaderSource is called, the shared library should run and write the shader into a file. After that it should call the original function.

Here is my code:

#include <dlfcn.h>
#include <GLES2/gl2.h>
#include <stdio>

// Function pointer to the original glShaderSource function
typedef void (*PFN_glShaderSource)(GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
PFN_glShaderSource real_glShaderSource = nullptr;

void glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) {
    printf("Intercepted glShaderSource!\n");

    FILE *file = fopen("/storage/emulated/0/Download/intercepted_shader.glsl", "w");
    if (!file) {
        fprintf(stderr, "Error opening file to save shader source\n");
        return;
    }

    for (GLsizei i = 0; i < count; ++i) {
        fprintf(file, "Shader source %d:\n%s\n", i, string[i]);
    }

    printf ("File is created.");
    fclose(file);

    // Call the original glShaderSource function
    real_glShaderSource(shader, count, string, length);
}


// Initialize the real function pointers
__attribute__((constructor)) void init() {
    void* handle = dlopen("libGLESv2.so", RTLD_LAZY);
    if (handle) {
        real_glShaderSource = (PFN_glShaderSource)dlsym(handle, "glShaderSource");
    } else {
        printf("Failed to load libGLESv2.so\n");
    }
}

Any help is appreciated!


Update 1:

I had to realize that LD_PRELOAD method is not gonna work. According to this site: link

In Android there is a parent process called Zygote and all the other processes are forked from this one. However setting the LD_PRELOAD environment variable won't affect the app's symbol loading because Zygote doesn't reload the dynamic linker as Zygote process is pre-initialized. So the application has to be launched using “wrap” system property set with LD_PRELOAD value.

At the moment I am using Genymotion to emulate Android on my machine and this way I also got root access. I installed the arm64 based apk to Android 9.0 with Genymotion_ARM_Translation, but the intercepting shared library is still in x86, cause the platform is x86. I got the error below. I guess this is because of the two different architecture.

enter image description here

Upvotes: 0

Views: 54

Answers (0)

Related Questions