赞
踩
一、创建项目 myapplication
我的项目文件大致是这样,这是我制作之后的全部文件:
二、设计UI界面布局
在\res\layout\activity_main.xml文件中添加两个TextView元素作为文字提示,一个EditText元素实现输入精度值,两个Button元素,分别实现计算和清空结果功能。
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">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center_horizontal"
- android:orientation="vertical"
- tools:layout_editor_absoluteX="16dp"
- tools:layout_editor_absoluteY="171dp">
-
- <TextView
- android:id="@+id/vText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_columnSpan="4"
- android:layout_margin="5dp"
- android:paddingLeft="12dp"
- android:gravity="left"
- android:text="Approximated value of Pi:"
- android:textSize="17dp"
- />
-
- <TextView
- android:id="@+id/showText"
- android:layout_width="match_parent"
- android:layout_height="35dp"
- android:layout_columnSpan="4"
- android:layout_margin="5dp"
- android:paddingTop="5dp"
- android:paddingLeft="12dp"
- android:gravity="left"
- android:text="Showing Result.. "
- android:textSize="17dp"
- app:layout_constraintTop_toBottomOf="@id/countButton" />
-
- <EditText
- android:id="@+id/inText"
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:layout_marginStart="10dp"
- android:hint="Please enter a number."
- android:inputType="numberDecimal" />
-
- <Button
- android:id="@+id/countButton"
- android:layout_width="150dp"
- android:layout_height="55dp"
- android:layout_marginTop="25dp"
- android:layout_marginRight="80dp"
- android:text="calculate" />
-
- <Button
- android:id="@+id/DeleteButton"
- android:layout_width="150dp"
- android:layout_height="55dp"
- android:layout_marginLeft="80dp"
- android:layout_marginTop="-55dp"
- android:text="delete" />
- </LinearLayout>
-
- </androidx.constraintlayout.widget.ConstraintLayout>

布局展示:
三、使用C语言实现莱布尼茨公式求 π 的近似值;
在cpp/native-lib.cpp文件中编写实现pi的近似值计算的程序代码,代码如下图:
- #include <jni.h>
- #include <string>
- #include <stdio.h>
- #include <cmath>
- using namespace std;
- #define PI 3.1415926535
-
- extern "C" JNIEXPORT jdouble JNICALL
- Java_com_example_myapplication_JNI_1N_calculationPI(
- JNIEnv* env,
- jclass /* this */, jdouble precision) {
- double pi = 0.0;
- double term = 1.0;
- int sign = 1;
- while(fabs(pi*4-PI)> precision)
- {
- pi += sign * (1.0 / term);
- term += 2.0;
- sign *= -1;
- }
- return 4.0 * pi;
- }
-
-

四、在自定的apps开放平台里设计并实现模块的封装及接口定义;
①java实现布局中各元素的事件处理
在\Java\com.example.myapplication\MainActivity.java文件中定义MainActivity类,继承自AppCompatActivity,并实现OnClickListener接口。这一步的目的是为两个Button元素定义单独的事件处理程序。在这个类中,将实现用户点击计算Button进行计算pi近似值和清除Button进行清空结果。
MainActivity.java代码展示:
- package com.example.myapplication;
- import androidx.appcompat.app.AppCompatActivity;
- import static com.example.myapplication.JNI_N.calculationPI;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.TextView;
- import android.widget.Button;
- import android.widget.EditText;
- public class MainActivity extends AppCompatActivity {
- static {
- System.loadLibrary("application");
- }
- @Override
- protected void onCreate(Bundle SaveInstanceState) {
- super.onCreate(SaveInstanceState);
- setContentView(R.layout.activity_main);
- //声明并初始化
- TextView tv=findViewById(R.id.showText);
- Button cButton=findViewById(R.id.countButton);
- Button delButton=findViewById(R.id.DeleteButton);
- EditText InText=findViewById(R.id.inText);
- //通过JNI_N.calculationPI(precision)来结合c++实现点击计算的按钮进行计算并展示结果
- cButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- cButton.setOnClickListener(this);
- String input = InText.getText().toString();
- if (!input.isEmpty()) {
- double precision = Double.parseDouble(InText.getText().toString());
- double pi = JNI_N.calculationPI(precision);
- tv.setText(" " + pi);
- }
- else
- {
- tv.setText("Please enter a number.");
- }
- } });
- //清除结果
- delButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- delButton.setOnClickListener(this);
- tv.setText(" ");
- }
- });
- }
- }
-
-
-
-
-

