fork download
  1. #define _POSIX_C_SOURCE 200112L
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <stdint.h>
  7. #include <unistd.h>
  8. #include <sys/types.h>
  9.  
  10. #if defined(__i386__)
  11. #define LD "/lib/ld-linux.so.2"
  12. #elif defined(__x86_64__)
  13. #define LD "/lib64/ld-linux-x86-64.so.2"
  14. #else
  15. #error "expected x86"
  16. #endif
  17.  
  18. static void execve_wrapper(const char *pgm, char *argv[], char *envp[])
  19. {
  20. printf("execve(\"%s\", {", pgm);
  21. for (int i = 0; argv[i]; i++) {
  22. printf("\"%s\"%s", argv[i], (argv[i + 1]) ? ", " : "});\n\n");
  23. }
  24. fflush(stdout);
  25. execve(pgm, argv, envp);
  26. perror("execve()");
  27. exit(EXIT_FAILURE);
  28. }
  29.  
  30. int main(int argc, char *argv[], char *envp[])
  31. {
  32. char self[1024];
  33. size_t rc = readlink("/proc/self/exe", self, sizeof(self));
  34. if (rc == -1) {
  35. perror("readlink()");
  36. exit(EXIT_FAILURE);
  37. }
  38. self[rc] = '\0';
  39.  
  40. printf("/proc/self/exe -> %s\n", self);
  41. for (int i = 0; i < argc; i++) {
  42. printf("argv[%i] = \"%s\"\n", i, argv[i]);
  43. }
  44.  
  45. if (argc < 2) {
  46. puts("Мы не можем доверять argv[0], там может быть любой мусор");
  47. execve_wrapper(self, (char *[]){"C:\\WINDOWS\\NOTEPAD.EXE", "stage=ld", NULL}, envp);
  48. } else if (strcmp(argv[1], "stage=ld") == 0) {
  49. puts("Но /proc/self/exe мы тоже не можем доверять");
  50. execve_wrapper(LD, (char *[]){LD, self, "stage=done", NULL}, envp);
  51. } else if (strcmp(argv[1], "stage=done") == 0) {
  52. return 0;
  53. }
  54. }
  55.  
Success #stdin #stdout 0s 11472KB
stdin
Standard input is empty
stdout
/proc/self/exe -> /home/cKvVYH/prog
argv[0] = "./prog"
Мы не можем доверять argv[0], там может быть любой мусор
execve("/home/cKvVYH/prog", {"C:\WINDOWS\NOTEPAD.EXE", "stage=ld"});

/proc/self/exe -> /home/cKvVYH/prog
argv[0] = "C:\WINDOWS\NOTEPAD.EXE"
argv[1] = "stage=ld"
Но /proc/self/exe мы тоже не можем доверять
execve("/lib64/ld-linux-x86-64.so.2", {"/lib64/ld-linux-x86-64.so.2", "/home/cKvVYH/prog", "stage=done"});

/proc/self/exe -> /lib/x86_64-linux-gnu/ld-2.24.so
argv[0] = "/home/cKvVYH/prog"
argv[1] = "stage=done"