- 对本书的赞誉
- 前言
- 基础篇
- 第 1 章 Android 中锁屏密码加密算法分析
- 第 2 章 Android 中 NDK 开发
- 第 3 章 Android 中开发与逆向常用命令总结
- 第 4 章 so 文件格式解析
- 第 5 章 AndroidManifest.xml 文件格式解析
- 第 6 章 resource.arsc 文件格式解析
- 第 7 章 dex 文件格式解析
- 防护篇
- 第 8 章 Android 应用安全防护的基本策略
- 第 9 章 Android 中常用权限分析
- 第 10 章 Android 中的 run-as 命令
- 第 11 章 Android 中的 allowBackup 属性
- 第 12 章 Android 中的签名机制
- 第 13 章 Android 应用加固原理
- 第 14 章 Android 中的 so 加固原理
- 工具篇
- 第 15 章 Android 逆向分析基础
- 第 16 章 反编译神器 apktool 和 Jadx
- 第 17 章 Hook 神器 Xposed
- 第 18 章 脱壳神器 ZjDroid
- 第 19 章 Native 层 Hook 神器 Cydia Substrate
- 操作篇
- 第 20 章 静态方式逆向应用
- 第 21 章 动态调试 smali 源码
- 第 22 章 IDA 工具调试 so 源码
- 第 23 章 逆向加固应用
- 第 24 章 逆向应用经典案例分析
- 第 25 章 Android 中常见漏洞分析
- 第 26 章 文件加密病毒 Wannacry 样本分析
2.2 第一行代码:HelloWorld
本节开始介绍 JNI 技术,先输出一个 Hello World。具体流程如下,在 Java 中定义一个方法,在 C++中实现这个方法,在方法内部输出“Hello World”,然后再回到 Java 中进行调用。
第一步:在 Eclipse 中建立一个类:JNIDemo。
命令如下:
其中 sayHello 就是要在 C++中实现的方法。
第二步:使用 javah 命令将 JNIDemo 生成.h 的头文件。
命令如下:
注意:
·首先要确保配置了 Java 的环境变量,不然 javah 命令不能用。
·案例的 Java 项目是放在 E:\workspace 中的,所以首先进入项目的 bin 目录中,然后使用 javah 命令生成头文件。
·javah 后面的类文件格式是类的全名(包名+class 文件名),同时不能有.class 后缀。
命令执行成功后会在 bin 目录中生成头文件 com_jni_demo_JNIDemo.h,参见图 2-15。
图 2-15 javah 命令参数说明
注意:如果包含 native 方法的类,引用其他地方的类,那么进入 bin\classes\目录下会出现问题提示找不到指定的类,这时候需要切换到源码目录 src 下运行即可。
第三步:使用 VC6.0 生成.dll 文件。
首先创建一个 dll 工程,如图 2-16~图 2-18 所示。
在.cpp 文件中输入如下代码:
图 2-16 VC6.0 生成.dll 文件
图 2-17 VC6.0 生成.dll 文件
图 2-18 VC6.0 生成.dll 文件
这个方法的声明可以在上面生成的 com_jni_demo_JNIDemo.h 头文件中找到,这个就是 Java 工程中的 sayHello 方法的实现:
这里编译会出现以下几个问题:
1)会提示找不到相应的头文件,如图 2-19 所示。这时需要将 jni.h、jni_md.h 文件拷贝到工程目录中,这两个文件的具体位置参见图 2-20。
Java 安装目录中的 include 文件夹下,jni_md.h 文件在 win32 文件夹中,找到这两个文件后,将其拷贝到 C++的工程目录中。
图 2-19 编译之后的头文件
图 2-20 jni.h 文件
2)当拷贝到这两个文件之后,编译还是提示找不到这两个文件:主要原因是#include<jni.h>是从系统目录中查找 jni.h 头文件的,而这里只把 jni.h 拷贝到工程目录中,所以需要在 com_jni_demo_JNIDemo.h 头文件中将#include<jni.h>改成#include"jni.h"。同理,在 jni.h 文件中将#include<jni_md.h>改成#include"jni_md.h"。
3)同时还有一个错误提示:e:\c++\jnidemo\jnidemo.cpp(9):fatal error C1010:unexpected end of file while looking for precompiled header directive,这是指预编译头文件读写错误,这时候还要在 VC 中进行设置:项目→设置→C/C++。在分类中选择预编译的头文件,选择不使用预补偿页眉,如图 2-21 所示。
这样,编译成功,生成 JNIDemo.dll 文件在 C++工程中的 Debug 目录中。
注意:因为之前开发都是使用 VC 工具,所以这里使用了 VC 6.0 来进行 C++代码的编写和运行,其实可以直接使用 Eclipse 或在 Android Studio 中也可以进行编写,这样会更方便。
第四步:将 JNIDemo.dll 文件添加到环境变量中,如图 2-22 所示。
注意:在用户变量中的 path 设置,用分号隔开:“;E:\C++\Debug”,这样就将.dll 文件添加到环境变量中了。
第五步:在 Eclipse 中调用 sayHello 方法,输出“Hello World”。代码如下:
图 2-21 预编译头文件
图 2-22 将 JNIDemo.dll 文件添加到环境变量中
System.loadLibrary 方法是加载 JNIDemo.dll 文件的,一定要注意不要有.dll 后缀名,只需要文件名即可。
注意,运行的时候会报错,如图 2-23 所示。
图 2-23 运行错误
这个提示是没有找到 JNIDemo.dll 文件,这时需要关闭 Eclipse,然后再打开,运行就没有错了。原因是 Eclipse 每次打开的时候都会去读取环境变量的配置,刚才配置的 path 没有立即生效,所以要关闭 Eclipse,然后重新打开一次即可。
注意:这里因为使用了 VC 编辑器进行 native 代码的编写,所以需要配置 dll 文件操作,但是现在更多的是习惯直接在 Eclipse/Android Studio 中配置 C++环境直接编写了,这样更方便。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论