• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Patching an application (long)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Patching an application (long)


  • Subject: Patching an application (long)
  • From: "Sven A. Schmidt" <email@hidden>
  • Date: Thu, 16 Jan 2003 13:09:41 +0100

Hi,

I'm trying to replace (or rather extend) a method implementation of an application with my own.

I've actually made more progress than I expected and Objective-C/Cocoa have impressed me time and time again on my way. But I'm not there, yet.

So far I have

- spied from the application which object I need, how to get it, and which message I need to replace (with the great combination of tools F-Script / F-Script-Anywhere).

- set up a project based on libPatch and managed to attach a bundle to the running application.

In this bundle/library, I have defined a category on the target object (OriginalObject) that replaces the method implementation in question. E.g.

PatchController.m:

@implementation OriginalObject (MyExtension)
- (void)theMethod:(id)sender {...}
@end

Now, when I build the library, I get the linker error:
ld: Undefined symbols: .objc_class_name_OriginalObject

My first shot a fixing this was adding an empty implementation to myObject.m:

@implementation OriginalObject
@end

This worked great. I could patch the application and my replacement would be called. But this won't do, because I also need to call the original method.

So next I tried the IMP caching trick from 'Cocoa Programming' which stores the pointer to the original implementation in the category's +load method before it is replaced with the new implementation.

The book warns that this is only tested on 10.1.3 or earlier and it actually doesn't work. class_getInstanceMethod(...) returns null when I call it in +load.

I can think of the following reasons:
1) Heed the warning. You're using 10.2 and are out of luck on this one.
2) Adding the empty implementation as linker fodder above actually hides the original implementation

To further investigate I tried MethodSwizzle from cocoadev. This swaps implementations between selectors that take similar parameters. No go, either. class_getInstanceMethod returns nil for both selectors.

Now this puzzled me, so next I used the following to get a list of all selectors (from 'Cocoa Programming', too, which seems to be as good as it is big -- only had it for half a day but it's already a treasure grove):

NSMutableArray *methodList( Class aClass ) {
NSMutableArray *result = [ NSMutableArray array ];
void *iterator = NULL;
struct objc_method_list *mlist;

while ( mlist = class_nextMethodList( aClass, &iterator ) ) {
const int numMethods = mlist->method_count;
int i;
for ( i = 0; i < numMethods; i++ ) {
Method currentMethod = &mlist->method_list[i];
[ result addObject: NSStringFromSelector( currentMethod->method_name ) ];
}
}
return result;
}

The array is empty. The runtime system does not know about the real abilities of the object I'm trying to patch, at least not at the time I'm calling 'methodList'.

So what can I do?

I have to add the empty implementation to silence the linker, since I don't have any library to link against. Or maybe there something anlong the lines of '-undefined suppress' as a linker switch?

In any case, I don't think I really hide the 'real' implementation, since the application still runs and I can replace the original method fine. I just can't find a way to get at the old implementation.

Is there a way other than in +load of the bundle to inspect the target object? My best guess right now is that I'm looking to early. I tried launching patch program and target application in different order but that didn't change anything.

Should I use a different approach?

Any hints, suggestions, pointers greatly appreciated,
Sven
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

  • Prev by Date: submenu action
  • Next by Date: Re: FSRef -> NSString
  • Previous by thread: submenu action
  • Next by thread: Re: Patching an application (long)
  • Index(es):
    • Date
    • Thread