我想知道是否有一种简单的方法来确定已编译的 .NET 或 Java 应用程序“使用”库中的哪些类,并且我需要编写一个简单的实用程序来执行此操作(因此使用任何可用的反编译器都可以不做这项工作)。
我不需要分析不同的输入来确定是否实际上为这个或那个输入集创建了一个类 - 我只关心应用程序中是否引用了该类。应用程序很可能会从我查找的类中继承并使用该子类。
我用十六进制编辑器查看了一堆 .Net .exe 和 Java .class,似乎引用的类是以纯文本形式拼写出来的,但我不确定是否总是如此 - 我的仅了解 MSIL/Java 字节码还不够。我认为即使应用程序本身可以被混淆,它仍然必须按原始名称调用库类?
最佳答案
扩展什么overslacked said .
编辑:出于某种原因,我以为您问的是方法,而不是类型。
类型
与查找方法一样,这不包括通过 Reflection API 进行访问。
您必须在 Reflector 插件中找到以下内容来识别引用的类型并执行 transitive closure :
- 方法参数
- 方法返回类型
- 自定义属性
- 基本类型和接口(interface)实现
- 局部变量声明
- 计算子表达式类型
- 字段、属性和事件类型
如果您自己解析 IL,您所要做的就是从主程序集中处理 TypeRef 和 TypeSpec 元数据,这非常简单(当然我在这里是通过解析整个字节码来进行讨论的)。但是,传递闭包仍然需要您处理引用程序集中每个引用方法的完整字节代码(以获取子表达式类型)。
方法
如果您可以为 Reflector 编写一个插件来处理该任务,这绝对是最简单的方法。解析 IL 并不简单,尽管我现在已经完成了,所以如果必须的话我只会使用该代码(只是说这并非不可能)。 :D
请记住,您可能有在第一次传递时看不到的方法依赖项,而提到的方法都不会捕获。这是由于通过 callvirt(虚拟和接口(interface)方法调用)和 calli(通常是委托(delegate))指令进行间接调度造成的。对于使用 newobj
创建的每个类型 T 以及该类型中的每个方法 M,您必须检查所有 callvirt
、ldftn
和 ldvirtftn
指令来查看 base definition 是否目标(如果目标是虚拟方法)与 T 中 M 的基本方法定义相同,或 M 位于类型 interface map如果目标是接口(interface)方法。这并不完美,但它是在没有定理证明的情况下静态分析所能做到的最好的结果。它是在 Reflection API 外部调用的实际方法的超集,也是程序集中完整方法集的子集。
关于java - 如何确定编译的.Net 或Java 应用程序中引用了哪些类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1369083/