duangsuse::Echo
#android #dev 面试题。上条则是简化版的答案 🧐 仅供参考,可能我解释的太抽象了,涉及一些淘汰的远古技术, 不符合标准答案。 - Handler 基础,Looper 怎么和 Thread 绑定,怎样提高 MessageQueue 优先级 - 进程间通讯的方法,对 AIDL 的了解,对 ContentProvider 的了解 - (根据项目) 自定义 View 的方法和注意事项、事件分发、View 复用 - 写过 demo 吗,什么时候会写 demo - 对 MVVM 的了解,对 Jetpack…
#android #hack #aop 继续,加上奇怪.. 的知识
Magisk 是 Android 版的 Docker (overlayfs),能管理root、去广告加皮肤、安装字体、模拟位置、利用权限骗过 SafetyNet DRM
它让 /boot/initrd 挂载(--bind) /sbin/.magisk tmpfs 来遮住 /mirror/system vendor 树,因此需要TWRP刷zip(和root时一样) 或fastboot刷入kitchen过的原机boot.img
新设备可能不区分boot分区(A/B 切换来OTA),修改内核强制使用 initrd(boot.img) 里的 init(PID0) 程序
简单说,#Linux 启动的传统是kernel解压启动 initrd 内存盘(recovery,Magisk)去寻找真'/',然后 chroot /sysroot /init (systemd,各类run-command,.)
Zygisk 和 Xposed 都是AOP框架,分别拦截和修改 Java android.*/JNI 函数的调用,从而实现对系统和应用程序的功能修改。Zygisk 是基于 Riru 的一个模块,使用 Zygote 注入技术来加载自定义代码。Xposed 是通过替换 /system/bin/app_process 程序来控制 Zygote 进程,使其在系统启动时加载 XposedBridge.jar 文件,从而完成对 Zygote 进程和 Dalvik 虚拟机的劫持。
Zygisk 是 Riru(#cpp .so 函数替换,靠魔改某项linker_PRELOAD) 的免安装续作,开启后不能规避检测,但支持文件/JNI重定向、实现了模块黑名单。 LSP和Ed-Xposed分别支持二者(不能共存)
LSP 用 env->RegisterNatives(动态注册版Java_), jni_method_map
PRELOAD=libxposed.so 利用
RegisterNatives 本身就能让JNI函数基于jobject clazz 派发,所以比ART hook 简单
FakeXposed 作者的博文
#kt #code
Magisk 是 Android 版的 Docker (overlayfs),能管理root、去广告加皮肤、安装字体、模拟位置、利用权限骗过 SafetyNet DRM
它让 /boot/initrd 挂载(--bind) /sbin/.magisk tmpfs 来遮住 /mirror/system vendor 树,因此需要TWRP刷zip(和root时一样) 或fastboot刷入kitchen过的原机boot.img
新设备可能不区分boot分区(A/B 切换来OTA),修改内核强制使用 initrd(boot.img) 里的 init(PID0) 程序
简单说,#Linux 启动的传统是kernel解压启动 initrd 内存盘(recovery,Magisk)去寻找真'/',然后 chroot /sysroot /init (systemd,各类run-command,.)
Zygisk 和 Xposed 都是AOP框架,分别拦截和修改 Java android.*/JNI 函数的调用,从而实现对系统和应用程序的功能修改。Zygisk 是基于 Riru 的一个模块,使用 Zygote 注入技术来加载自定义代码。Xposed 是通过替换 /system/bin/app_process 程序来控制 Zygote 进程,使其在系统启动时加载 XposedBridge.jar 文件,从而完成对 Zygote 进程和 Dalvik 虚拟机的劫持。
Zygisk 是 Riru(#cpp .so 函数替换,靠魔改某项linker_PRELOAD) 的免安装续作,开启后不能规避检测,但支持文件/JNI重定向、实现了模块黑名单。 LSP和Ed-Xposed分别支持二者(不能共存)
.internal.os.Zygote
是 app_process 的起点,它负责注册JNI、创建 SystemServer(PM,WM,AMS处理的Intent),之后便执行Xp模块LSP 用 env->RegisterNatives(动态注册版Java_), jni_method_map
[T][id][sig].fnPtr
来JNI替换,Zygisk 提供了 {pre(包名),post}AppSpecialize(args
)PRELOAD=libxposed.so 利用
env->FromReflectedMethod(由java查找).{access_flags|=ACC_NATIVE, (Dalvik|ART inlined jmp)nativeFunc=callHooked}
做函数替换RegisterNatives 本身就能让JNI函数基于jobject clazz 派发,所以比ART hook 简单
FakeXposed 作者的博文
#kt #code
import de.robv.android.xposed.*
import de.robv.android.xposed.XposedHelpers.*
val reg={
val NoPrint={
setStaticObjectField("java.lang.System", "out", PrintStream(OutputStream()) )
}
findAndHookMethod("java.lang.System", cl, "<clinit>", object: XC_MethodHook() {
override fun MethodHookParam.afterHookedMethod() {NoPrint()}
})
}
//assets/xposed_init 写下类名
class My: IXposedHookLoadPackage {
fun LoadPackageParam.handleLoadPackage() {
if(packageName.equals("com.example.app"))reg()
cl=classLoader
}
}
Gist
Zygisk 源码分析 #Magisk #Zygisk
Zygisk 源码分析 #Magisk #Zygisk. GitHub Gist: instantly share code, notes, and snippets.
duangsuse::Echo
感觉虽然有些收获,也都是没啥意思的问题…… 面试呢,或许对我这种数学渣就都做不到的吧? #statement 我讨厌这种AI都能写的问题,这些”深刻思考“有什么价值呢? 总是一些算法,让编程变成一种不快乐的任务、变成帮出题人自问自答的”寻宝“ 这些出题人又有多聪明呢? 大众都在润色70年前,世上还没电脑时就有的问题, 而小众又能成什么气候,又如何让他们的沧海遗珠给时兴编程带来价值呢? 如果用《算法图解》那种小说口吻去讲,做一些有弹性的科普视频,倒是有娱乐价值;如果写代码只是为了复制粘贴「能用的东西…
举例, #ts 上有”交并集类型“ (有人认为 hs, Rust 没有子类型所以不存在集合论的,确实如此但 in-out 形变是Racket子语言里也有的,我找不到原文但TRack 是有)
(我一点也不羡慕没有重载和this模块等多态技术的圆括号 😅, 模型的缺失是拿宏手动兼容 a.b.c 所弥补不了的, 就像 F# 的 |> 比不上 xx.let{}, kt 的元组 destruct 比不上 ES6 let[x,y]=P, ES6的解构又不如 Prolog 的 unify [x,1]=[2,y]...
观摩王垠《别再欺负我们读书少》:
- id(itself) “同时”是int->int和bool->bool,而不是表示它“有时”是int->int,而另外的时候是bool->bool。
- 所以,id(1)一定是int。如果你输入id(True),它推导出的一定是bool。
- 否则,调用id(1)会报错,因为id的类型有可能是bool->bool,不能接受int的输入。调用id(True)也会报错,左右不是人。
但我习惯拿 成员交=union ,成员并=insect ,绝口不提“同时”“有时” 这种抽象说法乃至术语
- id “必须”是int->int, bool->bool ,而不是“可为” int->int | bool->bool。 when(x) { is Int, is Str } 这种情况才是“x可为二者”
- 否则,调用id(1),id(True)都会报错,因为id的类型有可能是bool->bool,不能接受int的输入,或者反之。
严谨性绝对是次于创造力的,况且,含糊的说法对同时使用和实现不利。
虽然这些都是小小的细节,但每个细节都注重可读性,随着设计的步进,最终会形成巨大的差异。即便都是用AI,我的实现也会有很多不同
(我一点也不羡慕没有重载和this模块等多态技术的圆括号 😅, 模型的缺失是拿宏手动兼容 a.b.c 所弥补不了的, 就像 F# 的 |> 比不上 xx.let{}, kt 的元组 destruct 比不上 ES6 let[x,y]=P, ES6的解构又不如 Prolog 的 unify [x,1]=[2,y]...
观摩王垠《别再欺负我们读书少》:
- int -> int | bool ->bool
表示的确实是一个intersection type(^),而不是union type(|)- id(itself) “同时”是int->int和bool->bool,而不是表示它“有时”是int->int,而另外的时候是bool->bool。
- 所以,id(1)一定是int。如果你输入id(True),它推导出的一定是bool。
- 否则,调用id(1)会报错,因为id的类型有可能是bool->bool,不能接受int的输入。调用id(True)也会报错,左右不是人。
但我习惯拿 成员交=union ,成员并=insect ,绝口不提“同时”“有时” 这种抽象说法乃至术语
- int -> int | bool ->bool
表示的确实是一个重载,而不是Either- id “必须”是int->int, bool->bool ,而不是“可为” int->int | bool->bool。 when(x) { is Int, is Str } 这种情况才是“x可为二者”
- 否则,调用id(1),id(True)都会报错,因为id的类型有可能是bool->bool,不能接受int的输入,或者反之。
严谨性绝对是次于创造力的,况且,含糊的说法对同时使用和实现不利。
虽然这些都是小小的细节,但每个细节都注重可读性,随着设计的步进,最终会形成巨大的差异。即便都是用AI,我的实现也会有很多不同
Telegram
duangsuse::Echo
#learn #ts #kt 子类型 vs 组合, in/out参数
https://tttttt.me/dsuses/5194
总之,trait类型的交集 还是需要in/out,这不是子类型带来的麻烦。
a=append(a,x) 与 copy(a,src) 类型上是一样的,前者也并不能“把a修正为更窄接口”。 Go必须把list+=单项 写出来, 因为缺少型变
func main() {
var src []interface{} = []any{1, 2, 3, 4, 5}
var dst []int…
https://tttttt.me/dsuses/5194
总之,trait类型的交集 还是需要in/out,这不是子类型带来的麻烦。
a=append(a,x) 与 copy(a,src) 类型上是一样的,前者也并不能“把a修正为更窄接口”。 Go必须把list+=单项 写出来, 因为缺少型变
func main() {
var src []interface{} = []any{1, 2, 3, 4, 5}
var dst []int…