rentzsch / mach_star

code injection and function overriding for Mac OS X
254 stars 46 forks source link

No Injection on 32bit/Lion Still #23

Closed alexzielenski closed 2 years ago

alexzielenski commented 12 years ago

I get this error: "mach_inject failing.. (os/kern) invalid argument" when trying to inject into 32bit apps on Lion. It works in 32-bit on SL for some reason.

My error code is 4.

P.S. I am injecting a 64bit/32bit bundle.

albertz commented 12 years ago

In the function mach_inject, can you play around with imageOffset = 0;? See the related comment there. I introduced this patch because it didn't worked on MacOSX 10.7 32bit.

I would wonder though if in one case, RIP-relative addressing is used and not in the other.

alexzielenski commented 12 years ago

Yes I see this:

#if defined(__x86_64__)
        imageOffset = 0; // RIP-relative addressing
#else
//      ASSERT_CAST( void*, remoteCode );
//      imageOffset = ((void*) remoteCode) - image;
        // WARNING: See bug https://github.com/rentzsch/mach_star/issues/11 . Not sure about this.
        imageOffset = 0;
#endif
albertz commented 12 years ago

Where exactly does it fail? Have you debugged it in more detail?

alexzielenski commented 12 years ago

I just logged every single place where err is defined in mach_inject(…) and this is the only/last spot it errors out.

// create thread and launch it

        err = thread_create_running( remoteTask, x86_THREAD_STATE64,
                                     (thread_state_t) &remoteThreadState, x86_THREAD_STATE64_COUNT,
                                     &remoteThread );

But this makes no sense because that is inside the x86_64 code block.

So i did some testing and put this code into mach_inject.c

#if defined (__i386__)
    printf("i386\n");
#endif

#if defined (__x86_64__)
    printf("x86_64\n");
#endif

and the x86_64 log came up every time even when injecting into a 32bit app so I think there lies the problem. If the application that is using mach_inject is Universal or 64-bit it cannot inject into 32bit applications (or bundle stubs/framework)

EDIT: Update. After compiling my app for 32-bit only. (only the app, nothing else) I got it to work in 32-bit apps. But now 64-bit apps don't get injected into!

alexzielenski commented 12 years ago

So is that even possible to fix?

albertz commented 12 years ago

OSX is either running the 32 or the 64bit code of your injection app (and i.e. of mach_inject). If you compiled it for both, of course it will run the 64bit code. And the 64bit code cannot inject into 32bit processes.

This might be possible to fix but probably very hard.

I went another way and created a few small helper apps for each target (i.e. 32bit and 64bit processes). See https://github.com/albertz/simbl.

alexzielenski commented 12 years ago

But perhaps mach_inject can be modified to use a certain architecture if the executable being injected into is 32bit, etc. Also, your method only works on NSRunningApplication instances. What if I'm injecting into a non-bundle/no-identifier process? How could the architecture be identified then?

albertz commented 12 years ago

No, my method works always. See the code. (Whereby the code is only used for real applications in that case; but take a look at the really relevant code; it just needs a PID and nothing else, that is also what is passed to the helper tool.)

You might mean the code which determines the architecture of any target process. This one is simplified and not general because it was just easier this way for this specific project. You just might want to replace that by some more general code.

alexzielenski commented 12 years ago

Yes I mean the code which determines the architecture of the target process. NSRunning application does not apply to a process, for instance, like "mds"-one without a bundle. I have been googling around and have not yet found a way to find the architecture of a running process at runtime. Is there another way to do so?

loco4 commented 12 years ago

Has there been any more progress on "fixing" this?