Android中的NDK开发

环境配置

新建一个,这里命名为NDKbase吧

然后在java目录同层新建jni目录:new->folder->jni folder。

右键点击app目录,选择Open mode Setting。然后配置其中的SDK Location,使其指向ndk开发环境。

配置app/build.gradle中的ndx选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
defaultConfig {
applicationId "com.example.ndkbase"
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
ndk{
moduleName "encrypto"
abiFilters "armeabi", "armeabi-v7a", "x86"
ldLibs "logs"
}
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

其中moduleName为so文件名称,abiFilters为支持的体系结构,ldLibs "logs"为增加log的lib库。

然后再build目录下生成指定的so文件,拷贝到项目的libs目录下即可。

Hello World

参考:https://blog.csdn.net/zhuowalun8427/article/details/105970017/

因为是java14的,所以命令改成:

1
javac -h jni -classpath H:\code\Android\nativelib\app\build\intermediates\javac\debug\classes java/com/example/native_lib/myjni.java

JNIEnv类型和jobject类型

JNIEnv类型

JNIEnv类型代表了Java环境,通过JNIEnv* 指针就可以对Java端的代码进行操作。

JNIEnv类型有很多函数可用:

NewObject:创建Java类中的对象。

NewString:创建Java类中的String对象。

New<Type>Array创建类型为Type的数组对象。

Get<Type>Field获取类型为Type的字段。

Set<Type>Field设置类型为Type的字段的值。

GetStatic<Type>Field获取类型为Type的static的字段。

SetStatic<Type>Field设置类型为Type的static的字段的值。

Call<Type>Method调用返回类型为Type的方法。

CallStatic<Type>Method调用返回类型为Type的static方法。

jobject参数obj

如果native方法不是static,obj就代表native方法的类实例。

如果native方法是static,obj就代表native方法的类的class对象实例。

Java类型和native中的类型映射关系

具体可以查看jni.h文件

jclass类型

jclass类型用于表示Java中的Class类。

JNIEnv中有以下几个函数可以取得jclass:

jclass FindClass(const char* clsName)通过类名(类的全名,包名是用/分割的)来获取jclass。

jclass GetObjectClass(jobject obj)通过对象实例来获取jclass。

jclass GetSuperClass(jclass obj)通过jclass获取其父类的jclass对象。

native中访问Java层代码

为了在C/C++中表示属性和方法,JNI在jni.h头文件中定义了jfieldId、jmethodID类型来分别代表Java的属性和方法。在访问时,需要先获取ID,然后才能再本地代码中进行操作或调用。

JNIEnv的如下方法可以获得jfieldId和jmethodID:

  • GetFiledID/GetMethodID
  • GetStaticFieldID/GetStaticMethodID

以GetFiledID方法为例,其定义如下:

GetFiledID(jclass clazz, const char* name, const char* sign)

其中的三个参数:

clazz:这个方法依赖的类对象的class对象。

name:这个字段的名字。

sign:这个字段的签名。

JNIEnv类型中方法的使用

略过

Android中开发与逆向常用命令总结

基础命令

cat

echo

touch

非shell命令

需要提前用adb shell命令运行的命令叫做shell命令,直接用adb shell运行的命令叫做非shell命令。

  • adb shell dumpsys activity top 可以查看当前应用的activity信息。
  • adb shell dumpsys 同上,但会打印四大组件的信息。
  • adb shell dumpsys package [pkgname] 可以查询指定包名应用的详细信息(相当于应用的AndroidManifest.xml中的内容)。
    adb shell dumpsys meminfo [pname/pid] 可以查看指定进程名或进程id的内存信息。
  • adb shell dumpsys dbinfo [packagename] 可以查看指定包名应用的数据库存储信息(包括存储的SQL语句)。
  • adb install [apk] 安装指定应用宝apk文件,-r参数相当于升级。
  • adb uninstall [packagename] 卸载应用。
  • adb pull [设备目录文件] [本地目录] 下载设备上的文件到本地。
  • adb pull [本地目录] [设备目录文件] 上传本地文件到目录。
  • adb shell screencap -p [路径] 截屏。
  • adb shell screenrecord [路径] 录屏。
  • adb shell input text [content] 输入文本内容。
  • adb forward [远程端协议:端口号] [设备端协议:端口号] 设备的端口转发。
  • adb jdwp 查看设备中可以被调试的应用的进程号。
  • adb logcat 查看当前日志信息。

shell命令

  • run-as [packagename] 可以在非root设备中查看指定debug模式的包名应用沙盒数据。
  • ps 查看进程信息。
  • pm clear [packagename] 清空指定包名应用的数据
  • pm install [apk] 安装apk文件。
  • pm uninstall [packagename] 卸载应用。
  • am start -n [packagename]/[packagename].[Activity] 启动一个指定活动。debug方式需加-D参数。
  • am startservice -n [packagename]/[packagename].[service] 启动一个服务。
  • am broadcast -a [广播动作] 发送一个广播。
  • netcfg 查看设备的ip地址。
  • netstat 查看设备的端口号信息。
  • app_process [运行代码目录] [运行主类] 运行java代码。
  • dalvikvm -cp [dex文件] [运行主类] 运行一个dex文件。
  • top 查看当前应用的CPU消耗信息。
  • getprop [属性值名称] 查看系统属性值

操作apk命令

  • aapt dump xmltree [apk包名] [需要查看的资源文件xml] 查看apk中的信息以及编辑apk程序包。
  • dexdump [dex文件路径] 查看dex文件的详细信息。

进程命令

查看当前进程的内存加载情况

cat /proc/[pid]/maps

查看进程的状态信息

cat /proc/[pid]/status

查看当前应用使用的端口号信息

cat /proc/[pid]/net/[四选一:tcp/tcp6/udp/udp6]

so文件格式解析

略,参考:《Linux二进制分析》 | nuoye https://nuoye-blog.github.io/2020/05/09/%E7%AC%94%E8%AE%B0/Linux%E4%BA%8C%E8%BF%9B%E5%88%B6%E5%88%86%E6%9E%90/Linux%E4%BA%8C%E8%BF%9B%E5%88%B6%E5%88%86%E6%9E%90/

具体可直接看书或用命令man 5 elf了解。