this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Allow for running 32-bit apps in 32-bit processes

Use this by default instead of 32in64

+114 -29
+1
cmake/wrap_elf.cmake
··· 17 17 include_directories(${CMAKE_SOURCE_DIR}/src/dyld) 18 18 add_darling_library(${name} SHARED ${CMAKE_CURRENT_BINARY_DIR}/${name}.c) 19 19 target_link_libraries(${name} PRIVATE system) 20 + make_fat(${name}) 20 21 install(TARGETS ${name} DESTINATION libexec/darling/usr/lib/native) 21 22 endfunction(wrap_elf) 22 23
+10 -2
src/dyld/CMakeLists.txt
··· 11 11 12 12 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") 13 13 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 14 - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Ttext-segment,0x400000 -Wl,-Tbss,0x410000 -Wl,-Tdata,0x420000") 14 + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Ttext-segment,0x400000 -Wl,-Tbss,0x410000 -Wl,-Tdata,0x420000") 15 15 add_definitions(-DINSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}" -D_GNU_SOURCE -DMLDR_BUILD) 16 16 17 17 add_executable(darling darling.c) ··· 28 28 add_executable(mldr ${mldr_sources}) 29 29 target_link_libraries(mldr pthread dl) 30 30 31 + add_executable(mldr32 ${mldr_sources}) 32 + target_link_libraries(mldr32 pthread dl) 33 + set_target_properties(mldr32 34 + PROPERTIES 35 + COMPILE_FLAGS "-m32" 36 + LINK_FLAGS "-m32" 37 + ) 38 + 31 39 add_executable(wrapgen wrapgen/wrapgen.cpp) 32 40 target_link_libraries(wrapgen dl) 33 41 34 - install(TARGETS mldr DESTINATION libexec/darling/bin) 42 + install(TARGETS mldr mldr32 DESTINATION libexec/darling/bin) 35 43 install(TARGETS darling DESTINATION bin 36 44 PERMISSIONS 37 45 OWNER_READ OWNER_WRITE OWNER_EXECUTE
+13 -3
src/dyld/gdb.c
··· 42 42 43 43 struct jump 44 44 { 45 + #ifdef __x86_64__ 45 46 uint16_t mov; 46 47 void* addr; 47 48 uint16_t jump; 49 + #elif __i386__ 50 + uint8_t mov; 51 + void* addr; 52 + uint16_t jump; 53 + #endif 48 54 } __attribute__ ((packed)); 49 55 50 - void setup_gdb_notifications(uint64_t slide, uint64_t addr) 56 + void setup_gdb_notifications(uintptr_t slide, uintptr_t addr) 51 57 { 52 58 orig_dyld_all_image_infos = (struct dyld_all_image_infos*)(addr + slide); 53 59 54 60 // dyld will later rebase the address in notification, 55 61 // but at this point we must add slide manually. 56 - struct jump* jump = (struct jump*)(((uint64_t)orig_dyld_all_image_infos->notification) + slide); 62 + struct jump* jump = (struct jump*)(((uintptr_t)orig_dyld_all_image_infos->notification) + slide); 57 63 58 64 // Rewrite instructions in the notification function to redirect the call to us. 59 65 #ifdef __x86_64__ 60 66 jump->mov = 0xb948; // movabs imm,%rcx 61 67 jump->addr = (void*) &dyld_notification_wrapper; // immediate for preceding movabs 62 - jump->jump = 0xe1ff; // jmpq *%ecx 68 + jump->jump = 0xe1ff; // jmpq *%rcx 69 + #elif __i386__ 70 + jump->mov = 0xb9; // mov imm,%ecx 71 + jump->addr = (void*) &dyld_notification_wrapper; // immediate for preceding mov 72 + jump->jump = 0xe1ff; // jmpl *%ecx 63 73 #else 64 74 # error TODO: Unsupported platform 65 75 #endif
+1 -1
src/dyld/gdb.h
··· 26 26 extern "C" { 27 27 #endif 28 28 29 - void setup_gdb_notifications(uint64_t slide, uint64_t addr); 29 + void setup_gdb_notifications(uintptr_t slide, uintptr_t addr); 30 30 31 31 #ifdef __cplusplus 32 32 }
+11 -11
src/dyld/loader.c
··· 24 24 # error See above 25 25 #endif 26 26 27 - void FUNCTION_NAME(int fd, uint64_t* entryPoint_out, uint64_t* mh_out) 27 + void FUNCTION_NAME(int fd, uintptr_t* entryPoint_out, uintptr_t* mh_out) 28 28 { 29 29 struct MACH_HEADER_STRUCT header; 30 30 uint8_t* cmds; 31 - uint64_t entryPoint = 0, entryPointDylinker = 0; 31 + uintptr_t entryPoint = 0, entryPointDylinker = 0; 32 32 struct MACH_HEADER_STRUCT* mappedHeader = NULL; 33 - uint64_t slide = 0; 34 - uint64_t mmapSize = 0; 33 + uintptr_t slide = 0; 34 + uintptr_t mmapSize = 0; 35 35 bool pie = false; 36 36 uint32_t fat_offset; 37 37 ··· 58 58 59 59 if ((header.filetype == MH_EXECUTE && header.flags & MH_PIE) || header.filetype == MH_DYLINKER) 60 60 { 61 - uint64_t base = -1; 61 + uintptr_t base = -1; 62 62 63 63 // Go through all SEGMENT_COMMAND commands to get the total continuous range required. 64 64 for (uint32_t i = 0, p = 0; i < header.ncmds; i++) ··· 80 80 p += seg->cmdsize; 81 81 } 82 82 83 - slide = (uint64_t) mmap((void*) base, mmapSize, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_EXTRA, -1, 0); 84 - if (slide == (uint64_t)MAP_FAILED) 83 + slide = (uintptr_t) mmap((void*) base, mmapSize, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_EXTRA, -1, 0); 84 + if (slide == (uintptr_t)MAP_FAILED) 85 85 { 86 86 fprintf(stderr, "Cannot mmap anonymous memory range: %s", strerror(errno)); 87 87 exit(1); ··· 183 183 184 184 if (length > sizeof(path)-1) 185 185 { 186 - fprintf(stderr, "Dynamic linker name too long: %lu\n", length); 186 + fprintf(stderr, "Dynamic linker name too long: %zu\n", length); 187 187 exit(1); 188 188 } 189 189 ··· 193 193 apply_root_path(path); 194 194 195 195 #ifdef GEN_64BIT 196 - load(path, &entryPointDylinker, NULL, CPU_TYPE_X86_64); 196 + load(path, &entryPointDylinker, NULL, CPU_TYPE_X86_64, NULL); 197 197 #endif 198 198 #ifdef GEN_32BIT 199 - load(path, &entryPointDylinker, NULL, CPU_TYPE_X86); 199 + load(path, &entryPointDylinker, NULL, CPU_TYPE_X86, NULL); 200 200 #endif 201 201 202 202 break; ··· 218 218 if (entryPoint_out != NULL) 219 219 *entryPoint_out = entryPointDylinker ? entryPointDylinker : entryPoint; 220 220 if (mh_out != NULL) 221 - *mh_out = (uint64_t) mappedHeader; 221 + *mh_out = (uintptr_t) mappedHeader; 222 222 } 223 223 224 224
+78 -12
src/dyld/mldr.c
··· 37 37 #include "commpage.h" 38 38 #include "32in64.h" 39 39 40 + #define USE_32IN64 0 41 + 40 42 #ifndef PAGE_SIZE 41 43 # define PAGE_SIZE 4096 42 44 #endif ··· 56 58 // 57 59 // Additionally, mldr providers access to native platforms libdl.so APIs (ELF loader). 58 60 59 - static void load64(int fd, uint64_t* entryPoint_out, uint64_t* mh_out); 60 - static void load32(int fd, uint64_t* entryPoint_out, uint64_t* mh_out); 61 - static void load(const char* path, uint64_t* entryPoint_out, uint64_t* mh_out, cpu_type_t cpu); 61 + #ifdef __x86_64__ 62 + static void load64(int fd, uintptr_t* entryPoint_out, uintptr_t* mh_out); 63 + static void reexec32(char** argv); 64 + #endif 65 + static void load32(int fd, uintptr_t* entryPoint_out, uintptr_t* mh_out); 66 + static void load(const char* path, uintptr_t* entryPoint_out, uintptr_t* mh_out, cpu_type_t cpu, char** argv); 62 67 static int native_prot(int prot); 63 68 static void apply_root_path(char* path); 64 69 char* elfcalls_make(void); 65 70 static char* apple0_make(const char* filepath); 71 + 72 + #if USE_32IN64 66 73 static void* setup_stack32(void* stack, int argc, const char** argv, const char** envp, const char** apple, uint64_t mh); 67 74 68 75 static bool mode_32in64 = false; 76 + #endif 77 + 69 78 static uint32_t stack_size = 0; 70 79 71 80 int main(int argc, char** argv, char** envp) 72 81 { 73 - uint64_t entryPoint, mh; 82 + uintptr_t entryPoint, mh; 74 83 void** sp; 75 84 int pushCount = 0; 76 85 const char* apple[3]; ··· 90 99 strcpy(filename, p + 1); 91 100 else 92 101 strcpy(filename, argv[1]); 102 + 103 + #ifdef __i386__ 104 + load(filename, &entryPoint, &mh, CPU_TYPE_X86, argv); // accept i386 only 105 + #else 106 + load(filename, &entryPoint, &mh, CPU_TYPE_ANY, argv); 107 + #endif 93 108 94 109 p = argv[0]; 95 110 // Update process name in ps output ··· 104 119 memset(p, 0, envp[0]-p); 105 120 argv[--argc] = NULL; 106 121 107 - load(filename, &entryPoint, &mh, CPU_TYPE_ANY); 108 - 109 - #if defined(__i386__) || defined(__x86_64__) 122 + #if __i386__ || __x86_64__ 110 123 if (getenv("BREAK_AFTER_LOAD") != NULL) 111 124 __asm__("int3"); 112 125 #endif ··· 128 141 apple[1] = elfcalls_make(); 129 142 apple[2] = NULL; 130 143 144 + #if USE_32IN64 131 145 if (!mode_32in64) 146 + #endif 132 147 { 133 148 GETSP(sp); 134 149 sp--; ··· 149 164 150 165 JUMPX(pushCount, entryPoint); 151 166 } 167 + #if USE_32IN64 152 168 else 153 169 { 154 170 uint32_t size = stack_size ? stack_size : 8*1024*1024; ··· 165 181 166 182 _64TO32_WITH_STACK(setup_stack32(sp, argc, (const char**) argv, (const char**) envp, apple, mh), entryPoint); 167 183 } 168 - 184 + #endif 169 185 170 186 __builtin_unreachable(); 171 187 } ··· 189 205 return len; 190 206 } 191 207 192 - void* setup_stack32(void* stack, int argc, const char** argv_in, const char** envp_in, const char** apple_in, uint64_t mh) 208 + #if USE_32IN64 209 + void* setup_stack32(void* stack, int argc, const char** argv_in, const char** envp_in, const char** apple_in, uintptr_t mh) 193 210 { 194 211 char **argv_new, **envp_new, **apple_new; 195 212 size_t size, apple_size; ··· 231 248 232 249 return stack_pointers; 233 250 } 251 + #endif 234 252 235 - void load(const char* path, uint64_t* entryPoint_out, uint64_t* mh_out, cpu_type_t cpu_desired) 253 + void load(const char* path, uintptr_t* entryPoint_out, uintptr_t* mh_out, cpu_type_t cpu_desired, char** argv) 236 254 { 237 255 int fd; 238 256 uint32_t magic; ··· 244 262 exit(1); 245 263 } 246 264 247 - // TODO: We need to read argv[1] and detect whether it's a 32 or 64-bit application. 265 + // We need to read argv[1] and detect whether it's a 32 or 64-bit application. 248 266 // Then load the appropriate version of dyld from the fat file. 249 267 // In case the to-be-executed executable contains both, we prefer the 64-bit version, 250 268 // unless a special property has been passed to sys_posix_spawn() to force the 32-bit ··· 258 276 259 277 if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64) 260 278 { 279 + #ifndef __i386__ 261 280 if (mh_out) 262 281 commpage_setup(true); 263 282 264 283 lseek(fd, 0, SEEK_SET); 265 284 load64(fd, entryPoint_out, mh_out); 285 + #else 286 + abort(); 287 + #endif 266 288 } 267 289 else if (magic == MH_MAGIC || magic == MH_CIGAM) 268 290 { 291 + #if !__x86_64__ || USE_32IN64 269 292 if (mh_out) 270 293 commpage_setup(false); 271 - 294 + #if __x86_64__ 272 295 mode_32in64 = true; 296 + #endif 273 297 lseek(fd, 0, SEEK_SET); 274 298 load32(fd, entryPoint_out, mh_out); 299 + #else 300 + // Re-run self as mldr32 301 + reexec32(argv); 302 + #endif 275 303 } 276 304 else if (magic == FAT_MAGIC || magic == FAT_CIGAM) 277 305 { ··· 349 377 commpage_setup(best_arch.cputype & CPU_ARCH_ABI64); 350 378 351 379 if (best_arch.cputype & CPU_ARCH_ABI64) 380 + { 381 + #if !__i386__ 352 382 load64(fd, entryPoint_out, mh_out); 383 + #else 384 + abort(); 385 + #endif 386 + } 353 387 else 354 388 { 389 + #if USE_32IN64 && __x86_64__ 355 390 mode_32in64 = true; 391 + #endif 392 + #if !USE_32IN64 && __x86_64__ 393 + // Re-execute self as mldr32 394 + reexec32(argv); 395 + #else 356 396 load32(fd, entryPoint_out, mh_out); 397 + #endif 357 398 } 358 399 } 359 400 else ··· 365 406 close(fd); 366 407 } 367 408 409 + #ifdef __x86_64__ 368 410 #define GEN_64BIT 369 411 #include "loader.c" 370 412 #undef GEN_64BIT 413 + #endif 371 414 372 415 #define GEN_32BIT 373 416 #include "loader.c" ··· 443 486 return apple0; 444 487 } 445 488 489 + #ifdef __x86_64__ 490 + static void reexec32(char** argv) 491 + { 492 + char selfpath[1024]; 493 + ssize_t len; 494 + 495 + len = readlink("/proc/self/exe", selfpath, sizeof(selfpath)-3); 496 + if (len == -1) 497 + { 498 + perror("Cannot readlink /proc/self/exe"); 499 + abort(); 500 + } 501 + 502 + selfpath[len] = '\0'; 503 + strcat(selfpath, "32"); 504 + 505 + execv(selfpath, argv); 506 + 507 + perror("Cannot re-execute as 32-bit process"); 508 + abort(); 509 + } 510 + #endif 511 +