Created
August 9, 2025 14:27
-
-
Save kotenok2000/81efed371e08e5afacac147152527fa3 to your computer and use it in GitHub Desktop.
wsl1 exec format error fix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Given that Microsoft has effectively deprioritized addressing core issues in WSL1, I’ve implemented a workaround for this issue with ELF binaries. | |
| The solution uses a custom wrapper (elf_wrapper.c) with ld.so.preload to automatically intercept and redirect ELF execution through /lib64/ld-linux-x86-64.so.2, enabling system-wide compatibility without user intervention. Unlike direct invocations of /lib64/ld-linux-x86-64.so.2, this approach captures ELF execution at the system level, eliminating the need for wrapper scripts, shell aliases, or direct binary modifications with patchelf. | |
| elf_wrapper.c source code: | |
| #define _GNU_SOURCE | |
| #include <dlfcn.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <fcntl.h> | |
| #include <unistd.h> | |
| #include <sys/stat.h> | |
| // Path to the ELF interpreter used to execute ELF binaries | |
| static const char *ld_linux_so = "/lib64/ld-linux-x86-64.so.2"; | |
| // Pointer to the original execve function | |
| static int (*original_execve)(const char *filename, char *const argv[], char *const envp[]) = NULL; | |
| // Wrapper function for execve | |
| int execve(const char *filename, char *const argv[], char *const envp[]) { | |
| if (!original_execve) { | |
| // Load the original execve function | |
| original_execve = dlsym(RTLD_NEXT, "execve"); | |
| } | |
| // Check if the original file has the SUID bit set | |
| struct stat file_stat; | |
| if (stat(filename, &file_stat) == 0 && (file_stat.st_mode & S_ISUID)) { | |
| // If the SUID bit is set, call the original execve directly | |
| return original_execve(filename, argv, envp); | |
| } | |
| // Check if the file is an ELF binary | |
| FILE *file = fopen(filename, "rb"); | |
| if (file) { | |
| char magic[4]; | |
| fread(magic, 1, 4, file); | |
| fclose(file); | |
| // Check the ELF magic number: 0x7f 0x45 0x4c 0x46 | |
| if (memcmp(magic, "\x7f""ELF", 4) == 0) { | |
| int argc; | |
| for (argc = 0; argv[argc] != NULL; argc++); | |
| char **new_argv = malloc((argc + 2) * sizeof(char *)); | |
| new_argv[0] = (char *)ld_linux_so; | |
| new_argv[1] = (char *)filename; | |
| int i; | |
| for (i = 1; i < argc; i++) { | |
| if (argv[i] != NULL) { | |
| new_argv[i + 1] = argv[i]; | |
| } | |
| } | |
| new_argv[i + 1] = NULL; // Finalize the array with NULL | |
| // Execute the binary with the ELF interpreter | |
| int result = original_execve(ld_linux_so, new_argv, envp); | |
| free(new_argv); | |
| return result; | |
| } | |
| } | |
| // If not ELF, execute normally | |
| return original_execve(filename, argv, envp); | |
| } | |
| Run: | |
| sudo gcc -shared -fPIC -o /usr/local/lib/libelf_wrapper.so elf_wrapper.c -ldl | |
| echo "/usr/local/lib/libelf_wrapper.so" | sudo tee -a /etc/ld.so.preload |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment