如何静态转储在Cocoa应用程序中调用的所有ObjC方法?

假设我有一个基于cocoa的Mac或iOS应用程序。 我想在我的应用程序的源代码 我的应用程序的二进制文件上运行一个静态分析器来检索其中调用的所有Objective-C方法的列表。 有没有一种工具可以做到这一点?

几点:

  1. 我正在寻找一个静态解决scheme。 我不是在寻找一个dynamic的解决scheme 。

  2. 可以针对二进制或源代码运行的东西是可以接受的。

  3. 理想情况下,输出只是一个大量的Objective-C方法列表,如:

     ...
     -  [MyClass foo]
     ...
     + [NSMutableString stringWithCapacity:]
     ...
     -  [NSString长度]
     ...
    

    (如果它不是很酷的话)

  4. 如果存在其他types的符号(C函数,静态variables等),那就好了。

  5. 我熟悉类转储 ,但AFAIK,它转储在你的二进制声明的类 ,而不是二进制中的调用方法 。 这不是我要找的。 如果我错了,而且你可以用垃圾箱来做这件事,请纠正我。

  6. 我不完全确定这是可行的。 所以如果不是,那也是一个很好的答案。 🙂

我知道最接近的是otx ,它是一个围绕otool的包装器,可以在objc_msgSend()调用站点重buildselect器。

http://otx.osxninja.com/

如果您要求查找所有方法的完整列表,则这是不可能的,无论是静态还是dynamic。 原因是可以用各种方法调用方法,甚至可以dynamic地和以编程方式组装。

除了使用诸如[Object message]类的Objective-C消息的常规方法调用之外,还可以使用objc/message.h的C-API函数objc_msgSend(str, del)例如objc_msgSend(str, del)分派消息。 或者你可以使用NSInvocation API或者使用performSelector:withObject:和类似的方法)来分派它们,参见这里的例子 。 在所有这些情况下使用的select器可以是静态string,或者甚至可以使用NSSelectorFromString东西从string编程NSSelectorFromString

更糟糕的是,Objective-C甚至支持dynamic消息parsing ,它允许一个对象响应与方法根本不对应的消息!

如果只对特定的方法调用感到满意,那么parsing上面列出的模式的源代码会给你一个在执行过程中可能调用的最小的方法列表。 但是这个列表可能既不完整也不完整(即,不包含可能被调用的方法)以及过度完成(即可能包含在实践中未被调用的方法)。

另一个伟大的工具是类转储 ,这始终是我的第一个select静态分析。

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