2012-03-27 9 views
6

Supponiamo di avere un'app Mac o iOS basata su Cocoa. Mi piacerebbe correre un analizzatore statica sul codice sorgente mia appo mia app binario per recuperare un elenco di tutti i metodi Objective-C chiamati in esso. C'è uno strumento che può fare questo?Come scaricare staticamente tutti i metodi ObjC chiamati in un'app Cocoa?

alcuni punti:

  1. Cerco una soluzione statica. Non sto cercando uno dynamic solution.

  2. Qualcosa che può essere eseguito su un codice binario o sorgente è accettabile.

  3. Idealmente l'uscita sarebbe solo una massiccia lista de-ingannato di metodi Objective-C come:

     
    … 
    -[MyClass foo] 
    … 
    +[NSMutableString stringWithCapacity:] 
    … 
    -[NSString length] 
    … 
    
    (Se non è de-ingannato che è cool)

  4. Se altri tipi di simboli (funzioni C, vars statici, ecc) sono presenti, va bene.

  5. ho familiarità con class-dump, ma per quanto ne so, si scarica i classi dichiarate nei vostri binari, non i chiamati metodi nel binario. Non è quello che sto cercando. Se ho torto, e tu puoi fare questo con dump di classe, per favore correggi lo.

  6. Non sono del tutto sicuro che sia fattibile. Quindi se non lo è, anche questa è una buona risposta. :)

risposta

9

Il più vicino che sono a conoscenza di è otx, che è un wrapper otool e può ricostruire i selettori a objc_msgSend() siti di chiamata.

http://otx.osxninja.com/

+0

Puntatore eccellente, grazie bbum! –

+1

Il dominio non esiste più. http://web.archive.org/web/20130929164302/http://otx.osxninja.com/ dall'archivio dot org. – Klaas

0

Un altro grande strumento è class-dump che era sempre la mia prima scelta per l'analisi statica.

+0

Scusa, non ho letto correttamente la tua domanda ... – Chris

7

Se si sta cercando di trovare un elenco COMPLETO di tutti i metodi chiamati, questo è impossibile, sia staticamente che dinamicamente. La ragione è che i metodi possono essere chiamati in una varietà di modi e persino essere assemblati dinamicamente e programmaticamente.

Oltre alle normali chiamate di metodo che utilizzano i messaggi Objective-C come [Object message], è anche possibile inviare messaggi utilizzando le funzioni C-API da objc/message.h, ad es. objc_msgSend(str, del). Oppure puoi inviarli utilizzando l'API NSInvocation o con performSelector:withObject: (e metodi simili), consulta lo examples here. I selettori utilizzati in tutti questi casi possono essere stringhe statiche o possono essere anche creati a livello di codice da stringhe, usando cose come NSSelectorFromString.

Per peggiorare le cose, Objective-C supporta anche dynamic message resolution che consente a un oggetto di rispondere a messaggi che non corrispondono affatto ai metodi!

Se si è soddisfatti solo di invocazioni di metodi specifici, l'analisi del codice sorgente per i modelli elencati sopra fornisce un elenco minimo di metodi che possono essere richiamati durante l'esecuzione. Ma la lista può essere sia incompleta (vale a dire, non contiene metodi che possono essere chiamati), ma anche incompleta (cioè, può contenere metodi che non vengono chiamati in pratica).

+0

Mi piace molto questa risposta. Si pone un punto di vitale importanza: nessuna soluzione statica può garantire una copertura del 100% a causa delle funzionalità di runtime/linguaggio ObjC che hai citato. Lascerò comunque la mia domanda, poiché penso che ci sarebbe ancora valore in uno strumento che potrebbe trovare il resto. –

+3

Penso che più grande di tutta la metaprogrammazione della stranezza è il problema di non conoscere i tipi di ricevitori in fase di compilazione, che è necessario per determinare quale metodo viene chiamato. Quando scrivo '[foo length]', non si sa se è '- [lunghezza NSString]', '- [lunghezza FootballField]' o '+ [SomePoorlyDesignedClass length]' - potrebbe essere una qualsiasi combinazione dei tre a runtime, o anche qualche altro metodo caricato da un plugin. In questo modo è possibile determinare con elevata fedeltà quali messaggi * vengono inviati, ma è più difficile cercare di dire quali * metodi * vengono chiamati come risultato. – Chuck

+0

@Chuck Buon punto. Non sono solo i selettori, ma anche gli oggetti stessi che possono essere costruiti dinamicamente. +1 anche per sottolineare la sottigliezza dei metodi di istanza e classe! – user8472

0
otool -oV /path to executable/ | grep name | awk '{print $3}' 
Problemi correlati