上一篇 《教我兄弟学Android逆向05 在smali代码中插入Log 》我教会了你随心所欲的在smali代码中插入log,你也很认真的学习了,那么这节课我将带你走进so的世界,这时你有一些疑问,经常听比人说soso的那么so到底是什么呢?我是来学破解技术的啊为什么这节课要让我编写so?
先看一下下面的介绍:
Android开发中,我们经常会用到.so文件。原因有很多,比如部分方法不想暴露,如加密规则。比如部分秘钥需要存储,哪怕最简单的一个String。我们使用.so调用获取这个String,也比直接明文写在代码中要来的安全。那么逆向破解也是一样,你要破解一个so就得先学习这个so是怎么编写的 为了避免以后破解so时知其然而不知其所以然 所以今天我为你带来了这篇教程。
那么今天的主线是:如何用AndroidStudio编写一个so并在java层调用so中的方法?
带着这条主线 我将开始今天的教程 下面要认真听课了!
一.
打开AndroidStudio 新建一个类,声明native方法。这个类是java与C/C++交互的中介,方法由java声明,由C/C++实现。
![](https://i-blog.csdnimg.cn/blog_migrate/29d732847c2de511d994ab6c18e2d9dd.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2fc789d57babf1b0bacbe3ab625b6811.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3d5e4d6d9a37289b2535d9ffe8e64771.png)
public class myJNI {
//加载so库
static {
System.loadLibrary("JniTest");
}
//native方法
public static native String sayHello();
}
二.打开android studio终端,使用javac编译上述文件,生成class文件。
1.打开myJNI类所在的目录,并复制路径
![](https://i-blog.csdnimg.cn/blog_migrate/3a4a811f3cf6d2359f78db27adb435a6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/45a87876909cbf72c82b3d1f354247b8.png)
2.找到AndroidStudio最底部的Terminal打开命令行 输入命令cd+自己刚刚复制的目录(如果底部没有Terminal 按住快捷键alt+f2也能调出来)
![](https://i-blog.csdnimg.cn/blog_migrate/a32b46be7a111f203577d1c121f4e0f4.png)
3.使用javac编译上述文件,生成class文件。
![](https://i-blog.csdnimg.cn/blog_migrate/44d48e20418fb1247fe4363bf97cf9e8.png)
4.
确认自己的包名和类名!然后在java目录使用 javah -jni 包名.类名 命令生成.h头文件
然后就能看到生成了一个h文件。
注意
一定要在java层目录下输入命令,不然不会报错:找不到xxx类
![](https://i-blog.csdnimg.cn/blog_migrate/81bf4d690f499abc9087ae3fd7e6fe3b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/692412c4d11b57b78da089835701522c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d91bbdb9cd5b45980874cb41b994c322.png)
三。
新建一个jni文件夹,新建main.c,把.h里面的内容复制进去,并实现里面的函数。
1. 新建一个jni文件夹
![](https://i-blog.csdnimg.cn/blog_migrate/9535ff236aadf5ce0ec56be7b4eaad84.png)
2.
新建main.c
![](https://i-blog.csdnimg.cn/blog_migrate/d55c0d7dd045b4f16849a950896ba096.png)
![](https://i-blog.csdnimg.cn/blog_migrate/03bc5af3af19ba57f3f394d2cf8bce70.png)
3.
生成的h文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
<jni.h>
/* Header for class com_jwxdxnx06_myJNI */
#ifndef
_Included_com_jwxdxnx06_myJNI
#define
_Included_com_jwxdxnx06_myJNI
#ifdef
__cplusplus
extern
"C"
{
#endif
/*
* Class: com_jwxdxnx06_myJNI
* Method: sayHello
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jwxdxnx06_myJNI_sayHello
(JNIEnv *
,
jclass)
;
#ifdef
__cplusplus
}
#endif
#endif
拷贝修改后的main.c
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jwxdxnx06_myJNI */
#ifndef
_Included_com_jwxdxnx06_myJNI
#define
_Included_com_jwxdxnx06_myJNI
#ifdef
__cplusplus
extern
"C"
{
#endif
/*
* Class: com_jwxdxnx06_myJNI
* Method: sayHello
* Signature: ()Ljava/lang/String;
*/
//就实现了个函数 JNIEnv的用法可以自行百度,这里就不展开了
JNIEXPORT jstring JNICALL Java_com_jwxdxnx06_myJNI_sayHello(JNIEnv *env
,
jclass jobj)
{
//返回一句话
return
(*env)->NewStringUTF(env
,
"hello 52pojie!"
)
;
}
#ifdef
__cplusplus
}
#endif
#endif
4.还要在jni文件夹下添加一个空白的util.c文件,不然会报错,我也不知道为什么。
![](https://i-blog.csdnimg.cn/blog_migrate/88f4855ba3e8c06b6a9826aa18f73fd7.png)
5、配置NDK
打开Project的local.properties文件添加NDK路径 ndk下载
链接:
https://pan.baidu.com/s/1K0yDiJsn4cI0k1Bnpv920A
密码:hj4o
![](https://i-blog.csdnimg.cn/blog_migrate/f8fbcae707067b14502798affa62d6e1.png)
6.打开app Module的build.gradle文件,在defaultConfig节点里添加以下代码
注意这里的moduleName,是我们在之前自己编写的类里面加载的so库名
ndk {
moduleName
"JniTest"
ldLibs
"log", "z", "m"
abiFilters
"armeabi", "armeabi-v7a", "x86"
}
![](https://i-blog.csdnimg.cn/blog_migrate/39b9ee83019f9ad6e4f7930b1fc75b19.png)
7.
还要在gradle.properties里面加上这么一句话:
android.useDeprecatedNdk=true
![](https://i-blog.csdnimg.cn/blog_migrate/dd565bcef31837aad84524a481b91464.png)
四
生成SO库
1.完成以上步骤之后,我们rebuild一下就可以生成so库了 生成的so在项目的app\build\intermediates\ndk\debug\lib路径下
![](https://i-blog.csdnimg.cn/blog_migrate/6813097bf9fa545fe4f0973c580c0b58.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4bf06803f9fd3f119b88423e9d69a2d9.png)
五.配置so库
1.
在src\main下新建文件夹jniLIB,并将生成的SO文件拷贝到该文件夹下
![](https://i-blog.csdnimg.cn/blog_migrate/efe2eadaf435ff23e563cabe221235c3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a159e7188dd1046feabdd9e5f9da1584.png)
六.
打开MainActivity.java插入一条log来调用so中的sayHello方法,并连接手机调试
![](https://i-blog.csdnimg.cn/blog_migrate/34f7c2129f0c5dffe232a324a70875e7.png)
![](https://i-blog.csdnimg.cn/blog_migrate/95f46e0b009111602391c982fec8a4a6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ee963e4ef07865f6c3f28fc62dafeff8.png)
七.总结
本节课带你编写了第一个so文件,并在java层调用了so中的sayHello方法,学习完本节课相信你已经对so有了初步的了解,本节课的例子自己一定要跟着做一遍 ,对本节课教程中不懂得有疑问的,自己一定要去百度 。完成本节课的例子后,记得做课后作业。
本节课所用到的AndroidStudio项目和生成的Apk:
课后作业:
编写so并在里面实现一个加法的功能
最终效果:java层调用so中的Add方法,传入两个参数22和30,通过log显示出来52。