android安全学习
主要参考《CTF训练营》
android
Android是一种基于Linux的开源的操作系统,主要用于移动设备,如智能手机和平板电脑
- 2003年10月,Andy Rubin等人一起创办了Android公司
- 2005年8月,谷歌收购了该公司,并让Andy Rubin继续负责Android项目
- 2007年,谷歌开放了Android的源代码,加速了Android普及
- 2008年谷歌推出Android系统的第一个版本
- 2017年3月,Android全球网络流量和设备超越Microsoft Windows,正式成为全球第一大操作系统
自2008年以来,Android已更迭了许多版本:
Android系统架构:
- 应用框架:提供应用程序开发的各种API
- Binder IPC:Binder进程间通信机制,为高级框架 API 与 Android 系统服务提供交互
- 系统服务:专注于特定功能的模块化组件
- 硬件抽象层 (HAL):让 Android 忽略较低级别的驱动程序实现
- Linux 内核:提供硬件底层驱动
android studio项目开发
Android Studio 是用于开发 Android 应用的官方集成开发环境 (IDE),以 IntelliJ IDEA 为基础构建而成
下载链接:https://developer.android.com/studio
项目结构
Android Studio项目结构主要包括:
- manifests文件夹:
- 包含 AndroidManifest.xml 文件,该清单文件描述了Android 构建工具、Android 操作系统和应用的基本信息。比如文件中声明了软件包名称和应用 ID,也声明了应用的组件,包括所有 Activity、服务、广播接收器和内容提供程序,以及应用所需的访问权限和需要的硬件和软件功能。
- java文件夹:包含 Java 源代码文件,以及其他测试文件
- res文件夹:包含所有非代码资源(例如 XML 布局、界面字符串和位图图像),这些资源划分到相应的子目录中
- drawable文件夹:包含应用程序开发过程中所需的不同类型的图像
- layout文件夹:包含用来定义应用程序用户界面的所有XML布局文件,最重要的是activity_main.xml文件,描述主页面控件的布局
- values文件夹
- 包含如字符串、尺寸、颜色和样式定义在内的许多XML文件
- 其中一个最重要的文件是包含字符串信息的strings.xml文件
Android SDK
Android SDK是开发Android应用程序所需的软件开发工具和库的集合,谷歌每发布一个新的Android版本或更新版本,就会发布相应的SDK,开发者必须下载并安装。
在导航栏可以打开sdk manager。
sdk manager:
Android SDK包含了从头开始编写程序一直到进行测试所需的所有工具, 这些工具使得从开发、调试到打包的整个开发过程非常顺畅:
- Android SDK Tools:包含一套完整的Android开发和调试工具, android studio中已包含
- SDK Build Tools:用于构建Android应用程序的二进制文件
- SDK Platform:SDK平台的版本是由Android版本(如Android 7)和API版本(如API级别24)确定的,在构建Android应用程序之前,必须指定一个SDK平台作为构建目标,较新的SDK平台版本为开发者提供了更多特性,但较旧的设备可能与较新的平台版本不兼容
- SDK Platform-Tools:平台工具用于支持当前Android平台的特性,与测试设备上的Android平台交互,例如**Android Debug Bridge (adb)**就是一个用于与设备通信的方便的命令行工具,SDK Platform-Tools向后兼容,所以只需要一个版本即可
- Android Emulator:Android Emulator是一种设备仿真工具,可在计算机上模拟Android设备,从而使开发人员可以在不同设备和Android API级别上测试应用程序,而无需为每个设备都配备物理设备。该工具可以模拟多种Android设备,如Android手机、平板电脑、Wear操作系统和Android电视设备。它提供了提供了真正Android设备的几乎所有功能,如打电话、发短信等。
Android NDK
Android NDK 是一个工具集,可使用 C 和 C++ 等语言以原生代码(native code)实现应用的各个部分,其主要功能为:
- 进一步提升设备性能,以降低延迟或运行游戏、物理模拟等计算密集型应用
- 重复使用自己或其他开发者的 C 或 C++ 库
Android NDK构建原生应用时使用的主要组件:
- 原生共享库:NDK 从 C/C++ 源代码构建这些库或 .so 文件。
- Java 原生接口 (JNI):JNI 是 Java 和 C/C++组件用于相互通信的接口,它允许在Java虚拟机中运行的Java代码与其他编程语言编写的应用程序和库进行互操作
Java文件中native方法
Native层方法有两个特征:
- NDK生成的库文件需要显式加载:通过System.loadLibrary加载库,文件名为libMyJni.so的库,加载名字为MyJni
- 需要声明Native层方法的名字,且在名字前需加上native
lib库中函数实现
将上面的代码命名为MyJni.java,运行javah MyJni
命令,会在同目录下生成MyJni.h文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyJni */
#ifndef _Included_MyJni
#define _Included_MyJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: MyJni
* Method: getPart3
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_MyJni_getPart3
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
包含对函数Java_MyJni_getPart3
的说明:
- JNIEXPORT表明该函数是导出的,可以在IDA的Exports窗口看到
- JNIEnv *为当前线程的JNIEnv环境变量指针
- jclass为该函数所属java类实例的指针,这两个参数是每个JNI函数必须的
- 返回值为
jstring
编写MyJni.c实现函数:
#include "MyJni.h"
JNIEXPORT jstring JNICALL Java_MyJni_getPart3(JNIEnv *env, jclass obj)
{
return (*env)->NewStringUTF(env, "Just a test!");
}
然后新建两个文件Android.mk和Application.mk修改编译参数:
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyJni
LOCAL_SRC_FILES := MyJni.c
include $(BUILD_SHARED_LIBRARY)
Application.mk:
APP_ABI := all
然后将这些文件放在jni文件夹中,使用ndk-build
编译:
native方法加载lib库
MyJni.getPart3方法调用后,JNI需要连接到库中的相应函数,因此必须知道 Java 声明的Native方法与so库中函数的配对关系,配对的方式主要有两种:
-
使用JNI Native方法名称解析的动态链接
- 动态链接中需要根据规范命名库中的函数,以便系统能够正确的动态链接,如如getPart3对应的库函数名为
Java_com_example_mobilenormal_MyJni_getPart3
- 前缀
Java
,一个完整的类名com_example_mobilenormal_MyJni
,原方法名称getPart3
- 动态链接中需要根据规范命名库中的函数,以便系统能够正确的动态链接,如如getPart3对应的库函数名为
-
使用Registernative API调用的静态链接
-
(*env)->RegisterNatives(env, class, method, numMethods)
,调用该函数,即可动态注册Native函数Application.mk不变,Android.mk中把后缀c换成cpp
Myjni.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> #include <assert.h> #include <cstdlib> #
-