zoukankan      html  css  js  c++  java
  • 安卓逆向6.Android Studio JNI 快速构建项目+动态注册+简易计算器

    前面几篇文章演示的是比较原始的创建JNI项目的方法,旨在了解JNI项目构建原理!

    但是构建项目效率很低,开发,调试都存在很大的效率低下问题。

    本篇文章将演示利用Android Studio快速构建JNI项目。本篇文章要点:

    a、利用Android Studio快速构建JNI项目

    b、添加日志打印

    c、Android Studio调试C/C++代码

    d、JNI动态注册

    e、简易计算器实现。

    1.打开Android Studio新建Project,选中Native c++选项,此选项可以帮助开发人员快速创建JNI项目,免去手动配置等麻烦问题。

    2.项目取名为JniDynamicRegTest,点击Next

    3.使用默认C++标准,点击Finish

    4.File->Settings->Android SDK->SDK Tools选项下,安装LLDB,NDK,CMake

    5.File->Project Structure->SDK Location->Android NDK Location ,选择Default xxxx选项,从而配置完成NDK

    6.为了验证上一步是否配置成功,需要来到local.properties,如果同时出现ndk.dir=xxx sdk.dir=xxx 证明配置成功

    7.此时如果我们对native-lib.cpp进行编辑,可以看到出现了智能提示。就代表我们的环境配置没有问题了。

    8.接下来我们添加日志打印输出,将下面代码添加到cpp文件头部,使用的时候直接调用就行,比如:LOGI("我是输出的日志信息");
    #include <android/log.h>
    #define LOG_TAG    "JniDebugLogger"
    #define LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
    #define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
    #define LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

    9.接下来我们在C/C++代码下断点,并点击Debug图标。看是否能正确断下。

    10.注意,当出现如下界面时,千万别点击,只需要什么都不做,等几秒钟,断点断下就行。

    11.接下来我们在MainActivity中定义4个Native方法,分别为 add sub mul div

    12.在native-lib.cpp里实现MainActivity的方法,native-lib.cpp源码如下
    #include <jni.h>
    #include <string>
    
    #include <android/log.h>
    #define  LOG_TAG    "JniDebugLogger"
    #define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
    #define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
    #define LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
    
    extern "C" JNIEXPORT jstring JNICALL Java_com_crackme_jnidynamicregtest_MainActivity_stringFromJNI(JNIEnv* env,jobject /* this */) {
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
    jint NativeAdd(JNIEnv* env,jobject  obj,jint a,jint b)
    {
        return a+b;
    }
    
    jint NativeSub(JNIEnv* env,jobject  obj,jint a,jint b)
    {
        return a-b;
    }
    jint NativeMul(JNIEnv* env,jobject  obj,jint a,jint b)
    {
        return a*b;
    }
    jint NativeDiv(JNIEnv* env,jobject  obj,jint a,jint b)
    {
        return a/b;
    }
    JNINativeMethod jniNativeMethods[]
    {
            {"add","(II)I",(void*)NativeAdd},
            {"sub","(II)I",(void*)NativeSub},
            {"mul","(II)I",(void*)NativeMul},
            {"div","(II)I",(void*)NativeDiv}
    };
    
    jint  RegistNativeMethods(JNIEnv* env)
    {
        jclass _jclass=env->FindClass("com/crackme/jnidynamicregtest/MainActivity");
        if(env->RegisterNatives(_jclass,jniNativeMethods, sizeof(jniNativeMethods)/ sizeof(jniNativeMethods[0]))==JNI_OK)
        {
    
            return JNI_OK;
        }
        return  JNI_ERR;
    }
    JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
    {
        JNIEnv* jniEnv=0;
        if(vm->GetEnv((void**)&jniEnv,JNI_VERSION_1_6)!=JNI_OK)
        {
            LOGE("GetEnv执行失败");
            return  JNI_ERR;
        }
        if(RegistNativeMethods(jniEnv)!=JNI_OK)
        {
            LOGE("RegistNativeMethods执行失败");
            return  JNI_ERR;
        }
        return  JNI_VERSION_1_6;
    }

    13.在MainActivity里添加测试代码,运行测试

    14.运行测试Native层没有问题,接下来添加Java层代码并在界面增加控件,实现简单的计算器。MainActivity代码如下
    package com.crackme.jnidynamicregtest;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    
    public class MainActivity extends AppCompatActivity {
    
        static {
            System.loadLibrary("native-lib");
        }
    
        public native int add(int a,int b);
        public native int sub(int a,int b);
        public native int mul(int a,int b);
        public native int div(int a,int b);
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // Example of a call to a native method
    
            Button btnAdd=(Button)findViewById(R.id.btnAdd);
            Button btnSub=(Button)findViewById(R.id.btnSub);
            Button btnMul=(Button)findViewById(R.id.btnMul);
            Button btnDiv=(Button)findViewById(R.id.btnDiv);
            View.OnClickListener ocl=  new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    EditText editTextA=(EditText)findViewById(R.id.editTextA);
                    int nA=Integer.parseInt(editTextA.getText().toString());
                    EditText editTextB=(EditText)findViewById(R.id.editTextB);
                    int nB=Integer.parseInt(editTextB.getText().toString());
                    TextView tv = findViewById(R.id.sample_text);
                        switch (v.getId())
                        {
                            case R.id.btnAdd:
                                tv.setText(""+add(nA,nB));
                                break;
                            case R.id.btnSub:
                                tv.setText(""+sub(nA,nB));
                                break;
                            case R.id.btnMul:
                                tv.setText(""+mul(nA,nB));
                                break;
                            case R.id.btnDiv:
                                tv.setText(""+div(nA,nB));
                                break;
                        }
                }
            };
            btnAdd.setOnClickListener(ocl);
            btnSub.setOnClickListener(ocl);
            btnMul.setOnClickListener(ocl);
            btnDiv.setOnClickListener(ocl);
    
    
        }
    
        /**
         * A native method that is implemented by the 'native-lib' native library,
         * which is packaged with this application.
         */
        public native String stringFromJNI();
    }
    15.activity_main.xml代码如下
    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <EditText
            android:id="@+id/editTextB"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="56dp"
            android:autofillHints=""
            android:ems="10"
            android:inputType="textPersonName"
            android:text="@string/ediB"
            app:layout_constraintStart_toStartOf="@+id/editTextA"
            app:layout_constraintTop_toBottomOf="@+id/editTextA" />
    
        <TextView
            android:id="@+id/sample_text"
            android:layout_width="92dp"
            android:layout_height="23dp"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintHorizontal_bias="0.498"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.795" />
    
        <EditText
            android:id="@+id/editTextA"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="91dp"
            android:autofillHints=""
            android:ems="10"
            android:inputType="textPersonName"
            android:text="@string/ediA"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/btnAdd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="16dp"
            android:text="@string/add"
            app:layout_constraintBaseline_toBaselineOf="@+id/btnSub"
            app:layout_constraintEnd_toStartOf="@+id/btnSub"
            app:layout_constraintHorizontal_chainStyle="packed"
            app:layout_constraintStart_toStartOf="parent" />
    
        <Button
            android:id="@+id/btnSub"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="60dp"
            android:layout_marginEnd="5dp"
            android:text="@string/sub"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/btnAdd"
            app:layout_constraintTop_toBottomOf="@+id/editTextB" />
    
        <Button
            android:id="@+id/btnDiv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="34dp"
            android:layout_marginEnd="5dp"
            android:text="@string/div"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/btnMul"
            app:layout_constraintTop_toBottomOf="@+id/btnSub" />
    
        <Button
            android:id="@+id/btnMul"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="16dp"
            android:text="@string/mul"
            app:layout_constraintBaseline_toBaselineOf="@+id/btnDiv"
            app:layout_constraintEnd_toStartOf="@+id/btnDiv"
            app:layout_constraintHorizontal_chainStyle="packed"
            app:layout_constraintStart_toStartOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>

    16.测试运行

    源文件下载:

    链接:https://pan.baidu.com/s/1KZrjlLP9OiThZdT-MYeJbA
    提取码:qiol

  • 相关阅读:
    汇编指令
    汇编指令
    汇编指令
    字在寄存器中的存储
    汇编指令
    字在寄存器中的存储
    汇编指令
    8086CPU的8位寄存器数据存储情况
    [转载]使用嵌入式 Tomcat 简化程序调试
    [转载]Java语法总结
  • 原文地址:https://www.cnblogs.com/fuhua/p/12725771.html
Copyright © 2011-2022 走看看