目的

能快速,简单(主要是指脱离AndroidStudio)的把c/c++ 源码进行交叉编译成Android上的动态库,静态库,或者可执行文件。从而为逆向分析构建demo节省时间。

编译环境配置

电脑:Mac OS 10.13.4
NDK:官网下载,目前最新的好像android-ndk-r17 我用的是 android-ndk-r14b,ndk不需要安装官网下载后解压就行。
测试机: 华为EVA-AL00 Android7.0

配置环境变量

为了方便使用ndk的命令行工具,我们配置环境变量
~/.bash_profile 文件中添加如下配置

export ANDROID_NDK_HOME=/Users/user01/Development/android-ndk-r14bexport PATH=${PATH}:${ANDROID_NDK_HOME}:${ANDROID_NDK_HOME}/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin

然后命令行运行如下命令:

$ source ~/.bash_profile

然后命令行运行:

$ ndk-build -h

如果能打印出 ndk-build 这个工具的帮助文档说明环境变量配置成功

测试简单的例子

创建如下目录结构(注意jni这层目录很重要,名字不要随便取):

~/Desktop/test/└── jni/    ├── Android.mk    ├── Application.mk    └── test.c

主要有三个文件,其中Android.mk和Application.mk 是辅助ndk-build进行编译的,test.c是我们的c测试用例

  1. Application.mk

主要指定生成哪些cpu架构的动态库,这里只生成armeabi 和armeabi-v7a架构的库

APP_ABI      := armeabi armeabi-v7aAPP_PLATFORM := android-14
  1. Android.mk

具体Android.mk的更详细的配置自行Google

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)# 生成的so库的名字为libdemo.soLOCAL_MODULE    := demo# 用于编译的c文件LOCAL_SRC_FILES := test.c# 生成库的类型,是动态库,静态库还是可执行文件,这里先来生成一个动态库include $(BUILD_SHARED_LIBRARY)# 下面这么写是生成可执行文件#include $(BUILD_EXECUTABLE)
  1. test.c

很简单就是打印一句 hello world!

#include int main(const int argc,const char* args[]){const char* str  = "hello world!";printf("%s\n",str);return 0;}

然后命令行进入到test目录下面:

$ cd ~/Desktop/test

$ ndk-build -C ./jni

然后会生成如下目录结构,obj目录下是生成动态库的中间文件,libs里面是最终生成的不同CPU架构的动态库:

test├── jni│   ├── Android.mk│   ├── Application.mk│   └── test.c├── libs│   ├── armeabi│   │   └── libdemo.so│   └── armeabi-v7a│       └── libdemo.so└── obj    └── local        ├── armeabi        │   ├── libdemo.so        │   └── objs        │       └── demo        │           ├── test.o        │           └── test.o.d        └── armeabi-v7a            ├── libdemo.so            └── objs                └── demo                    ├── test.o                    └── test.o.d

为什么非要有jni那一层目录

约定优于配置,没有不行吗?行,但是要改点东西。去掉jni那层目录再编译一次,当前目录结构如下:

test/├── Android.mk├── Application.mk└── test.c

命令行执行

  1. $ cd ~/Desktop/test
  2. $ ndk-build

结果报错如下:

Android NDK: Could not find application project directory !Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.

错误日志上说什么路径找不到错误,需要定义一个xx变量,我们只需要把编译命令改成如下就可以了:

ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk NDK_APPLICATION_MK=./Application.mk

编译一个可以允许的文件

修改Android.mk 文件如下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := demoLOCAL_SRC_FILES := test.c#include $(BUILD_SHARED_LIBRARY)# Android4.4 以后 调用的可执行文件不是基于PIE方式编译的,则无法运行LOCAL_CFLAGS += -pie -fPIELOCAL_LDFLAGS += -pie -fPIE# 编译一个可执行文件include $(BUILD_EXECUTABLE)

这个可执行文件在电脑上是没法执行的,只能放到手机里面执行,执行如下命令,我们把刚生成的文件放到手机上:

  1. push 文件到手机
    $ adb push libs/armeabi-v7a/demo /data/local/tmp
  2. 为手机中的demo文件添加可执行权限(为了方便直接给予所有权限了)
    $ adb shell 'chmod 777 /data/local/tmp/demo'
  3. 用手机环境运行demo这个文件
    $ adb shell '/data/local/tmp/demo'

运行结果会打印一行
hello world!

更多相关文章

  1. Linux Android(安卓)反编译
  2. Android中assets目录和raw目录的区别和使用情况
  3. Android(安卓)Zxing创建带文字的一维码(条形码)
  4. 【Android笔记 九】Android(安卓)Sharedpreferences实现用户偏好
  5. android PinYinIME横屏模式禁止全屏输入 & 调整横屏模式下键盘高
  6. 开始启程,你的第一行
  7. Android资源文件strings实现特殊字符转义
  8. android 手机存储文件夹学习
  9. android布局文件中一些属性介绍

随机推荐

  1. AndroidManifest.xml文件详解(activity)(一)
  2. Android广播机制
  3. Android 实现windows文件资源管理器
  4. 背光之关闭(turnOff)
  5. android TextView setEms 方法名字
  6. Android 简单录音程序
  7. android 字体大小,样式 ,像素的设置
  8. android 设置textview跑马灯效果
  9. Android实现底部切换标签
  10. Android 内核源代码交叉编译纺