Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reimplementing NSObject from scratch

When I was reading about the new 4.0.2 iOS update I wanted to know what hackers do or try doing with a buffer overflow, which after some wikipedia'ing got me interested in playing with malloc and thus creating my own "NSObject".

I am not actually planning to use this in any of my applications, its only for learning and playing around with objective-c.

And of course, as expected I encountered some problems which I couldn't solve myself.

for creating my object I do:

+ (id)create{ return malloc(sizeof(self)); }

and

- (void)free { free(self); }

When calling [TestObject create]; I get the following console messages:

"8/11/10 11:17:31 PM TestingHeap[2675] *** NSInvocation: warning: object 0x100002100 of class 'AObject' does not implement doesNotRecognizeSelector: -- abort"

So its trying to handle my object as an NSObject.. ? and how do I solve this.

Also when compiling without Foundation or AppKit, I get an error for missing symbols, __objc_empty_vtable and __objc_empty_cache in particular. I've tried including several header files from /usr/include/objc/

Thanks in advance.

Update

After linking with libobjc I receive EXC_BAD_INSTRUCTION when trying to call a method from my class.

like image 333
Antwan van Houdt Avatar asked Aug 11 '10 21:08

Antwan van Houdt


1 Answers

You need to use class_getInstanceSize instead of sizeof, as David pointed out.

You need to link against libobjc (as you found out yourself).

Your base class requires a isa pointer which has to be set in your create method.

And the runtime requires a +initialize method to be implemented which will be called before your class is used the first time. If it is missing it crashes.

So all things together your base class should have at least this:

#include <objc/objc.h>
#include <objc/runtime.h>
#include <stdlib.h>

@interface MyBase {
    Class isa;
}

+ (id) alloc;
- (void) free;

@end

@implementation MyBase

+ (void) initialize;
{
}

+ (id) alloc;
{
        size_t size = class_getInstanceSize( self );
        MyBase *result = malloc( size  );
        result->isa = self;
        return result;
}

- (void) free;
{
        free( self );
}

@end
like image 135
Sven Avatar answered Oct 08 '22 02:10

Sven