Magisk基础
Magisk基础项目源代码地址
Magisk是什么?有什么用?
Magisk是一个开源的用于获取Root权限的框架
Magisk可以用于获取手机Root权限
Magisk如何使用
具体的使用可见手册
官方手册
简单来说:
环境需要:
已经解除BootLoader锁。
已经安装adb、fastboot工具(以及驱动)
系统boot镜像
使用步骤:
根据是否有ramdisk分区确认初始镜像,如果有获取系统的boot/init_boot镜像,如果没有获取recovery镜像
使用Magisk App对初始进行进行patch操作
使用fastboot刷入boot/init_boot/recovery镜像
Magisk项目源代码环境配置
具体内容可见
官方手册
1.设置环境
先下载Magisk项目
1git clone --recurse-submodules https://github.com/topjohnwu/Magisk.git
然后下载Magisk定制的ndk
1./build.py ndk
2.编译项目
12345678910 ...
Compose源码环境搭建
Compose源码环境搭建
进行Compose源代码环境构建。
Compose Compiler:1.5.1
前言
为什么需要使用Linux作为搭建环境?(指跑源代码)
这肯定不是我想用Linux开发,因为Compose项目的限制
a. 我们可以看一部分project的manifest声明,发现什么?项目依赖了ios的sdk,linux的sdk,就是没有Windows。这想表明什么就不言而喻了
b. 通过查看Compose项目的一部分的文件你也能发现一些端倪,没有gradlew.bat?所以使用Windows跑环境会有一些问题的。
(不清楚是否能跑。但是绝对是要做一些配置的。)
为什么选择配置Compose Compiler的Release环境?
很简单,如果你拉取最新的commit项目未必能跑起来,是否稳定你只能求助开发者。
这是因为开发分值是feature最多的分值,而且你不清楚他是否是开发完成的,这种项目的不稳定因素肯定就尽可能控制下。
(问就是踩过坑。)
Release的版本号为什么选择1.5.1
我们可以查看下目前的Compose Compiler Rel ...
Gradle构建流程
Gradle构建流程
前面我们分析了Gradle的Daemon启动。后续我们需要对Gradle的构建流程进行分析(粗略分析)
缘起
前面分析到,Gradle的Daemon启动源于Client Connector连接。
由于Client连接了Server,Server在没有启动的时候才会进行Fork启动。
启动后的Server并不会构建,因为Server也不知道Client要干嘛,因为Server还没有Client的构建信息。
所以接下来会介绍Gradle构建的触发。
(其实上部分Daemon启动的解析中有提到——也就是Connect accept过程会触发构建流程)
1234567891011121314151617181920212223242526272829303132public class DaemonTcpServerConnector implements DaemonServerConnector { // ...... @Override public Address start(final IncomingConnection ...
Gradle Daemon启动分析
Gradle Server Start
Server的启动主要是进行初始化和环境的准备
主要可以分为如下几个过程
Bootstrap:启动进程,设置ClassLoader
Init:初始化成员,初始化Socket
Wait:进程keep-alive,防止main线程死亡,休眠等待。
Bootstrap
前面分析到了Gradle会通过ProcessBuilder开启一个Deamon进程
并调用shell
12java -cp *gradle-launcher-7.6.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon
BootStrap
和Client启动类似
12345public class GradleDaemon { public static void main(String[] args) { ProcessBootstrap.run("org.gradle.launcher.daemon.bootstrap.DaemonMain", args) ...
ShadowHook原理分析
ShadowHook原理分析
初始化
无论是使用Native初始化还是Java进行初始化。最后其实都会调用到shadowhook_init方法
init的实际初始化逻辑包含如下几个过程
errno init
信号量处理初始化(sigsegv、sigbus)
enter、exit初始化
mode相关初始化
a) shared: safe_init + hub_init
b) unique: linker_init
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152int shadowhook_init(shadowhook_mode_t mode, bool debuggable) { bool do_init = false; // check是否没有初始化 if (__predict_true(SHADOWHOOK_ERRNO_UNINIT == shadowhook_init_errno)) { s ...
Shadowhook基础使用
ShadowHook
什么是ShadowHook
请看官网
ShadowHook 是一个 Android inline hook 库,它支持 thumb、arm32 和 arm64。
基础概念inline-hook
Inline-hook 通过直接修改目标函数的机器指令来实现。通常情况下,会将目标函数的开头几条指令替换为跳转指令,指向一段插入的代码。这段插入的代码可以执行额外的操作,例如记录函数参数、修改函数返回值,或者完全改变函数的执行逻辑。
——from Gemini(快说:谢谢Gemini)
Android 的Native Hook技术有两类,PLT Hook & Inline Hook
PLT Hook用于有外部的依赖库调用的Hook。
Inline Hook用于Hook内部库的调用
如下是是PLT Hook和Inline Hook的使用场景以及区别
Plt Hook
Inline Hook
shadow hook
Shadow hook是一个Inline Hook框架。
Shadow Hook基础使用Quick Start
Note: 具体可见 ...
bhook基础原理分析
BHook原理解析基础概念PLT/GOT hook
BHook是一个plt/got hook框架。
plt/got hook是指,利用动态链接过程的特点。
即——使用PLT表作为跳板查got表来查询被调用函数的地址在哪。
如果我们修改GOT表内的地址就可以实现劫持函数的执行过程。
示例
test.c
1234567#include <stdio.h>void sayHell() { printf("Hello World");}int main() { sayHello();}
PLT/GOT hook前
hook 后
Relocation
即重定位,讲符号引用转化为直接引用。
说直白点就是:
编译器在编译一个库函数调用的时候,编译器本身是不知道你调用的地址在哪,所以会直接用0填充
于此同时他会在.rela中生成一条记录(我们暂且称之为“坑位“),告知来着,哪个函数调用需要填充地址。
Relocation即填坑的过程。
静态链接
对于 ...
使用C/C++解析ELF文件
ELF文件解析
关于ELF文件我们可以看下面这张大图(总结地很到位)
Note:
由于目前x86 64位架构为主流,后续分析主要是基于Elf64进行分析、介绍
Demo 源代码地址
结构体介绍
文件包含(usr/include/elf.h)
1#include <elf.h>
准备工作
12345#include <stdio.h>int main() { printf("Hello World!");}
1gcc test.c -o test
Elf64_Ehdr
结构体
12345678910111213141516171819#define EI_NIDENT (16)typedef struct{ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ Elf64_Half e_type; /* Object file type */ Elf64_H ...
risc-v指令架构基础
RISC-V指令基础RV32RV32I
RV32M
RV32F & RV32D
RV32A
RV32C
RV32V
RV64RV64I
RV64M & RV64A
RV64F & RV64D
RV64C
RiscV中断
分类在Riscv中中断的类型分为3种
software interrupt——软件中断
timer interrupt——时钟中断
external interrupt——外部中断
mstatus(Machine Status),维护各种状态,如全局中断使能状态。
mip(Machine Interrupt Pending),记录当前的中断请求。
mie(Machine Interrupt Enable),维护处理器的中断使能状态。
mcause(Machine Exception Cause),指示发生了何种异常。
mtvec(Machine Trap Vector),存放发生异常时处理器跳转的地址。
mtval(Machine Trap Value),存 ...
C语言内联汇编
ASM
此处的ASM指的是C语言中的asm关键字
asm关键字可以用于内联汇编代码,即在C文件中声明一部分汇编代码,最后在编译器的作用下,实现一部分C语言无法实现的功能。
概念C语言的编译过程
我们知道C语言
1.会汇编为assembly(汇编语言)
2.汇编语言会在汇编器(as)的作用下变为object文件。
3.最后通过会linker链接为elf/exe文件。
为什么需要asm
前面其实有说过asm是C语言中的一个关键字
这个关键字的功能就是使用assembly去实现一部分功能。
这里有一个问题☝️
C语言会有无法实现的功能需要assembly去实现?
有吗?没有吗?
肯定是有的
其实有很多。
我们C语言所有的能力都是基于汇编的。
如果没有汇编,那么就C语言什么都做不了。
所有的C语言特性都是基于assembly去实现的。
那么问题来了?C语言的语言特性能完成所有事情吗?
并不能,不然系统调用,系统注册,操控寄存器,控制屏幕。
这部分内容assembly能实现吗?
太能了,assembly虽然怪难写的,但是人家是正经的,所有的功 ...