【问题标题】:Keeping all strings JNI android to protect from reverse engineering?保留所有字符串 JNI android 以防止逆向工程?
【发布时间】:2020-01-27 09:18:34
【问题描述】:

这就是我在 JNI 中保存字符串的方式

extern "C" JNIEXPORT jstring JNICALL
Java_com_galaxy_mars_moon_MainActivity_getDefaultNegative(JNIEnv* env, jobject)
{
std::string defaultNegative = "Cancel";
return env->NewStringUTF(defaultNegative.c_str());
}

我从 java 类中调用这个本机函数。

我的问题是:

  1. 能反编译识别吗?
  2. 我也用了Proguard,Proguard 会用它做混淆代码吗?
  3. 会不会被转成.so文件,反编译的人是否可读?

提前谢谢你。我希望有人能对此有所了解

【问题讨论】:

  • .so 文件中的字符串可以轻松读取(使用带有十六进制编辑器的 notepad++)
  • @Hooman,知道把它放在哪里,这样反编译的人会觉得很困难吗?
  • 我认为没有标准的方法,但您可以通过某些功能在用户设备上生成字符串。它比纯文本更好,但通常不要指望它

标签: android c++11 java-native-interface obfuscation deobfuscation


【解决方案1】:

你无法阻止逆向工程,但你可以让逆向工程变得更加困难,包括并非每个人都能做到的更多工作和额外步骤。

将常量放入本机库可防止它们出现在反编译的 java 代码中。连接已编译库中的哪个字符串与最终应用程序中的哪个值匹配并非易事。一种常见的方法是只从本地库中导出所有字符串并通过上下文匹配它们——例如,寻找看起来像 API 密钥的东西。如果您加密这些常量并在应用程序本身中解密它们,这会为逆向工程增加另一个步骤,尽管由于加密密钥在应用程序中,攻击者最终当然可以自己完成。

要快速轻松地加密 NDK 中的值,请考虑使用基本的 salsa20 或 chacha20 实现 - 出于混淆目的,不需要身份验证,并且可以对密钥进行硬编码。

例如,使用this simple Salsa20 C implementation:

// hard-coded 128-bit key, can be anything
uint8_t k[32] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };

// hard-coded nonce, can be anything
uint8_t n[8] = { 101, 102, 103, 104, 105, 106, 107, 108 };

// The s20_crypt() function encrypts/decrypts in place.

// During development, do this:
std::string myString = ...;
std::vector<uint8_t> vec(myString.begin(), myString.end());
s20_crypt(k, S20_KEYLEN_128, n, 0, vec.data(), vec.size());
// export the vector bytes somehow - you can run this on your computer and write then to a file or to stdout for example

// After you have the encrypted bytes:

Java_com_galaxy_mars_moon_MainActivity_getDefaultNegative(JNIEnv* env, jobject)
{
  uint8_t[] defaultNegative = [...]; // the encrypted values
  s20_crypt(k, S20_KEYLEN_128, n, 0, defaultNegative, sizeof(defaultNegative));
  std::string decrypted(defaultNegative, defaultNegative+sizeof(defaultNegative));
  return env->NewStringUTF(decrypted.c_str());
}

【讨论】:

  • 我可以删除 => std::string myString = ...;发布应用时?
  • @RushikantPawar 当然,您只需要计算加密值。您也可以使用 android 代码之外的命令行实用程序来实现 - 我在 gist.github.com/orip/0595f3bd3bfb959f25d03c4610d164f3 上提供了一个示例
  • 被接受为答案并为这些努力点赞。它真的很有帮助。非常感谢
猜你喜欢
  • 2012-11-03
  • 2011-11-18
  • 1970-01-01
  • 2011-09-27
  • 2017-10-18
  • 2011-07-14
  • 1970-01-01
  • 2012-09-05
相关资源
最近更新 更多