PAGalaxyLab / YAHFA

Yet Another Hook Framework for ART
GNU General Public License v3.0
1.56k stars 350 forks source link

Fix crash on Android 11 #133

Closed kotori2 closed 3 years ago

kotori2 commented 3 years ago

Fix #132 #130 (probably) 鉴于某谜语壬宁愿在issue里面讲故事也不发PR,那我自己研究下好了 Since someone figured out but won't send a PR, I'll do it.

From the crash trace, it tries to call artQuickGenericJniTrampoline and art_quick_generic_jni_trampoline, which will read data_ from ArtMethod instead of entry_point_from_quick_compiled_code_, which will get null pointer and it won't properly throw a Exception. But according to the Changelog, it might cause hook fail on Android O+, but it seems working for me with even debug build.

Credits: @yujincheng08

yujincheng08 commented 3 years ago

@lianglixin 你也是谜语人:有更好的解决方法。 所以方法呢?

ghost commented 3 years ago

@lianglixin 你也是谜语人:有更好的解决方法。 所以方法呢?

💴

yujincheng08 commented 3 years ago

@lianglixin 在人家开源项目底下说钱,真有你的呢

canyie commented 3 years ago

@yujincheng08 把ClassLinker::ShouldUseInterpreterEntrypoint 这个函数inline hook掉,对于被hook过的方法让其返回false就能解决debug不生效的问题;另,yahfa作者明确表示过不想再引入一套完整的native inline hook框架,所以我没发pr。

yujincheng08 commented 3 years ago

@canyie 这个其实edxp有个接口只是没实现。我个人不是很喜欢这种native hook的方法。

kotori2 commented 3 years ago

@yujincheng08 把ClassLinker::ShouldUseInterpreterEntrypoint 这个函数inline hook掉,对于被hook过的方法让其返回false就能解决debug不生效的问题;另,yahfa作者明确表示过不想再引入一套完整的native inline hook框架,所以我没发pr。

看起来我遇到的并不是这个问题;我试了下直接拿yahfa的示例app在debug build的系统跑是没问题的,但是edxp在hook了这个函数后,甚至没有遇到过被hook的method检查ShouldUseInterpreterEntrypoint,不过楼上用模拟器测试的时候并没有遇到这个问题。

rk700 commented 3 years ago

谢谢 @kotori2 @yujincheng08

shuajinanhai commented 3 years ago

某谜语壬测试下来,发现有个问题,不知道是谜语壬的问题,还是你的问题,、会调到java层的backup里。 public static Toast backup(Context context, CharSequence text, int duration) { try{ Log.e("yahfa", "this is cannot delete, come in is error!!!"); return null; }catch (Exception e){ return null; } }

2020-09-26 19:29:34.779 9988-9988/lab.galaxy.yahfa E/yahfa: this is cannot delete, come in is error!!!

rk700 commented 3 years ago

hook的目标target方法原本的入口是什么?backup的trampoline会最终调用target原本的入口(如果是要解析的话可能就会根据native access flag错误解析到jni?)

shuajinanhai commented 3 years ago

2020-09-28 11:28:25.546 28866-28866/lab.galaxy.yahfa.demoApp I/YAHFA-Native: replace entry point from 0x791f808fa0 to 0x7bb37b93a0 2020-09-28 11:28:25.546 28866-28866/lab.galaxy.yahfa.demoApp I/YAHFA-Native: change access flags from 0x12080009 to 0x12080009 2020-09-28 11:28:25.546 28866-28866/lab.galaxy.yahfa.demoApp I/YAHFA-Native: replace method from 0x71233098 to 0x790472a1d8 2020-09-28 11:28:25.546 28866-28866/lab.galaxy.yahfa.demoApp I/YAHFA-Native: replace entry point from 0x791f808fa0 to 0x7bb37b93c0 2020-09-28 11:28:25.546 28866-28866/lab.galaxy.yahfa.demoApp I/YAHFA-Native: change access flags from 0x12080001 to 0x12080001        这里是 access_flags &= ~kAccFastInterpreterToInterpreterInvoke; 但执行前后access_flags是一样 2020-09-28 11:28:25.546 28866-28866/lab.galaxy.yahfa.demoApp I/YAHFA-Native: hook and backup done 2020-09-28 11:28:25.641 28866-28866/lab.galaxy.yahfa.demoApp E/origin: call Log.e()        这里永远都是调用原函数,不会进hook函数

