保留所有字符串 JNI android 以防止逆向工程?
Keeping all strings JNI android to protect from reverse engineering?
这就是我在 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 class 调用这个原生函数。
我的问题是:
- 能不能反编译人识别?
- 我也用 Proguard,Proguard 会从中制作混淆代码吗?
- 是否会转换为.so文件,反编译人员可读?
提前谢谢你。我希望有人能对此给予更多的启发
你无法阻止逆向工程,但你可以让它变得更难,涉及更多的工作和额外的步骤,这并不是每个人都能做到的。
将常量放入本机库可防止它们出现在反编译的 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());
}
这就是我在 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 class 调用这个原生函数。
我的问题是:
- 能不能反编译人识别?
- 我也用 Proguard,Proguard 会从中制作混淆代码吗?
- 是否会转换为.so文件,反编译人员可读?
提前谢谢你。我希望有人能对此给予更多的启发
你无法阻止逆向工程,但你可以让它变得更难,涉及更多的工作和额外的步骤,这并不是每个人都能做到的。
将常量放入本机库可防止它们出现在反编译的 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());
}