Android安全:onCreate()函数的Native化
发布日期:2021-06-29 11:29:25
浏览次数:2
分类:技术文章
本文共 6813 字,大约阅读时间需要 22 分钟。
Java
在Android开发一个Activity,常规Java写法如下:
package com.zyc.oncreate2native;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;import android.widget.TextView;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView txt = findViewById(R.id.txt_main); txt.setText("onCreate-->Native success!"); }}
运行:
这样的写法放进反编译工具,分析起来几乎没有难度。Native
上面的代码Native化之后:
#include#include #include extern "C" JNIEXPORT void JNICALLJava_com_zyc_oncreate2native_MainActivity_onCreate(JNIEnv *env, jobject thiz, jobject saved_instance_state) { //super.onCreate(savedInstanceState); jclass MainActivity = env->GetObjectClass(thiz); jclass AppCompatActivity = env->GetSuperclass(MainActivity); jmethodID onCreate = env->GetMethodID(AppCompatActivity, "onCreate", "(Landroid/os/Bundle;)V"); env->CallNonvirtualVoidMethod(thiz, AppCompatActivity, onCreate, saved_instance_state); //调用父类方法 //setContentView(R.layout.activity_main); jmethodID setContentView = env->GetMethodID(MainActivity, "setContentView", "(I)V"); jclass Layout = env->FindClass("com/zyc/oncreate2native/R$layout"); //注意R类的写法 jfieldID activity_main = env->GetStaticFieldID(Layout, "activity_main", "I"); jint id_activity_main = env->GetStaticIntField(Layout, activity_main); env->CallVoidMethod(thiz, setContentView, id_activity_main); //TextView txt = findViewById(R.id.txt_main); jmethodID findViewById = env->GetMethodID(MainActivity, "findViewById","(I)Landroid/view/View;"); jclass id = env->FindClass("com/zyc/oncreate2native/R$id"); jfieldID txt_main = env->GetStaticFieldID(id, "txt_main", "I"); jint id_txt_main = env->GetStaticIntField(id, txt_main); jobject txt = env->CallObjectMethod(thiz, findViewById, id_txt_main); //txt.setText("onCreate-->Native success by c++ !!!"); jclass TextView = env->FindClass("android/widget/TextView"); jmethodID setText = env->GetMethodID(TextView, "setText", "(Ljava/lang/CharSequence;)V"); jstring text = env->NewStringUTF("onCreate-->Native success by c++ !!!"); env->CallVoidMethod(txt, setText, text); env->DeleteLocalRef(text);}
运行:
这时再反编译,Java层就无法看到有用信息了。 即使找到so文件分析伪C++代码,也头疼多了。int __cdecl Java_com_zyc_oncreate2native_MainActivity_onCreate(_JNIEnv *a1, int a2, int a3){ int v3; // eax int v4; // ST6C_4 int v5; // eax int v6; // ST68_4 int v7; // eax int v8; // ST60_4 int v9; // eax int v10; // ST5C_4 int v11; // eax char v12; // al int v13; // ST50_4 int v14; // eax int v15; // ST4C_4 int v16; // eax char v17; // al int v18; // ST40_4 int v19; // eax int v20; // ST38_4 int v21; // ST34_4 v3 = _JNIEnv::GetObjectClass(a1, a2); v4 = v3; v5 = _JNIEnv::GetSuperclass(a1, v3); v6 = v5; v7 = _JNIEnv::GetMethodID(a1, v5, 4564, 4573); _JNIEnv::CallNonvirtualVoidMethod(a1, a2, v6, v7, a3); v8 = _JNIEnv::GetMethodID(a1, v4, "setContentView", "(I)V"); v9 = _JNIEnv::FindClass(a1, "com/zyc/oncreate2native/R$layout"); v10 = v9; v11 = _JNIEnv::GetStaticFieldID(a1, v9, 4649, 4663); v12 = _JNIEnv::GetStaticIntField(a1, v10, v11); _JNIEnv::CallVoidMethod(a1, a2, v8, v12); v13 = _JNIEnv::GetMethodID(a1, v4, "findViewById", "(I)Landroid/view/View;"); v14 = _JNIEnv::FindClass(a1, "com/zyc/oncreate2native/R$id"); v15 = v14; v16 = _JNIEnv::GetStaticFieldID(a1, v14, 4730, 4663); v17 = _JNIEnv::GetStaticIntField(a1, v15, v16); v18 = _JNIEnv::CallObjectMethod(a1, a2, v13, v17); v19 = _JNIEnv::FindClass(a1, "android/widget/TextView"); v20 = _JNIEnv::GetMethodID(a1, v19, 4763, 4771); v21 = _JNIEnv::NewStringUTF(a1, "onCreate-->Native success by c++ !!!"); _JNIEnv::CallVoidMethod(a1, v18, v20, v21); return _JNIEnv::DeleteLocalRef(a1, v21);}
当然, Java_com_zyc_oncreate2native_MainActivity_onCreate() 的方法名还是容易暴露,换成改成动态注册:
#include#include #include #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "Tag", __VA_ARGS__)void ffff(JNIEnv *env, jobject thiz, jobject saved_instance_state) { //super.onCreate(savedInstanceState); jclass MainActivity = env->GetObjectClass(thiz); jclass AppCompatActivity = env->GetSuperclass(MainActivity); jmethodID onCreate = env->GetMethodID(AppCompatActivity, "onCreate", "(Landroid/os/Bundle;)V"); env->CallNonvirtualVoidMethod(thiz, AppCompatActivity, onCreate, saved_instance_state); //调用父类方法 //setContentView(R.layout.activity_main); jmethodID setContentView = env->GetMethodID(MainActivity, "setContentView", "(I)V"); jclass Layout = env->FindClass("com/zyc/oncreate2native/R$layout"); jfieldID activity_main = env->GetStaticFieldID(Layout, "activity_main", "I"); jint id_activity_main = env->GetStaticIntField(Layout, activity_main); env->CallVoidMethod(thiz, setContentView, id_activity_main); //TextView txt = findViewById(R.id.txt_main); jmethodID findViewById = env->GetMethodID(MainActivity, "findViewById", "(I)Landroid/view/View;"); jclass id = env->FindClass("com/zyc/oncreate2native/R$id"); jfieldID txt_main = env->GetStaticFieldID(id, "txt_main", "I"); jint id_txt_main = env->GetStaticIntField(id, txt_main); jobject txt = env->CallObjectMethod(thiz, findViewById, id_txt_main); //txt.setText("onCreate-->Native success by c++ !!!"); jclass TextView = env->FindClass("android/widget/TextView"); jmethodID setText = env->GetMethodID(TextView, "setText", "(Ljava/lang/CharSequence;)V"); jstring text = env->NewStringUTF("onCreate-->Native success by c++ ffff!!!"); env->CallVoidMethod(txt, setText, text); env->DeleteLocalRef(text);}static JNINativeMethod methods[] = { { "onCreate", "(Landroid/os/Bundle;)V", (void*)ffff}};static int registerNatives(JNIEnv *env) { //找到声明native方法的类 const char *className = "com/zyc/oncreate2native/MainActivity"; jclass clazz = env->FindClass(className); if (clazz == NULL) { return JNI_FALSE; } //注册函数 参数:java类 所要注册的函数数组 注册函数的个数 int methodsNum = sizeof(methods) / sizeof(methods[0]); if (env->RegisterNatives(clazz, methods, methodsNum) < 0) { return JNI_FALSE; } return JNI_TRUE;}JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv *env = NULL; //获取JNIEnv if (vm->GetEnv(reinterpret_cast (&env), JNI_VERSION_1_6) != JNI_OK) { return -1; } assert(env != NULL); if (!registerNatives(env)) { return -1; } //返回jni 的版本 return JNI_VERSION_1_6;}
这样一来定位 onCreate() 就更加困难了。
总 结
由上面不难看出, onCreate() 函数在Native化后逆向分析起来就困难多了。同理,其他Java函数也可以如法炮制,当然这一方法在提高安全性的同时也降低了开发效率。
转载地址:https://blog.csdn.net/zyc3545/article/details/117019993 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月09日 08时21分49秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
对不起,我们不要野生程序员...
2019-04-29
有了这 4 款工具,老板再也不怕我写烂SQL了
2019-04-29
为什么大家都说SELECT * 效率低
2019-04-29
万字长文!入门 Docker , 这一篇就够了
2019-04-29
他被称为"中国第一代程序员",一人之力单挑Java,如今财务自由后,做起了老师!...
2019-04-29
JavaScript常用API合集汇总
2019-04-29
计算机网络基础知识总结
2019-04-29
HTTP/3 来了 !未来可期
2019-04-29
为了面阿里P8,我肝了一份651个技术分支的脑图,要么?(限时领)
2019-04-29
牛逼!36岁阿里 P8宣布退休! 六年实现“财务自由”,裸辞环游世界!
2019-04-29
太肝了、最近5年183个Java面试问题列表及回答(值得收藏)
2019-04-29
10M/S!百度网盘偷偷更新,终于实现免费不限速了!
2019-04-29
尤雨溪:重头来过的 Vue 3 带来了什么?
2019-04-29
用完Gradle后,贼快!开始嫌弃Maven了...
2019-04-29
面试官问:高并发下,你都怎么选择最优的线程数?
2019-04-29
日志系统新贵Loki,确实比笨重的ELK轻
2019-04-29
史上最烂的项目:苦撑 12 年,600 多万行代码
2019-04-29
牛逼!最优方案spring cloud出马,十面九稳,又拿下一个大厂offer!
2019-04-29
互联网公司忽悠员工的黑话,套路太深了。。。
2019-04-29
牛批牛批!GitHub开源仿抖音国际版,火爆全网!
2019-04-29