大佬还是亲测一下吧

------------------ 原始邮件 ------------------ 发件人: "Ruikai Liu"<notifications@github.com>; 发送时间: 2020年11月25日(星期三) 中午11:20 收件人: "PAGalaxyLab/YAHFA"<YAHFA@noreply.github.com>; 抄送: "1281579248"<1281579248@qq.com>; "Comment"<comment@noreply.github.com>; 主题: Re: [PAGalaxyLab/YAHFA] Fix crash on Android 11 (#133)

hook的目标target方法原本的入口是什么?backup的trampoline会最终调用target原本的入口(如果是要解析的话可能就会根据native access flag错误解析到jni?)

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

kotori2 commented 3 years ago

@rk700 没记错的话是backup解析成了JNI。的确我这边用edxposed的话会因为没有quick_code所以走解释,但是用YAHFA应用是有quick_code的,可能是跟系统是debug build有关系。

shuajinanhai commented 3 years ago

我这里debug或者release都是一样的情况。好吧,那我也说下自己的解决方案吧,我使用了Handler.sendMessageAtFrontOfQueue完美修复11.0闪退问题(完美不闪退,包括一加8),但是这样会导致hook时机会偏慢一点点,后面我开了一个线程去等待,可以解决时机问题,但是现在在一加8,上会发现部分游戏有崩溃现象,也是那个队列的问题(但是是因为这个线程引起的)。另外建议作者可以测试时候直接在hook完马上调用dowork(),不要放在button里去测试。这样即使测试正常,真正使用还是会发现有很多问题

------------------ 原始邮件 ------------------ 发件人: "双草酸酯"<notifications@github.com>; 发送时间: 2020年11月25日(星期三) 中午1:55 收件人: "PAGalaxyLab/YAHFA"<YAHFA@noreply.github.com>; 抄送: "1281579248"<1281579248@qq.com>; "Comment"<comment@noreply.github.com>; 主题: Re: [PAGalaxyLab/YAHFA] Fix crash on Android 11 (#133)

@rk700 没记错的话是backup解析成了JNI。的确我这边用edxposed的话会因为没有quick_code所以走解释,但是用YAHFA应用是有quick_code的,可能是跟系统是debug build有关系。

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

shuajinanhai commented 3 years ago

跟native这个flag没关系,而且R系统也是必须加这个flag。

rk700 commented 3 years ago

native flag记得是很早之前引入的,主要为了防止hook不生效

现在好像是backup添加native flag,解析会变成jni stub?这几个方法的原本entry都是什么?R我只有模拟器显示几个方法的entry都是interp bridge,所以没有复现出来jni的情况

shuajinanhai commented 3 years ago

R系统在AS上的模拟器是正常的,并且以前做反射在AS上的模拟器都不需要pass,,所以作者,不要在模拟器上测试,会浪费时间还得不到准确答案。

shuajinanhai commented 3 years ago

Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 14181 (.bigbull.tdsgtw), pid 14181 (.bigbull.tdsgtw),我是觉得跟队列有关系,SI_QUEUE,所以我用我的方案是成功修复,不会闪退,只是一个时机问题。开一个线程等待就可以解决,然而跟libil2cpp会有冲突,需要attach(domain)那个

rk700 commented 3 years ago

没有R真机

130 的trace里面,确实有art_quick_generic_jni_trampoline,这个是有问题,不知道是怎么根据native flag解析到jni trampoline的

kotori2 commented 3 years ago

https://cs.android.com/android/platform/superproject/+/master:art/runtime/class_linker.cc;l=3742;drc=master;bpv=1;bpt=1 没有quick_code的情况下就走到jni了

shuajinanhai commented 3 years ago

可以参考下sandhook这个
void getInterpreterBridge(bool isNative) { SandHook::ElfImg libart(art_lib_path); if (isNative) { return reinterpret_cast<void >(libart.getSymbAddress("art_quick_generic_jni_trampoline")); } else { return reinterpret_cast<void *>(libart.getSymbAddress("art_quick_to_interpreter_bridge")); } }

rk700 commented 3 years ago

是在link阶段,应该不影响后面的运行时吧。这里的检查

https://cs.android.com/android/platform/superproject/+/master:art/runtime/class_linker.cc;l=3727;drc=master

ghost commented 3 years ago

是在link阶段,应该不影响后面的运行时吧。这里的检查

https://cs.android.com/android/platform/superproject/+/master:art/runtime/class_linker.cc;l=3727;drc=master

我提交的更改已经提示比较明显了,其实并不是所属什么Native Flag问题。Debug下实际表现跟安卓10之前一样,问题实际在GC,目前不通过钩子无法较好解决这个问题。具体在ArtMethod的invoke函数里面,走到执行分支,进入汇编函数闪退。汇编函数检测异常,进入处理异常流程,根本原因是Moving GC。

ghost commented 3 years ago

是在link阶段,应该不影响后面的运行时吧。这里的检查

https://cs.android.com/android/platform/superproject/+/master:art/runtime/class_linker.cc;l=3727;drc=master

目前有个比较复杂的解决办法,在 汇编shellcode处 加入结构体成员信息恢复流程,每次调用都恢复backup的成员信息,但是这样做影响性能。另一个方案不支持某些函数,兼容性不好,实现更复杂,容易引起崩溃,其实是更改hook框架的全部成员属性。

kotori2 commented 3 years ago

是在link阶段,应该不影响后面的运行时吧。这里的检查 https://cs.android.com/android/platform/superproject/+/master:art/runtime/class_linker.cc;l=3727;drc=master

我提交的更改已经提示比较明显了,其实并不是所属什么Native Flag问题。Debug下实际表现跟安卓10之前一样,问题实际在GC,目前不通过钩子无法较好解决这个问题。具体在ArtMethod的invoke函数里面,走到执行分支,进入汇编函数闪退。汇编函数检测异常,进入处理异常流程,根本原因是Moving GC。

你提交的更改=检测到debug就直接崩掉

kotori2 commented 3 years ago

汇编函数检测异常,进入处理异常流程

你仔细看看看就会知道实际上他崩的原因是Check failed: exception != nullptr,他出错是在artQuickGenericJniTrampoline这个函数,直接called->GetEntryPointFromJni();返回了个nullptr,然后汇编认为他出错了才跳到异常处理的,实际上是Android的bug导致他返回nullptr的时候没有设置exception

kotori2 commented 3 years ago

130 的trace里面,确实有art_quick_generic_jni_trampoline,这个是有问题,不知道是怎么根据native flag解析到jni trampoline的

确实,LinkCode发生得比hook早,我之前改AOSP打了下log,那个方法被LinkCode的时候的确是没有quick_code的,不过既然这么说的话当时这里应该是走interpreter的。 结果感觉像是SetEntryPointsToInterpreter的问题

kotori2 commented 3 years ago

好了查明白了

11-25 22:54:27.846  8638  8638 D EdXposed:   # 0: 0x792f048a08  edxp::captureBacktrace(void**, unsigned long)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 1: 0x792f0462d0  art::ClassLinker::ShouldUseInterpreterEntrypointReplace(void*, void const*)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 2: 0x7936c12098  art::ClassLinker::FixupStaticTrampolines(art::ObjPtr<art::mirror::Class>)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 3: 0x792f0461f0  art::ClassLinker::FixupStaticTrampolinesReplace(void*, void*)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 4: 0x7936c41a50  
11-25 22:54:27.846  8638  8638 D EdXposed:   # 5: 0x7936c2e7cc  art::ClassLinker::InitializeClass(art::Thread*, art::Handle<art::mirror::Class>, bool, bool)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 6: 0x7936c0ada8  art::ClassLinker::EnsureInitialized(art::Thread*, art::Handle<art::mirror::Class>, bool, bool)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 7: 0x79370d5898  MterpNewInstance
11-25 22:54:27.846  8638  8638 D EdXposed:   # 8: 0x7936b7d214  
11-25 22:54:27.846  8638  8638 D EdXposed:   # 9: 0x79370cfa38  MterpInvokeDirect
11-25 22:54:27.846  8638  8638 D EdXposed:   #10: 0x7936b7f918  
11-25 22:54:27.846  8638  8638 D EdXposed:   #11: 0x79370cd3bc  MterpInvokeVirtual
11-25 22:54:27.846  8638  8638 D EdXposed:   #12: 0x7936b7f818  
11-25 22:54:27.846  8638  8638 D EdXposed:   #13: 0x7936d57c38  
11-25 22:54:27.846  8638  8638 D EdXposed:   #14: 0x79370bbe24  artQuickToInterpreterBridge
11-25 22:54:27.846  8638  8638 D EdXposed:   #15: 0x7936b8effc  
11-25 22:54:27.846  8638  8638 D EdXposed:   #16: 0x7936b857ec  
11-25 22:54:27.846  8638  8638 D EdXposed:   #17: 0x7936bfaa98  art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, ar

这里FixupStaticTrampolines说是会"Link the code of methods skipped by LinkCode.",实际上是把所有static方法都重新设置了一遍。不过不知道非static方法是怎么走的。

shuajinanhai commented 3 years ago

程序员都是这么晚睡的吗。头发都还好吗 ------------------ 原始邮件 ------------------ 发件人: "双草酸酯"<notifications@github.com> 发送时间: 2020年11月26日(星期四) 凌晨2:21 收件人: "PAGalaxyLab/YAHFA"<YAHFA@noreply.github.com>; 抄送: "shuajinanhai"<1281579248@qq.com>;"Comment"<comment@noreply.github.com>; 主题: Re: [PAGalaxyLab/YAHFA] Fix crash on Android 11 (#133)

rk700 commented 3 years ago

好了查明白了

11-25 22:54:27.846  8638  8638 D EdXposed:   # 0: 0x792f048a08  edxp::captureBacktrace(void**, unsigned long)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 1: 0x792f0462d0  art::ClassLinker::ShouldUseInterpreterEntrypointReplace(void*, void const*)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 2: 0x7936c12098  art::ClassLinker::FixupStaticTrampolines(art::ObjPtr<art::mirror::Class>)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 3: 0x792f0461f0  art::ClassLinker::FixupStaticTrampolinesReplace(void*, void*)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 4: 0x7936c41a50  
11-25 22:54:27.846  8638  8638 D EdXposed:   # 5: 0x7936c2e7cc  art::ClassLinker::InitializeClass(art::Thread*, art::Handle<art::mirror::Class>, bool, bool)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 6: 0x7936c0ada8  art::ClassLinker::EnsureInitialized(art::Thread*, art::Handle<art::mirror::Class>, bool, bool)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 7: 0x79370d5898  MterpNewInstance
11-25 22:54:27.846  8638  8638 D EdXposed:   # 8: 0x7936b7d214  
11-25 22:54:27.846  8638  8638 D EdXposed:   # 9: 0x79370cfa38  MterpInvokeDirect
11-25 22:54:27.846  8638  8638 D EdXposed:   #10: 0x7936b7f918  
11-25 22:54:27.846  8638  8638 D EdXposed:   #11: 0x79370cd3bc  MterpInvokeVirtual
11-25 22:54:27.846  8638  8638 D EdXposed:   #12: 0x7936b7f818  
11-25 22:54:27.846  8638  8638 D EdXposed:   #13: 0x7936d57c38  
11-25 22:54:27.846  8638  8638 D EdXposed:   #14: 0x79370bbe24  artQuickToInterpreterBridge
11-25 22:54:27.846  8638  8638 D EdXposed:   #15: 0x7936b8effc  
11-25 22:54:27.846  8638  8638 D EdXposed:   #16: 0x7936b857ec  
11-25 22:54:27.846  8638  8638 D EdXposed:   #17: 0x7936bfaa98  art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, ar

这里FixupStaticTrampolines说是会"Link the code of methods skipped by LinkCode.",实际上是把所有static方法都重新设置了一遍。不过不知道非static方法是怎么走的。

从trace看是在class初始化的时候调用fixup

但反射拿方法时,方法所在的类应该已经初始化过了

https://github.com/PAGalaxyLab/YAHFA/blob/master/library/src/main/java/lab/galaxy/yahfa/HookMain.java#L46

shuajinanhai commented 3 years ago

here:https://cs.android.com/android/platform/superproject/+/master:art/runtime/jit/jit_code_cache.cc;l=739?q=GetCurrentRegion&ss=android%2Fplatform%2Fsuperproject

kotori2 commented 3 years ago

好了查明白了

11-25 22:54:27.846  8638  8638 D EdXposed:   # 0: 0x792f048a08  edxp::captureBacktrace(void**, unsigned long)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 1: 0x792f0462d0  art::ClassLinker::ShouldUseInterpreterEntrypointReplace(void*, void const*)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 2: 0x7936c12098  art::ClassLinker::FixupStaticTrampolines(art::ObjPtr<art::mirror::Class>)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 3: 0x792f0461f0  art::ClassLinker::FixupStaticTrampolinesReplace(void*, void*)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 4: 0x7936c41a50  
11-25 22:54:27.846  8638  8638 D EdXposed:   # 5: 0x7936c2e7cc  art::ClassLinker::InitializeClass(art::Thread*, art::Handle<art::mirror::Class>, bool, bool)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 6: 0x7936c0ada8  art::ClassLinker::EnsureInitialized(art::Thread*, art::Handle<art::mirror::Class>, bool, bool)
11-25 22:54:27.846  8638  8638 D EdXposed:   # 7: 0x79370d5898  MterpNewInstance
11-25 22:54:27.846  8638  8638 D EdXposed:   # 8: 0x7936b7d214  
11-25 22:54:27.846  8638  8638 D EdXposed:   # 9: 0x79370cfa38  MterpInvokeDirect
11-25 22:54:27.846  8638  8638 D EdXposed:   #10: 0x7936b7f918  
11-25 22:54:27.846  8638  8638 D EdXposed:   #11: 0x79370cd3bc  MterpInvokeVirtual
11-25 22:54:27.846  8638  8638 D EdXposed:   #12: 0x7936b7f818  
11-25 22:54:27.846  8638  8638 D EdXposed:   #13: 0x7936d57c38  
11-25 22:54:27.846  8638  8638 D EdXposed:   #14: 0x79370bbe24  artQuickToInterpreterBridge
11-25 22:54:27.846  8638  8638 D EdXposed:   #15: 0x7936b8effc  
11-25 22:54:27.846  8638  8638 D EdXposed:   #16: 0x7936b857ec  
11-25 22:54:27.846  8638  8638 D EdXposed:   #17: 0x7936bfaa98  art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, ar

这里FixupStaticTrampolines说是会"Link the code of methods skipped by LinkCode.",实际上是把所有static方法都重新设置了一遍。不过不知道非static方法是怎么走的。

从trace看是在class初始化的时候调用fixup

但反射拿方法时,方法所在的类应该已经初始化过了

https://github.com/PAGalaxyLab/YAHFA/blob/master/library/src/main/java/lab/galaxy/yahfa/HookMain.java#L46

我hook过InitializeClass,很多类都会初始化若干次,不太懂原理,但是solo在EdXp这里做的workaround就是把FixupStaticTrampolines给hook了,然后如果是hook过的类的话就把native flag去掉,走完再重新hook一遍这个static函数。

shuajinanhai commented 3 years ago

https://github.com/tiann/epic/pull/45

rk700 commented 3 years ago

应该还不涉及jit,因为hook方式是通过解释器执行,不进行jit编译

rk700 commented 3 years ago

可以看下hook之前几个方法的entry指向的是什么,在trampoline下断点看下运行时是否会访问到

rk700 commented 3 years ago

如果class初始化fixup在hook之前执行,那时还没有native flag,应该可以把static方法的entry从resolve更新为interpreter bridge

rk700 commented 3 years ago

如果反射获取方法时没有对类做初始化,那么可能会有问题 https://github.com/PAGalaxyLab/YAHFA/issues/126#issuecomment-607109896

因为backup方法也是static的,所以backup方法所在的类也需要初始化或者类似上面说的在fixup之后再添加native flag进行hook

canyie commented 3 years ago

@kotori2 那个workaround翻了下commit记录,好像在2019年5月加的,时间对不上所以应该不是解决R这个问题的

rk700 commented 3 years ago

我有一个思路,不知道可不可行

native flag还是继续设置,entrypoint也和之前一样,不过对ArtMethod里面jni地址也指向一段新的的代码

如果没有触发类初始化,那么entry不变正常;如果触发了类初始化,由于native flag的原因会进入到我们的jni地址,这里还是我们可控的,在这段伪jni代码中再把方法的entry替换回来,并回到栈起始处重新调用

yujincheng08 commented 3 years ago

@rk700 感觉可行,但是实现上似乎比较难。因为JNI的栈是跳了好几层的。如果是这样,不如直接上libffi。

当然,在我给edxp最新提交的PR上提供了几种解决方案,不过都需要inline hook:https://github.com/ElderDrivers/EdXposed/pull/717

rk700 commented 3 years ago

jni trampoline在调用jni方法之前会备份寄存器和栈顶

https://cs.android.com/android/platform/superproject/+/master:art/runtime/arch/arm64/quick_entrypoints_arm64.S;drc=cc5629c1480b3be6189391b335d17911c9ddb6ad;l=1811

jni方法代码是否可以直接从x28恢复栈和寄存器?

canyie commented 3 years ago

@rk700 后面那里不太理解,不过我想到了一种方案,不知道和你说的是不是同一个 还是同样改jni地址,这段伪jni代码里把method entry改回来,完成之后直接通过jni调用自己这个java method,由于此时entry已经改回来了,就会进入原来的执行流程

rk700 commented 3 years ago

嗯,感觉都需要我们先在jni里找到ArtMethod *恢复其entry为hook trampoline。改完entry后调用,我觉得是否可以在恢复栈和寄存器的情况下,直接跳转到改后的entry?

我的想法是,我们的jni data指向另一段trampoline,在那里先通过x28恢复栈到这里 https://cs.android.com/android/platform/superproject/+/master:art/runtime/arch/arm64/quick_entrypoints_arm64.S;l=1785

然后从栈顶拿ArtMethod *x0,再pop其他寄存器,恢复栈到这里 https://cs.android.com/android/platform/superproject/+/master:art/runtime/arch/arm64/quick_entrypoints_arm64.S;l=1756 (此时的栈和寄存器应该相当于刚进入entry时的状态?)我们再改掉ArtMethod的entry,直接跳到那个entry执行hook trampoline

yujincheng08 commented 3 years ago

yahfa又没有延迟hook,完全可以利用 MakeInitializedClassesVisiblyInitialized 的,这个不需要inline hook,直接 dlopen 拿到sym就行。但是edxp由于有延时hook,所以会死锁。

yujincheng08 commented 3 years ago

如果想动jni那边,我建议直接上libffi,在closure里面再次替换entrypoint然后调用自己,如此便不需要写汇编搞寄存器。 由于entrypoint被替换了,我建议用 unordered_map 来存起来。如此效率上和实现上都有不错的平衡。

rk700 commented 3 years ago

谢谢建议哈

我的想法,一个是尽量减少代码的副作用让使用者遇到未曾设想的情况,我可能更愿意的方式是检测类是否初始化,如果没有则报错让用户自己初始化。二是我个人想尽量保持项目的简单,不到万不得已不太愿意再引入一个复杂的依赖

yujincheng08 commented 3 years ago

R上面的类初始化已经不能由用户完成了。所以最符合你想法的方案应该就是 MakeInitializedClassesVisiblyInitialized

yujincheng08 commented 3 years ago

鉴于你没有实机测试,如果方案可以,我这边可以提PR (符号提取和offset是用回我在edxp使用的方案)。

rk700 commented 3 years ago

谢谢,我再看看jni的方式是否能到达效果,如果不行那还是需要主动调用初始化了

shuajinanhai commented 3 years ago

我的想法,一个是尽量减少代码的副作用让使用者遇到未曾设想的情况,我可能更愿意的方式是检测类是否初始化,如果没有则报错让用户自己初始化。二是我个人想尽量保持项目的简单,不到万不得已不太愿意再引入一个复杂的依赖 我非常赞同你这点, 尽可能少代码量,保持简单又功能强大 尽量不使用hook 理解起来也会比较容易上手 其他框架写得太臃肿------------------ 原始邮件 ------------------ 发件人: "Ruikai&nbsp;Liu"<notifications@github.com> 发送时间: 2020年12月12日(星期六) 下午5:57 收件人: "PAGalaxyLab/YAHFA"<YAHFA@noreply.github.com>; 抄送: "shuajinanhai"<1281579248@qq.com>;"Comment"<comment@noreply.github.com>; 主题: Re: [PAGalaxyLab/YAHFA] Fix crash on Android 11 (#133)

kotori2 commented 3 years ago

直接跳转到改后的entry?

指的是让他从jni的入口直接跳到quick_code的入口?听起来感觉这种实现有点脏。 另外是不是可以换一种思路,把hook和backup的static去掉?

rk700 commented 3 years ago

去掉static,可能会改变参数布局,可能需要再重新调整

感觉除了backup是static,hook的目标是static也可能会造成类似的fixupstatictrampoline的调用问题,这种情况的话直接jni中汇编恢复栈可能会有问题