如何确定编译的.Net或Java应用程序中引用了哪些类?

时间:2009-09-02 17:26:27

标签: java .net reference dependencies

我想知道是否有一种简单的方法可以确定编译的.NET或Java应用程序“使用”库中的哪些类,我需要编写一个简单的实用程序来执行此操作(因此使用任何可用的反编译器赢了)不做这个工作。

我不需要分析不同的输入来确定是否为这个或那个输入集实际创建了一个类 - 我只关心该类是否在应用程序中被引用。很可能应用程序将从我查找的类中继承子类并使用子类。

我用一个十六进制编辑器查看了一堆.Net .exe和Java .classes,看来引用的类是用明文拼写出来的,但我不确定是不是总是这样 - 我的对MSIL / Java字节码的了解还不够。我假设即使应用程序本身可以被混淆,它仍然必须通过原始名称调用库类?

3 个答案:

答案 0 :(得分:2)

扩展overslacked said

编辑:由于某种原因,我认为您询问了方法,而不是类型

类型

与查找方法一样,这不包括通过Reflection API进行访问。

您必须在Reflector插件中找到以下内容以识别引用的类型并执行transitive closure

  • 方法参数
  • 方法返回类型
  • 自定义属性
  • 基本类型和接口实现
  • 本地变量声明
  • 评估的子表达式类型
  • 字段,媒体资源和事件类型

如果您自己解析IL,那么您所要做的就是从主程序集中处理的是TypeRef和TypeSpec元数据,这非常简单(当然我在这里解析整个字节代码)。但是,传递闭包仍然需要处理引用程序集中每个引用方法的完整字节代码(以获取子表达式类型)。

方法

如果可以为Reflector编写插件来处理任务,那肯定是最简单的方法。解析IL是非常重要的,虽然我现在已经完成了,所以如果必须的话我会使用该代码(只是说这不是不可能的)。 :d

请记住,您可能在第一次传递时看不到方法依赖关系 提到的方法都不会捕获。这些是由于通过callvirt(虚拟和接口方法调用)和calli(通常是委托)指令间接调度。对于使用newobj创建的每种类型 T 以及类型中的每个方法 M ,您必须检查所有callvirt,{{1 }}和ldftn指令,以查看目标的base definition(如果目标是虚方法)是否与 M 的基本方法定义相同<如果目标是接口方法,则em> T 或 M 属于类型interface map。这并不完美,但如果没有定理证明器,它就是静态分析的最佳选择。它是将在Reflection API之外调用的实际方法的超集,以及程序集中的完整方法集的子集。

答案 1 :(得分:1)

对于.NET:看起来an article on MSDN可以帮助您入门。对于它的价值,对于.NET来说,神奇的谷歌词语是“.net汇编参考”。

答案 2 :(得分:0)

在Java中,查找类依赖关系的最佳机制(以编程方式)是bytecode inspection。这可以使用BCEL或(最好)ASM等库来完成。如果您希望使用自己的代码解析类文件,class file structure中会详细记录Java VM specification

请注意,类检查不会涵盖运行时依赖项(例如使用service API加载的类)。