2

I'd like to steal an NSWindow from another process. Preferably that, but an NSView, that is, the one that I would get from [window contentView], would be fine as well (especially since I suppose that I can escalate to NSWindow with [view window].

Obviously, this is likely undocumented and incredibly not approved by Apple (or the Mac App Store). From my research, it seems that this might be doable via the accessibility API that Apple provides, however I have yet to find a method to do this.

I've looked at CGWindow.h, but it doesn't seem to provide what I need.

Thanks (this is my first SO post).

I was advised to provide a non-nefarious reason: simple! It's for debugging purposes! And, err, for anything that anyone wants to do, really, because that will be possible, of course. One of my close friends, who is a great iOS hacker (the developer of MobileNotifier, search it on Google if you haven't heard of it) has suggested injecting bundles, which I said could then set up a distributed objects server, which would then work great. So we'll probably attempt that approach.

  • 4
    Some friendly advice: if you can come up with a remotely plausible non-nefarious reason for doing this, you might get more helpful responses. – MusiGenesis Apr 03 '11 at 02:32
  • Is this why Steam requires certain accessibility features to be turned on? – Nathan S. Apr 03 '11 at 02:33
  • @MusiGenesis - Added. I'm not attempting anything malicious, as this will all be local. However, it would certainly be possible to adapt the code I hope to produce to run remotely, especially since I'll probably be leveraging distributed objects. That being said, anyone could exploit any holes that exist already. My code will all be open source, either BSD or GPL (if I have to use someone else's GPL code, so it goes), so people will know exactly what they're running. @Nathan S. - Possibly, for the in game overlay? Not particularly sure, but that would seem reasonable. –  Apr 03 '11 at 05:55
  • Another cool thing you can do is to [make a PDF screenshot out of it](https://stackoverflow.com/a/11955836). – Mingye Wang Mar 02 '20 at 09:39

3 Answers3

1

You can't "steal" a window, but you can use something like SIMBL or mach_inject/override to add whatever behaviour you want to windows of arbitrary processes.

Fjölnir
  • 490
  • 2
  • 12
0

Despite I don't believe the OP that he writes something "non-malicious", as most developer tools use instrumentation APIs or higher level APIs to get needed information, without the need to inject anything to the running process - still some basic explanation is due, to the benefit of other readers.

A "Window" isn't one thing. There are several entities related to different parts of the OS that together make up the "Window" thing, each lives in different context, process, and even hardware level.

You can't "steal" an NSWindow object, because it is a simple Objective-C object, that has no meaning in any process except that one that created it.

Correctly said @alexy13, "Create your own!", but I'll extend. The NSWindow (or a Carbon Window object) both refer to a Windows-Server window, via the window ID (and several other attributes). You could, in principle, "wrap" the same Windows-Server window with several NSWindows in different processes.

If I understand the OP right, he would like to take a picture of that "stolen" window, and that is a legitimate task, that one can achieve without stealing anything. You just need to discover the Windows-Server ID of that window and call Window-Server API to get a picture of that window.

Beyond that - if you want to CONTROL the "stolen" window, you can do it via the original NSWindow in the original pricess that created the window, by sending the application a high-level event (easiest to do with AppleScript) to move, resize, close, or any other control or inquiry call you need.

Motti Shneor
  • 2,095
  • 1
  • 18
  • 24
0

You can't steal windows. Make your own! If you did, it would be a system hack/bug and Apple will find out about it. What good will stealing windows do?

alexyorke
  • 4,224
  • 3
  • 34
  • 55
  • Currently I'm doing it with `DYLD_INSERT_LIBRARIES`, injecting a Distributed Objects server into their process. However, this requires the app I'm injecting myself into to restart. It works, however. In the future, I'd like to use [bundle injection](https://github.com/rentzsch/mach_star/tree/master/mach_inject_bundle)to do this to any running project (falling back on `DYLD_INSERT_LIBRARIES` if the process crashes). The application I'm writing is a developer tool, I'm not attempting anything malicious. –  Apr 14 '11 at 04:20