下载源码 新建源码目录
mkdir ~/android13 && cd ~/android13 南方用户 先去中科大 按照aosp镜像使用帮助 下载底包
wget -c https://mirrors.ustc.edu.cn/aosp-monthly/aosp-latest.tar 验证一下底包md5看看是否完整 比如当前下载的 a1366894d0ddfbf32db9a719929bdcd7 aosp-20231101.tar
md5sum aosp-latest.tar 解压源码
tar xvf aosp-latest.tar 配置git
sudo apt-get install git git config --global user.email xxx@qq.com git config --global user.name 'abc' 下载 repo 工具。
mkdir ~/bin PATH=~/bin:$PATH curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo ## 如果上述 URL 不可访问,可以用下面的: ## curl -sSL 'https://gerrit-googlesource.proxy.ustclug.org/git-repo/+/master/repo?format=TEXT' |base64 -d > ~/bin/repo chmod a+x ~/bin/repo ## 替换repo里的源为中科大的源,这样不用代理,下载源码 export REPO_URL = 'https://gerrit-googlesource.
一.Android属性原理: 属性系统基础: 属性由键值对组成,属性的值有类型,比如string,int,bool等,属性还关联着selinux上下文,因为属性是一种重要的资源,所以由selinux保护,由selinux的策略决定了哪些域可以读取/写哪些属性。
Android属性本质上是进程间通信的一种方式,由init进程创建/dev/__properties__目录,并在此目录下创建和属性相关的文件,然后init进程会调用带着MAP_SHARED标志的mmap()将这些文件映射到vm_area_struct,对属性的初始化和修改会反映到这些文件中去.其他需要读取和修改属性的进程也会调用带着MAP_SHARED标志的mmap()将这些文件映射到自己的vm_area_struct,因此本质上就是共享内存的方式。
在设计上基于安全的考虑,只有init进程可以初始化属性系统,即在/dev/__properties__目录下创建文件,也只有init进程可以修改属性,其他进程想修改属性需要通过/dev/socket/property_service这个socket文件向init进程发起通信请求,而且并不是所有进程都有权限访问这个socket文件,普通的app进程所在的untrusted_app域就是无法访问的,因此普通的app进程无法修改属性。
属性大致分为: ro开头的只读属性,persist开头的持久化属性,ctl开头的控制属性,selinux.restorecon_recursive属性与普通属性。这么区分是因为init进程中对这些属性有不同的处理逻辑,后面会详细描述不同类型属性的差异。
基于效率的考虑,Android属性在属性文件格式的组织上经过了精心的设计,对于频繁的获取某一属性这种场景Android还提供了属性缓存的机制,这个机制也是改机的一个障碍。
进程间通信必然需要某种同步机制,Android中的属性通过包装futex系统调用实现了属性的同步功能。
系统提供了getprop工具可以获取所有属性值,调用的时候加上-Z参数可以获取属性对应的selinux上下文,加上-T参数可以获取属性值对应的类型。
属性核心API: Android属性的实现核心代码放在了bionic libc中,有两个重要的头文件:<sys/system_properties.h>和<sys/_system_properties.h>描述了属性的api,这两个文件都处于路径bionic/libc/include/sys/下,这两个头文件不论是系统代码还是基于ndk开发的代码都是可以包含的,只不过包含<sys/_system_properties.h>文件的时候需要定义"#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_”,不然编译会报错,这是因为<sys/_system_properties.h>文件开头明确了:
#ifndef _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ #error you should #include <sys/system_properties.h> instead #endif 从这里也可以看出系统的开发者不想让你直接包含<sys/_system_properties.h>文件使用里边的接口,而最好使用<sys/system_properties.h>文件中的接口。
<sys/system_properties.h>:
这个文件包含的接口主要是设置属性,遍历属性以及读取属性的值,涵盖了正常使用属性系统的需求,其中有些接口需要prop_info结构体,这个结构体表示了属性值所在的区域.只不过调用接口的人无需关心prop_info结构体里边的细节,只需要调用一个接口获取prop_info指针,再将该指针传递给另外的接口获取更多信息。
以下是接口描述:
int` `__system_property_set(const char``*` `__name, const char``*` `__value); 设置name属性的值为value,它的内部实现是通过/dev/socket/property_service这个socket文件向init进程发起通信请求,因此必须是selinux策略明确同意的进程才有权限发起通信,selinux策略同意设置属性的宏为set_prop,定义在te_macros文件中,这个宏其中之一的作用是允许指定的域connectto init进程域的unix_stream_socket文件.在system_app.te文件中指定了system_app可以设置的一些属性:
set_prop(system_app, bluetooth_audio_hal_prop)
set_prop(system_app, bluetooth_prop)
set_prop(system_app, debug_prop)
set_prop(system_app, system_prop)
表明system_app域中的进程既可以读取u:object_r:bluetooth_audio_hal_prop:s0上下文的属性值,也可以写这些上下文的属性值。
普通的app进程无法调用此函数,会报: type=1400 audit(0.0:901): avc: denied { write } for name="property_service" dev="tmpfs" ino=25226 scontext=u:r:untrusted_app:s0:c107,c256,c512,c768 tcontext=u:object_r:property_socket:s0 tclass=sock_file permissive=0 app=xxx.xxx.xxx
const prop_info* __system_property_find(const char* __name); void __system_property_read_callback(const prop_info* __pi,void (*__callback)(void* __cookie, const char* __name, const char* __value, uint32_t __serial), void* __cookie) 这两个函数是一对,先调用__system_property_find()函数获取对应属性值的区域结构体指针prop_info*,然后调用__system_property_read_callback()以回调的方式接受属性值,属性值输出参数为value,其中cookie参数由调用方任意设置,最终调用callback的时候会将cookie再传递给回调函数。getprop程序获取单个属性值就是通过调用这两个函数实现的。
ADB命令大全 //关闭adb adb kill-server //开启adb adb start-server //查看当前连接设备 adb devices //如果发现多个设备 例:adb -s devicel install xxx.apk adb -s 设备号 其他指令 //往手机SDCard传递文件 adb push 文件名 手机端SDCard路径 //从手机端下载文件 adb pull /sdcard/xxx.txt 操作APP //查看手机端安装的所有app包名 adb shell pm list packages //查看顶部Activity adb shell dumpsys activity | findstr "mFocusedActivity" //安装apk文件 //使用覆盖安装:adb install -r xxx.apk adb install xxx.apk //卸载App: //保留数据: adb uninstall -k com.zhy.app adb uninstall com.zhy.app //启动Activity 例:adb shell am start com.zhy.aaa/com.zhy.aaa.MainActivity adb shell am start 包名/完整Activity路径 //启动一个隐式的Intent: adb shell am start -a "android.
[TOC]
利用Exception()触发函数执行流程 新建一个项目在MainActivity的onCreate方法中执行log触发流程 log如下
android.util.Log.e("xiaozhu", "onCreate: ", new Exception());
[TOC]
介绍 此文章翻译出处8ksed.io
Android设备上的Root检测相关的技术以及绕过它的方法。主要重点将放在应用开发者采用的策略上,以保护他们的应用程序并防止其在受损设备上运行。为了学习目的,我们将使用一个名为Root Detector的示例Root检测应用程序 下载地址
示例应用程序已安装在我们的Root设备上,正如我们所看到的,它表明设备已经Root。
通过使用jadx-gui来反编译apk文件,以了解Root Detector应用程序在设备上安装后的操作。AndroidManifest.xml是所有Android应用程序的入口点,其中定义了应用程序的不同组件和服务。
jadx-gui 查看XML Permissions 权限 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <permission android:name="com.8ksec.inappprotections.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" android:protectionLevel="signature"/> <uses-permission android:name="com.8ksec.inappprotections.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"/> 从权限的角度来看,似乎没有什么有趣的东西。主要使用存储权限。
除了这些定义的权限之外,看看这个应用程序中还有哪些其他组件。
<activity android:exported="true" android:name="com.8ksec.inappprotections.MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> 可以看到它只有一个活动,即MainActivity,它会被启动。
看看在这个MainActivity.java文件中有什么。
可以看到jadx无法反编译大部分代码。这是因为代码混淆。但让我们尽量从我们已经反编译的代码中找出一些信息吧!
似乎MainActivity有一个静态块,在其中调用 System.loadLibrary("inappprotections") ,负责将本地库加载到内存中。
static { String str = "ۧ۠ۧۤ۬۠ۗۛۙۡۦۚۙۡۧۢۛۡۘ۟ۛۥۢ۬۠۬ۨ۬۟ۤۙۙۢۘ۠ۡۛۤۨۨۨۙۜ۟۬ۜۜۙۦۘۤ۠ۨۨ۟ۡ"; while (true) { switch ((((str.hashCode() ^ 436) ^ 234) ^ 912) ^ (-1907612566)) { case -1083933248: return; case 1567145872: System.