上面代码中,double pi = JNI_N.calculationPI(precision); 是调用c语言代码接口。而这个接口声明定义我是在新建的另一个JNI_N.java文件中声明的,代码如下图:
- package com.example.myapplication;
-
- public class JNI_N {
- // static {System.loadLibrary("pi");}
- public static native double calculationPI(double precision);
- }
我对MainActivity.java代码简单解释一下哈:
计算Button点击事件实现代码是上面MainActivity.java代码中的:
清除结果Button点击事件实现代码是上面MainActivity.java代码中的:
注意:求π 的近似值的c语言代码必须在Java_com_example_myapplication_JNI_1N_calculationPI(JNIEnv* env,jclass /* this */, jdouble precision){}方法内实现。JNI_1N就是JNI_N.java中的JNI_N类名,calculationPI就是接口名。
五、CMakeLists.txt文件中也要添加项目名字:
然后编译程序(Make Project),试着运行(Run)看看能不能成功,编译成功后会生成xxx.so文件,如下图:
六、在自制简单demo工程里调用模块实现输入精度值(不少于5组精度值),输出 π 值;
运行demo工程可以在手机中显示的一个计算pi近似值app界面,输入精度值,点击calculate得出结果,点击delete清除结果。实现效果如下图:
七、设置 Obfuscator-LLVM 的代码混淆参数并对封装后的模块编译生成库文件;
混淆前先使用的反汇编工具是IDA 进行查看libapplication.so的反汇编代码。直接将Andriod Studio的工程文件中的cpp\jniLibs\x86文件下的libapplication.so拖进去IDA界面中。回到Andriod Studio就可以看到cpp\jniLibs\x86下多了几个libapplication.so.xxx。
以下是使用IDA查看.so文件步骤(直接将Andriod Studio的工程文件中的cpp\jniLibs\x86文件下的libapplication.so拖进去IDA界面中):
(1)混淆前先做环境配置工作准备,分别下载并安装好Obfuscator-LLVM、cmake、Mingw。
我下载的是obfuscator-llvm-9.0.1版。
(2)cmd进入命令窗口,进入obfuscator-llvm-9.0.1目录下,新建一个build目录文件:mkdir build ,obfuscator-llvm-9.0.1目录下就会出来一个空的build 文件夹 。
(3)然后进入build目录文件中执行以下操作:
①初始化MakeFIle,输入命令:cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF ../../obfuscator-llvm-9.0.1
②开始编译,编译时间>=30min,电脑配置好的话可能会短些。输入命令:mingw32-make.exe -j8
(4)编译完成后,build文件中就会生成很多文件,然后我将obfuscator-llvm-9.0.1\build\bin下的 clang、clang-format、clang++ 三个文件复制替换到我存放Andriod studio用的ndk文件夹D:\solft\appgalley\ndk\21.4.7075529\toolchains\llvm\prebuilt\windows-x86_64\bin(这个ndk文件是看你之前安装An下的ndk存放的位置。这里面的这三个文件最好复制一份保存到别的地方,以防替换不成功还可以恢复)中。
(5)接着我将obfuscator-llvm-9.0.1\build\lib\clang\9.0.1\include下的__stddef_max_align_t.h 、stdarg.h 、stddef.h三个文件复制替换到我存放Andriod studio用的ndk文件夹D:\solft\appgalley\ndk\21.4.7075529\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\include下。
(6)设置环境变量:系统变量中Path中添加cmake,mingw64的环境变量
(7)设置参数修改 CMakeLists.txt
(8)然后clean project再编译程序make project,成功就可以了。
八、再把新的.so文件拖到IDA中查看,对比混淆代码前后的库文件,反汇编的结果;
下面是我的demo工程文件生成.so文件在IDA中的原本样子展示以及源代码(20行)展示:
混淆后框框变多了,代码变复杂了,代码原本只有20行,变成了31行,效果图展示如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。