6

甚至我的类的私有成员/函数也可以通过使用setAccessible(true). 有没有办法防止这种来自外部代码的访问?

我在 stack-overflow 上读到了一些东西,我可以用它SecurityManager来防止小程序中的反射(虽然不确定它是如何工作的),但是 Android 也有类似的机制吗?也许是注释或聪明的编程?

4

3 回答 3

14

退后一步,您观察到的是安全理念上的差异,在 Sun 最初体现在 JVM 中的 Java 执行模型和 Android 的执行模型之间。

最初的 Java VM 设计是为一个系统设计的,其中多个相互可疑的应用程序(或 Java 术语中的“小程序”)将同时驻留在单个地址空间中,在单个 VM 中运行。因为设计者不希望一个应用程序能够与另一个应用程序发生冲突,所以他们煞费苦心地定义了一个虚拟机内安全模型,该模型将禁止诸如一个对象接触不同类的另一个对象的私有字段之类的事情。

也就是说,Java 库最终从安全模型中获得了各种“逃生口”。setAccessible()正如您所注意到的,其中之一是在反射对象上。

Android 的模型不同:Android 使用进程作为安全边界和应用程序隔离的单元,而不是像传统 JVM 那样试图将其影射进程中。这使得整个 Java 安全模型没有实际意义,除了它帮助应用程序“将其从自身中拯救出来”。也就是说,不让一个对象插入另一个对象的私有部分是一种很好的设计,而默认的 Java 安全模型正是提供了这一点。

撇开人们修改您的代码的问题不谈,对于 Android,作为应用程序作者,您可以控制最终在您的应用程序进程中运行的所有代码。如果您选择包含调用的代码setAccessible()那是您的事。您可能会在自己的脚下开枪,但您肯定不会在任何其他应用程序的脚下开枪,因为 Android 安全模型在进程层上运行,本质上不会让这种情况发生。同样,使用本机代码将完全让您脱离 Java 对象模型,这允许事情在此过程中完全混乱,但也允许您以比在 Java 中更高效的方式表达一些事情。这是一种权衡,但它是每个应用程序开发人员的权衡,而不是特别影响手机/设备上发生的任何其他事情。

我知道这并不能直接回答您的问题,但我希望它提供了一些有用的上下文。

于 2012-11-03T19:14:54.760 回答
1

Is there a way to prevent this kind of access from outside code?

Not really.

is there a similar mechanism for Android as well?

Even if there is (and I am not aware that such a thing exists), anyone can remove it, by decompiling your code (assuming they do not have your source already), getting rid of the protection, and recompiling the code.

Bear in mind that ProGuard, when used properly, will obfuscate your private classes and methods for your production APK builds. That, plus a lack of documentation, will make it tedious for anyone to gain access to those private classes and methods.

于 2012-11-03T17:17:19.690 回答
0

我不相信您可以真正 100% 地防止用户使用对您的项目进行恶意的反射。您可以通过对代码进行混淆等操作使用户更难做到这一点,但仍然可以对混淆后的代码进行反思。

我不相信 SecurityManager 可以用于您建议的目的,尽管我可能是错的。

于 2012-11-03T18:57:36.703 回答