spacepaste

  1.  
  2. void map() {
  3. if (library[library_index].is_mapped == 0) {
  4. library[library_index]._elf_header = (Elf64_Ehdr *) library[library_index].array;
  5. library[library_index]._elf_program_header = (Elf64_Phdr *)((unsigned long)library[library_index]._elf_header + library[library_index]._elf_header->e_phoff);
  6. /*
  7. the very first thing we do is obtain the base address
  8. Base Address
  9. The virtual addresses in the program headers might not represent the actual virtual addresses
  10. of the program's memory image. Executable files typically contain absolute code. To let the
  11. process execute correctly, the segments must reside at the virtual addresses used to build the
  12. executable file. On the other hand, shared object segments typically contain
  13. position-independent code. This lets a segment's virtual address change from one process to
  14. another, without invalidating execution behavior. Though the system chooses virtual addresses
  15. for individual processes, it maintains the segments’ relative positions. Because
  16. position-independent code uses relative addressing between segments, the difference between
  17. virtual addresses in memory must match the difference between virtual addresses in the file.
  18. The difference between the virtual address of any segment in memory and the corresponding
  19. virtual address in the file is thus a single constant value for any one executable or shared object
  20. in a given process. This difference is the base address. One use of the base address is to relocate
  21. the memory image of the program during dynamic linking.
  22. An executable or shared object file's base address is calculated during execution from three
  23. values: the virtual memory load address, the maximum page size, and the lowest virtual address
  24. of a program's loadable segment. To compute the base address, one determines the memory
  25. address associated with the lowest p_vaddr value for a PT_LOAD segment. This address is
  26. truncated to the nearest multiple of the maximum page size. The corresponding p_vaddr value
  27. itself is also truncated to the nearest multiple of the maximum page size. The base address is
  28. the difference between the truncated memory address and the truncated p_vaddr value.
  29. */
  30. // aquire the first and last PT_LOAD'S
  31. int PT_LOADS=0;
  32. for (int i = 0; i < library[library_index]._elf_header->e_phnum; ++i) {
  33. switch(library[library_index]._elf_program_header[i].p_type)
  34. {
  35. case PT_LOAD:
  36. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "i = %d\n", i);
  37. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "PT_LOADS = %d\n", PT_LOADS);
  38. if (!PT_LOADS) {
  39. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "saving first load\n");
  40. library[library_index].First_Load_Header_index = i;
  41. }
  42. if (PT_LOADS) {
  43. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "saving last load\n");
  44. library[library_index].Last_Load_Header_index = i;
  45. }
  46. PT_LOADS=PT_LOADS+1;
  47. break;
  48. }
  49. }
  50. size_t span = library[library_index]._elf_program_header[library[library_index].Last_Load_Header_index].p_vaddr + library[library_index]._elf_program_header[library[library_index].Last_Load_Header_index].p_memsz - library[library_index]._elf_program_header[library[library_index].First_Load_Header_index].p_vaddr;
  51. read_fast_verifyb(library[library_index].array, library[library_index].len, &library[library_index].mapping_start, span, library[library_index]._elf_program_header[library[library_index].First_Load_Header_index], library[library_index]._elf_program_header[library[library_index].Last_Load_Header_index]);
  52. fprintf(stderr, "library[library_index]._elf_program_header[library[library_index].Last_Load_Header_index].p_vaddr = %014p\n", library[library_index]._elf_program_header[library[library_index].Last_Load_Header_index].p_vaddr);
  53. // aquire the lowest PT_LOAD'S
  54. Elf64_Addr lowest_p_vaddr = 0;
  55. int lowest_idx = -1;
  56. for (int i = 0; i < library[library_index]._elf_header->e_phnum; ++i) {
  57. switch(library[library_index]._elf_program_header[i].p_type)
  58. {
  59. case PT_LOAD:
  60. if (!lowest_p_vaddr) {
  61. lowest_p_vaddr = library[library_index]._elf_program_header[i].p_vaddr;
  62. lowest_idx = i;
  63. }
  64. if (lowest_p_vaddr < library[library_index]._elf_program_header[i].p_memsz) {
  65. lowest_p_vaddr = library[library_index]._elf_program_header[i].p_vaddr;
  66. lowest_idx = i;
  67. }
  68. break;
  69. }
  70. }
  71. size_t pagesize = 0x1000;
  72. if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "library[library_index]._elf_program_header[lowest_idx].p_paddr = %014p\nlibrary[library_index]._elf_program_header[lowest_idx].p_vaddr = %014p\n",library[library_index]._elf_program_header[lowest_idx].p_paddr, library[library_index]._elf_program_header[lowest_idx].p_vaddr);
  73. Elf64_Addr truncated_physical_address = round_down(library[library_index]._elf_program_header[lowest_idx].p_paddr, pagesize);
  74. Elf64_Addr truncated_virtual_address = round_down(library[library_index]._elf_program_header[lowest_idx].p_vaddr, pagesize);
  75. library[library_index].base_address = truncated_physical_address - truncated_virtual_address;
  76. library[library_index].align = round_nearest(library[library_index]._elf_program_header[library[library_index].Last_Load_Header_index].p_vaddr, pagesize);
  77. library[library_index].mapping_end = library[library_index].mapping_start+span;
  78. if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "base address range = %014p - %014p\nmapping = %014p\nbase address = %014p\n", library[library_index].mapping_start, library[library_index].mapping_end, library[library_index].mapping_start, library[library_index].base_address);
  79. // abort_();
  80. // base address aquired, map all PT_LOAD segments adjusting by base address then continue with the rest
  81. if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\n\n\nfind %014p, %014p, (int) 1239\n\n\n\n", library[library_index].mapping_start, library[library_index].mapping_end);
  82. if (library[library_index].mapping_start == 0x00000000) abort_();
  83. int PT_LOADS_CURRENT = 0;
  84. for (int i = 0; i < library[library_index]._elf_header->e_phnum; ++i) {
  85. switch(library[library_index]._elf_program_header[i].p_type)
  86. {
  87. case PT_LOAD:
  88. PT_LOADS_CURRENT = PT_LOADS_CURRENT + 1;
  89. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "mapping PT_LOAD number %d\n", PT_LOADS_CURRENT);
  90. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_flags: %014p\n", library[library_index]._elf_program_header[i].p_flags);
  91. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_offset: %014p\n", library[library_index]._elf_program_header[i].p_offset);
  92. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_vaddr: %014p\n", library[library_index]._elf_program_header[i].p_vaddr+library[library_index].mapping_start);
  93. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_paddr: %014p\n", library[library_index]._elf_program_header[i].p_paddr);
  94. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_filesz: %014p\n", library[library_index]._elf_program_header[i].p_filesz);
  95. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_memsz: %014p\n", library[library_index]._elf_program_header[i].p_memsz);
  96. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\t\tp_align: %014p\n\n", library[library_index]._elf_program_header[i].p_align);
  97. //
  98. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "\tp_flags: %014p", library[library_index]._elf_program_header[i].p_flags);
  99. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, " p_offset: %014p", library[library_index]._elf_program_header[i].p_offset);
  100. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, " p_vaddr: %014p", library[library_index]._elf_program_header[i].p_vaddr+library[library_index].mapping_start);
  101. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, " p_paddr: %014p", library[library_index]._elf_program_header[i].p_paddr);
  102. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, " p_filesz: %014p", library[library_index]._elf_program_header[i].p_filesz);
  103. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, " p_memsz: %014p", library[library_index]._elf_program_header[i].p_memsz);
  104. // if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, " p_align: %014p\n\n\n", library[library_index]._elf_program_header[i].p_align);
  105. if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "mprotect(%014p+round_down(%014p, %014p), %014p, ", library[library_index].mapping_start, library[library_index]._elf_program_header[i].p_vaddr, library[library_index]._elf_program_header[i].p_align, library[library_index]._elf_program_header[i].p_memsz);
  106. prot_from_phdr(library[library_index]._elf_program_header[i].p_flags);
  107. if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, ");\n");
  108. errno = 0;
  109. int check_mprotect_success = mprotect(library[library_index].mapping_start+round_down(library[library_index]._elf_program_header[i].p_vaddr, library[library_index]._elf_program_header[i].p_align), round_up(library[library_index]._elf_program_header[i].p_memsz, library[library_index]._elf_program_header[i].p_align), library[library_index]._elf_program_header[i].p_flags);
  110. if (errno == 0)
  111. {
  112. if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "mprotect on %014p succeded with size: %014p\n", library[library_index].mapping_start+round_down(library[library_index]._elf_program_header[i].p_vaddr, library[library_index]._elf_program_header[i].p_align), round_up(library[library_index]._elf_program_header[i].p_memsz, library[library_index]._elf_program_header[i].p_align));
  113. print_maps();
  114. }
  115. else
  116. {
  117. if (bytecmpq(global_quiet, "no") == 0) fprintf(stderr, "mprotect failed with: %s (errno: %d, check_mprotect_success = %d)\n", strerror(errno), errno, check_mprotect_success);
  118. print_maps();
  119. abort_();
  120. }
  121. break;
  122. }
  123. }
  124. library[library_index].is_mapped = 1;
  125. }
  126. }
  127.