|
11 | 11 | #include <mach-o/dyld.h> |
12 | 12 | #include <mach-o/getsect.h> |
13 | 13 | #elif defined(__linux__) |
| 14 | +#include <elf.h> |
14 | 15 | #include <link.h> |
| 16 | +#include <sys/param.h> |
| 17 | +#include <sys/auxv.h> |
15 | 18 | #elif defined(_WIN32) |
16 | 19 | #include <windows.h> |
17 | 20 | #endif |
18 | 21 |
|
19 | | -#if defined(__linux__) |
20 | | -// NOTE - This needs to be a sentinel value, if it's initialized to |
21 | | -// NULL then it won't have a spot in the executable to change |
22 | | -#define POSTJECT_SHT_PTR_SENTINEL 0000000001 |
23 | | -extern volatile void* _binary_postject_sht_start; |
24 | | - |
25 | | -struct postject_elf_section { |
26 | | - uint64_t virtual_address; // Don't use a pointer here, standardize size |
27 | | - uint32_t size; |
28 | | -}; |
29 | | -#endif |
30 | | - |
31 | 22 | struct postject_options { |
32 | 23 | const char* elf_section_name; |
33 | 24 | const char* macho_framework_name; |
@@ -101,49 +92,53 @@ static const void* postject_find_resource(const char* name, |
101 | 92 |
|
102 | 93 | return ptr; |
103 | 94 | #elif defined(__linux__) |
104 | | - void* ptr = NULL; |
105 | | - |
106 | | - // This executable might be a Position Independent Executable (PIE), so |
107 | | - // the virtual address values need to be added to the relocation address |
108 | | - uintptr_t relocation_addr = _r_debug.r_map->l_addr; |
109 | | - |
110 | | - if (_binary_postject_sht_start != (void*)POSTJECT_SHT_PTR_SENTINEL) { |
111 | | -#if defined(__POSTJECT_NO_SHT_PTR) |
112 | | - void* sht_ptr = (void*)&_binary_postject_sht_start; |
113 | | -#else |
114 | | - void* sht_ptr = |
115 | | - (void*)(relocation_addr + (uintptr_t)_binary_postject_sht_start); |
116 | | -#endif |
| 95 | + void *ptr = NULL; |
| 96 | + |
| 97 | + if (options != NULL && options->elf_section_name != NULL) { |
| 98 | + name = options->elf_section_name; |
| 99 | + } |
| 100 | + |
| 101 | + uintptr_t p = getauxval(AT_PHDR); |
| 102 | + size_t n = getauxval(AT_PHNUM); |
| 103 | + uintptr_t base_addr = p - sizeof(ElfW(Ehdr)); |
| 104 | + |
| 105 | + // iterate program header |
| 106 | + for (; n > 0; n--, p += sizeof(ElfW(Phdr))) { |
| 107 | + ElfW(Phdr) *phdr = (ElfW(Phdr) *)p; |
| 108 | + |
| 109 | + // skip everything but notes |
| 110 | + if (phdr->p_type != PT_NOTE) { |
| 111 | + continue; |
| 112 | + } |
| 113 | + |
| 114 | + // note segment starts at base address + segment virtual address |
| 115 | + uintptr_t pos = (base_addr + phdr->p_vaddr); |
| 116 | + uintptr_t end = (pos + phdr->p_memsz); |
| 117 | + |
| 118 | + // iterate through segment until we reach the end |
| 119 | + while (pos < end) { |
| 120 | + if (pos + sizeof(ElfW(Nhdr)) > end) { |
| 121 | + break; // invalid |
| 122 | + } |
| 123 | + |
| 124 | + ElfW(Nhdr) *note = (ElfW(Nhdr) *)(uintptr_t)pos; |
| 125 | + if (note->n_namesz != 0 && note->n_descsz != 0 && |
| 126 | + strncmp((char *)(pos + sizeof(ElfW(Nhdr))), |
| 127 | + (char *)name, sizeof(name)) == 0) { |
| 128 | + *size = note->n_descsz; |
| 129 | + // advance past note header and aligned name |
| 130 | + // to get to description data |
| 131 | + return (void *)((uintptr_t)note + |
| 132 | + sizeof(ElfW(Nhdr)) + |
| 133 | + roundup(note->n_namesz, 4)); |
| 134 | + } |
| 135 | + |
| 136 | + pos += (sizeof(ElfW(Nhdr)) + roundup(note->n_namesz, 4) + |
| 137 | + roundup(note->n_descsz, 4)); |
| 138 | + } |
| 139 | + } |
| 140 | + return NULL; |
117 | 141 |
|
118 | | - // First read the section count |
119 | | - uint32_t section_count = *((uint32_t*)sht_ptr); |
120 | | - sht_ptr = (uint32_t*)sht_ptr + 1; |
121 | | - |
122 | | - uint32_t i; |
123 | | - for (i = 0; i < section_count; i++) { |
124 | | - // Read the section name as a null-terminated string |
125 | | - const char* section_name = (const char*)sht_ptr; |
126 | | - sht_ptr = (char*)sht_ptr + strlen(section_name) + 1; |
127 | | - |
128 | | - // Then read the virtual_address (8 bytes) |
129 | | - uint64_t virtual_address = *((uint64_t*)sht_ptr); |
130 | | - sht_ptr = (uint64_t*)sht_ptr + 1; |
131 | | - |
132 | | - // Finally read the section size (4 bytes) |
133 | | - uint32_t section_size = *((uint32_t*)sht_ptr); |
134 | | - sht_ptr = (uint32_t*)sht_ptr + 1; |
135 | | - |
136 | | - if (strcmp(section_name, name) == 0) { |
137 | | - if (size != NULL) { |
138 | | - *size = (size_t)section_size; |
139 | | - } |
140 | | - ptr = (void*)(relocation_addr + (uintptr_t)virtual_address); |
141 | | - break; |
142 | | - } |
143 | | - } |
144 | | - } |
145 | | - |
146 | | - return ptr; |
147 | 142 | #elif defined(_WIN32) |
148 | 143 | void* ptr = NULL; |
149 | 144 | char* resource_name = NULL; |
|
0 commit comments