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 {@Overrideprotected 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 <jni.h>
#include <string>
#include <android/log.h>extern "C" JNIEXPORT void JNICALL
Java_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; // eaxint v4; // ST6C_4int v5; // eaxint v6; // ST68_4int v7; // eaxint v8; // ST60_4int v9; // eaxint v10; // ST5C_4int v11; // eaxchar v12; // alint v13; // ST50_4int v14; // eaxint v15; // ST4C_4int v16; // eaxchar v17; // alint v18; // ST40_4int v19; // eaxint v20; // ST38_4int v21; // ST34_4v3 = _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 <jni.h>
#include <string>
#include <android/log.h>#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;//获取JNIEnvif (vm->GetEnv(reinterpret_cast<void **>(&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函数也可以如法炮制,当然这一方法在提高安全性的同时也降低了开发效率。

Android安全:onCreate()函数的Native化相关推荐

  1. 【Android 逆向】加壳技术识别 ( 函数抽取 与 Native 化加壳的区分 | VMP 加壳与 Dex2C 加壳的区分 )

    文章目录 一.加壳特征识别 1.函数抽取 与 Native 化加壳的区分 2.VMP 加壳与 Dex2C 加壳的区分 一.加壳特征识别 1.函数抽取 与 Native 化加壳的区分 函数抽取 与 Na ...

  2. 深入了解android平台的jni---注册native函数

    注册native函数有两种方法:静态注册和动态注册. 1.静态注册方法 根据函数名找到对应的JNI函数:Java层调用函数时,会从对应的JNI中寻找该函数,如果没有就会报错,如果存在则会建立一个关联联 ...

  3. 【Android 逆向】ART 脱壳 ( InMemoryDexClassLoader 脱壳 | DexFile 构造函数及相关调用函数 | Android 源码中查找 native 函数 )

    文章目录 一.DexFile 构造函数 二.DexFile.openInMemoryDexFile 函数 三.Android 源码中查找 native 函数 一.DexFile 构造函数 上一篇博客 ...

  4. Android 淘气三千传之 —— 插件化的一点理解(上)

    插件化 这一篇主要是个人对插件化涉及到的一些基础知识的理解,内容都比较简单: 包括以下内容: 目录: 1.类加载机制 2.Binder机制 3.APP.四大组件的启动流程 4.APK安装过程 5.资源 ...

  5. [免费专栏] Android安全之Android APP应用程序的汉化功能 (修改so中的字符串内容)

    也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 Android安全付费专栏长期更新,本篇最新内容请前往: [ ...

  6. 4、在已有的Android应用中使用React Native

    这一篇记录的是如何在已有的Android应用中使用React Native,在官方的文档上也有介绍:http://reactnative.cn/docs/embedded-app-android.ht ...

  7. Android在OnCreate中获取控件的宽度和高度

    在Android中,有时需要对控件进行测量,得到的控件宽度和高度可以用来做一些计算.在需要自适应屏幕的情况下,这种计算就显得特别重要.另一方便,由于需求的原因,希望一进入界面后,就能得到控件的宽度和高 ...

  8. 【Android RTMP】Android Studio 集成 x264 开源库 ( Ubuntu 交叉编译 | Android Studio 导入函数库 )

    文章目录 安卓直播推流专栏博客总结 一. x264 简介 二. x264 交叉编译 三. Android Studio 导入函数库 四. 交叉编译版本 五. GitHub 项目地址 安卓直播推流专栏博 ...

  9. android获取自适应高度,Android中oncreate中获得控件高度或宽度的实现方法

    Android中oncreate中获得控件高度或宽度的实现方法 onCreate函数只是提供了数据初始化的机会,此时还没有正式绘制图形.在图形尚未渲染的情况下,getWidth()或getHeight ...

最新文章

  1. oracle 2日dba 11g,Oracle 11gR2 注意revoke dba 会一并回收通过”quota“分配的表空间限额...
  2. Redis的数据类型详解
  3. php 代码修改后 重新实例化_从匿名函数到PHP设计模式之容器模式
  4. promise中调用ajax
  5. Anaconda+vscode+pytorch环境搭建
  6. bootstraptable导出excel独立使用_JavaWeb系列之-一小时搞定POI导出Excel
  7. 网站留言板防重复留言_2020微信公众号怎么开通原创、赞赏、留言功能?【5月更新】...
  8. 循环下标_【转】【Python效率】五种Pandas循环方法效率对比
  9. R-CNN解读+代码梳理
  10. 技术开发、产品开发和平台开发的区别
  11. 目标检测数据集PASCAL VOC详解
  12. 网站域名假墙处理方法 内含cloudflare API自动更换IP的php脚本
  13. CVPR 2021 论文大盘点-医学影像篇
  14. rono在oracle的作用_oracle分区表有什么作用
  15. codeforces 416C C. Booking System(贪心)
  16. C语言中strstr函数功能及用法
  17. Java设计一个类代表二维空间的一个点,设计一个类代表二维空间的一个圆,计算面积,,并写程序验证计算一个点(Point对象)是否在圆(Cricle对象)内
  18. 计算机网络技术用i3可以吗,买电脑避坑第一步,i3处理器和i5等处理器有什么区别?...
  19. 一个40多岁老程序员的学习之路,在别人为“中年危机”忧愁时,你可以淡然处之
  20. 残缺棋盘问题 C语言 算法

热门文章

  1. Caffe2 Synchronous SGD
  2. 虚拟机Centos,登陆之后又弹回到登陆界面,无法进入系统
  3. 怎么找网图本人_怎么通过照片找人-请问如何用相片在网络查找个人资料就是利用相 – 手机爱问...
  4. 【数据结构】8. 队列(带头节点的单链表实现)(完整代码实现:初始化、入队列、出队列、获取队头元素、获取队尾元素、获取队列中有效元素的个数、判空、销毁)
  5. 微信公众号支付,iframe跨域
  6. 新绝代双骄3终极全攻略1
  7. RankNet - LambdaRank - LambdaMART
  8. 【wxPython】wxPython之窗口操作
  9. 利用github和godaddy搭建使用二级域名的个人主页
  10. Vue+bpmn.js自定义流程图之palette(二)