在Andriod Studio 开发使用C语言实现莱布尼茨公式求 π 的近似值的简易计算app详细过程以及使用 Obfuscator-LLVM (Pluto-obfuscator)设置代码混肴

本文详细描述了创建一个Android应用的过程,包括设计UI界面、使用C语言实现莱布尼茨公式求π的近似值、自定义模块封装和JNI接口,以及混淆代码以提高安全性的步骤。
摘要由CSDN通过智能技术生成

一、创建项目 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行,效果图展示如下:

  • 29
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值