2010-08-11 12 views
13

Quando stavo leggendo sul nuovo aggiornamento iOS 4.0.2 volevo sapere cosa fanno o fanno gli hacker con un buffer overflow, che dopo qualche wikipedia mi ha interessato a giocare con malloc e quindi a creare il mio "NSObject".reimplementing NSObject da zero

Non ho intenzione di usarlo in nessuna delle mie applicazioni, è solo per imparare e giocare con l'obiettivo-c.

E ovviamente, come previsto, ho riscontrato alcuni problemi che non riuscivo a risolvere da solo.

per creare il mio oggetto che faccio:

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

e

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

Quando si chiama [TestObject Crea]; Ottengo i seguenti messaggi di console:

"8/11/10 11:17:31 PM TestingHeap [2675] *** NSInvocation: avviso: l'oggetto 0x100002100 della classe 'AObject' non implementa doesNotRecognizeSelector: - abort"

Quindi sta cercando di gestire il mio oggetto come un NSObject ..? e come risolvo questo.

Anche durante la compilazione senza Foundation o AppKit, viene visualizzato un errore per i simboli mancanti, __objc_empty_vtable e __objc_empty_cache in particolare. Ho provato a includere diversi file di intestazione da/usr/include/objc/

Grazie in anticipo.

Aggiornamento

Dopo il collegamento con libobjc ricevo EXC_BAD_INSTRUCTION quando si cerca di chiamare un metodo della mia classe.

+0

Si consiglia di dare un'occhiata al protocollo NSObject, se non l'hai già: http://developer.apple. com/mac/library/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html – Justin

+0

L'inclusione dei file di intestazione non risolverà gli errori di simboli mancanti, che provengono dal linker. Devi collegarti a libobjc (normalmente fatto per te dalla Fondazione). –

+3

Probabilmente non vuoi ottenere la dimensione usando 'sizeof (self)' comunque. 'self' è un puntatore e quindi otterrai solo la dimensione del puntatore. Puoi invece usare 'class_getInstanceSize'. – David

risposta

9

È necessario utilizzare class_getInstanceSize anziché sizeof, come indicato da David.

È necessario eseguire il collegamento con libobjc (come hai scoperto tu stesso).

La classe base richiede un puntatore isa che deve essere impostato nel metodo create.

E il runtime richiede l'implementazione di un metodo +initialize che verrà chiamato prima che la classe venga utilizzata la prima volta. Se manca si blocca.

così tutte le cose insieme la vostra classe di base devono avere almeno questo:

#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