| Index: third_party/mach_override/mach_override.c
|
| ===================================================================
|
| --- third_party/mach_override/mach_override.c (revision 98423)
|
| +++ third_party/mach_override/mach_override.c (working copy)
|
| @@ -170,6 +170,23 @@
|
| assert( originalFunctionAddress );
|
| assert( overrideFunctionAddress );
|
|
|
| + // this addresses overriding such functions as AudioOutputUnitStart()
|
| + // test with modified DefaultOutputUnit project
|
| +#if defined(__x86_64__) || defined(__i386__)
|
| + for(;;){
|
| + if(*(unsigned char*)originalFunctionAddress==0xE9) // jmp .+0x????????
|
| + originalFunctionAddress=(void*)((char*)originalFunctionAddress+5+*(int32_t *)((char*)originalFunctionAddress+1));
|
| +#if defined(__x86_64__)
|
| + else if(*(uint16_t*)originalFunctionAddress==0x25FF) // jmp qword near [rip+0x????????]
|
| + originalFunctionAddress=*(void**)((char*)originalFunctionAddress+6+*(int32_t *)((uint16_t*)originalFunctionAddress+1));
|
| +#elif defined(__i386__)
|
| + else if(*(uint16_t*)originalFunctionAddress==0x25FF) // jmp *0x????????
|
| + originalFunctionAddress=**(void***)((uint16_t*)originalFunctionAddress+1);
|
| +#endif
|
| + else break;
|
| + }
|
| +#endif
|
| +
|
| long *originalFunctionPtr = (long*) originalFunctionAddress;
|
| mach_error_t err = err_none;
|
|
|
| @@ -193,26 +210,26 @@
|
| overridePossible = false;
|
| }
|
| if (!overridePossible) err = err_cannot_override;
|
| - if (err) printf("err = %x %d\n", err, __LINE__);
|
| + if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
|
| #endif
|
|
|
| // Make the original function implementation writable.
|
| if( !err ) {
|
| err = vm_protect( mach_task_self(),
|
| - (vm_address_t) originalFunctionPtr,
|
| - sizeof(long), false, (VM_PROT_ALL | VM_PROT_COPY) );
|
| + (vm_address_t) originalFunctionPtr, 8, false,
|
| + (VM_PROT_ALL | VM_PROT_COPY) );
|
| if( err )
|
| err = vm_protect( mach_task_self(),
|
| - (vm_address_t) originalFunctionPtr, sizeof(long), false,
|
| + (vm_address_t) originalFunctionPtr, 8, false,
|
| (VM_PROT_DEFAULT | VM_PROT_COPY) );
|
| }
|
| - if (err) printf("err = %x %d\n", err, __LINE__);
|
| + if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
|
|
|
| // Allocate and target the escape island to the overriding function.
|
| BranchIsland *escapeIsland = NULL;
|
| if( !err )
|
| err = allocateBranchIsland( &escapeIsland, kAllocateHigh, originalFunctionAddress );
|
| - if (err) printf("err = %x %d\n", err, __LINE__);
|
| + if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
|
|
|
|
|
| #if defined(__ppc__) || defined(__POWERPC__)
|
| @@ -226,19 +243,19 @@
|
| branchAbsoluteInstruction = 0x48000002 | escapeIslandAddress;
|
| }
|
| #elif defined(__i386__) || defined(__x86_64__)
|
| - if (err) printf("err = %x %d\n", err, __LINE__);
|
| + if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
|
|
|
| if( !err )
|
| err = setBranchIslandTarget_i386( escapeIsland, overrideFunctionAddress, 0 );
|
|
|
| - if (err) printf("err = %x %d\n", err, __LINE__);
|
| + if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__);
|
| // Build the jump relative instruction to the escape island
|
| #endif
|
|
|
|
|
| #if defined(__i386__) || defined(__x86_64__)
|
| if (!err) {
|
| - uint32_t addressOffset = ((void*)escapeIsland - (void*)originalFunctionPtr - 5);
|
| + uint32_t addressOffset = ((char*)escapeIsland - (char*)originalFunctionPtr - 5);
|
| addressOffset = OSSwapInt32(addressOffset);
|
|
|
| jumpRelativeInstruction |= 0xE900000000000000LL;
|
| @@ -250,7 +267,7 @@
|
| // Optionally allocate & return the reentry island.
|
| BranchIsland *reentryIsland = NULL;
|
| if( !err && originalFunctionReentryIsland ) {
|
| - err = allocateBranchIsland( &reentryIsland, kAllocateNormal, NULL);
|
| + err = allocateBranchIsland( &reentryIsland, kAllocateHigh, NULL);
|
| if( !err )
|
| *originalFunctionReentryIsland = reentryIsland;
|
| }
|
| @@ -296,18 +313,18 @@
|
| if( reentryIsland )
|
| err = setBranchIslandTarget_i386( reentryIsland,
|
| (void*) ((char *)originalFunctionPtr+eatenCount), originalInstructions );
|
| + // try making islands executable before planting the jmp
|
| +#if defined(__x86_64__) || defined(__i386__)
|
| + if( !err )
|
| + err = makeIslandExecutable(escapeIsland);
|
| + if( !err && reentryIsland )
|
| + err = makeIslandExecutable(reentryIsland);
|
| +#endif
|
| if ( !err )
|
| atomic_mov64((uint64_t *)originalFunctionPtr, jumpRelativeInstruction);
|
| }
|
| #endif
|
|
|
| -#if defined(__i386__) || defined(__x86_64__)
|
| - if ( !err )
|
| - err = makeIslandExecutable( escapeIsland );
|
| - if ( !err && reentryIsland )
|
| - err = makeIslandExecutable( reentryIsland );
|
| -#endif
|
| -
|
| // Clean up on error.
|
| if( err ) {
|
| if( reentryIsland )
|
| @@ -380,7 +397,7 @@
|
| }
|
| }
|
| if( allocated )
|
| - *island = (void*) page;
|
| + *island = (BranchIsland*) page;
|
| else if( !allocated && !err )
|
| err = KERN_NO_SPACE;
|
| }
|
| @@ -530,6 +547,7 @@
|
|
|
| #if defined(__i386__)
|
| static AsmInstructionMatch possibleInstructions[] = {
|
| + { 0x5, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0x55, 0x89, 0xe5, 0xc9, 0xc3} }, // push %ebp; mov %esp,%ebp; leave; ret
|
| { 0x1, {0xFF}, {0x90} }, // nop
|
| { 0x1, {0xFF}, {0x55} }, // push %esp
|
| { 0x2, {0xFF, 0xFF}, {0x89, 0xE5} }, // mov %esp,%ebp
|
| @@ -539,6 +557,9 @@
|
| { 0x1, {0xFF}, {0x57} }, // push %edi
|
| { 0x1, {0xFF}, {0x56} }, // push %esi
|
| { 0x2, {0xFF, 0xFF}, {0x31, 0xC0} }, // xor %eax, %eax
|
| + { 0x3, {0xFF, 0x4F, 0x00}, {0x8B, 0x45, 0x00} }, // mov $imm(%ebp), %reg
|
| + { 0x3, {0xFF, 0x4C, 0x00}, {0x8B, 0x40, 0x00} }, // mov $imm(%eax-%edx), %reg
|
| + { 0x4, {0xFF, 0xFF, 0xFF, 0x00}, {0x8B, 0x4C, 0x24, 0x00} }, // mov $imm(%esp), %ecx
|
| { 0x0 }
|
| };
|
| #elif defined(__x86_64__)
|
| @@ -550,6 +571,8 @@
|
| { 0x4, {0xFB, 0xFF, 0x00, 0x00}, {0x48, 0x89, 0x00, 0x00} }, // move onto rbp
|
| { 0x2, {0xFF, 0x00}, {0x41, 0x00} }, // push %rXX
|
| { 0x2, {0xFF, 0x00}, {0x85, 0x00} }, // test %rX,%rX
|
| + { 0x5, {0xF8, 0x00, 0x00, 0x00, 0x00}, {0xB8, 0x00, 0x00, 0x00, 0x00} }, // mov $imm, %reg
|
| + { 0x3, {0xFF, 0xFF, 0x00}, {0xFF, 0x77, 0x00} }, // pushq $imm(%rdi)
|
| { 0x0 }
|
| };
|
| #endif
|
| @@ -598,6 +621,7 @@
|
| // if all instruction matches failed, we don't know current instruction then, stop here
|
| if (!curInstructionKnown) {
|
| allInstructionsKnown = false;
|
| + fprintf(stderr, "mach_override: some instructions unknown! Need to update mach_override.c\n");
|
| break;
|
| }
|
|
|
|
|