Swap out an ELF executable's main function with another function from its symbol table, without touching its code at all.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

67 lines
1.3 KiB

  1. #include <stddef.h>
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <stdio.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <unistd.h>
  8. // TODO: allow for non-native-bitness ELF parsing
  9. #include "manip-exe.h"
  10. int main(int argc, char* argv[]) {
  11. if (argc < 4) {
  12. fprintf(stderr,"usage: %s <input> <output> <symbol>\n", argv[0]);
  13. return 0;
  14. }
  15. const char* symname = argv[3];
  16. FILE* f = fopen(argv[1], "rb");
  17. if (f == NULL) {
  18. fprintf(stderr, "%s: can't open input file '%s'\n", argv[0], argv[1]);
  19. return 1;
  20. }
  21. fseek(f, 0, SEEK_END);
  22. long s = ftell(f);
  23. fseek(f, 0, SEEK_SET);
  24. fprintf(stderr, "s=%zu\n", s);
  25. void* blob = calloc(1, (size_t)s);
  26. if (fread(blob, 1, (size_t)s, f) != (size_t)s) {
  27. fprintf(stderr, "%s: can't read input file '%s'\n", argv[0], argv[1]);
  28. free(blob);
  29. fclose(f);
  30. return 1;
  31. }
  32. fclose(f);
  33. if (manip_elf(blob, symname)) {
  34. fprintf(stderr, "%s: ELF patching failed\n", argv[0]);
  35. free(blob);
  36. return 1;
  37. }
  38. f = fopen(argv[2], "wb");
  39. if (f == NULL) {
  40. fprintf(stderr, "%s: can't open output file '%s'\n", argv[0], argv[2]);
  41. return 1;
  42. }
  43. if (fwrite(blob, 1, (size_t)s, f) != (size_t)s) {
  44. fprintf(stderr, "%s: can't write output file '%s'\n", argv[0], argv[2]);
  45. free(blob);
  46. fclose(f);
  47. return 1;
  48. }
  49. fclose(f);
  50. free(blob);
  51. return 0;
  52. }