package Ġcom . chen cc . android stud yn otes code . hook . activity hook . hook čĊč Ċ import Ġandroid . app . Activity č Ċ import Ġandroid . app . Instrumentation č Ċ import Ġandroid . content . Component Name č Ċ import Ġandroid . content . Context č Ċ import Ġandroid . content . Intent č Ċ import Ġandroid . os .* č Ċ import Ġandroid . util . Log č Ċ import Ġcom . chen cc . android stud yn otes code . hook . activity hook . Stub Activity č Ċ import Ġjava . lang . reflect . Invocation Handler č Ċ import Ġjava . lang . reflect . Proxy čĊčĊč Ċ /** čĊ Ġ* Ġ@ author ĠCreated Ġby ĠC HEN Ġon Ġ 2 0 2 0 / 1 2 / 3 0 čĊ Ġ* Ġ@ email Ġ 1 8 8 6 6 9 @ 1 6 3 . com čĊ Ġ*/ č Ċ private Ġconst Ġval ĠTAG Ġ= Ġ" Hook Helper " č Ċ private Ġconst Ġval ĠEX TRA _ TARGET _ INT ENT Ġ= Ġ" extra _ target _ intent " čĊč Ċ fun Ġhook AM SA idl (){ čĊĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ> ĠBuild . VERSION _ CODES . P ){ čĊĠĠĠĠĠĠĠ Ġhook I Activity Task Manager () čĊĠĠĠ Ġ} else { čĊĠĠĠĠĠĠĠ Ġhook I Activity Manager () čĊĠĠĠ Ġ} čĊč Ċ } čĊčĊč Ċ private Ġfun Ġhook I Activity Task Manager (){ čĊčĊĠĠĠ Ġtry Ġ{ čĊĠĠĠĠĠĠĠ Ġval Ġactivity Manager Ġ= ĠClass . forName (" android . app . Activity Task Manager ") čĊĠĠĠĠĠĠĠ Ġval Ġsingleton Field Ġ= Ġactivity Manager . getDeclared Field (" I Activity Task Manager Singleton "). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġval Ġsingleton Ġ= Ġsingleton Field . get ( null ) čĊĠĠĠĠĠĠĠ Ġ// Ġæĭ ¿ åĪ° ĠI Activity Task Manager Ġå¯¹è±¡ čĊĠĠĠĠĠĠĠ Ġval Ġsingleton Class Ġ= ĠClass . forName (" android . util . Singleton ") čĊĠĠĠĠĠĠĠ Ġval Ġm Instance Field Ġ= Ġsingleton Class . getDeclared Field (" m Instance "). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ// Ġ åİŁå§ĭ çļĦ I Activity Task Manager čĊĠĠĠĠĠĠĠ Ġval ĠI Activity Task Manager Ġ= Ġm Instance Field . get ( singleton ) čĊčĊĠĠĠĠĠĠĠ Ġval Ġproxy Ġ= ĠProxy . new Proxy Instance ( Thread . currentThread (). context ClassLoader , čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠarrayOf ( Class . forName (" android . app . I Activity Task Manager ")), čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠInvocation Handler Ġ{ Ġproxy , Ġmethod , Ġargs Ġ-> čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" hook I Activity Task Manager : Ġ Ġ${ method . name }") čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġraw Ġ: ĠIntent ? Ġ= Ġnull čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġindex Ġ= Ġ- 1 čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(" startActivity " Ġ== Ġmethod . name ){ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" invoke Ġ: ĠstartActivity Ġ åĲ¯åĬ¨ åĩĨå¤ĩ ") čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġargs . forEach Indexed Ġ{ Ġi , Ġany Ġ-> čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( any Ġis ĠIntent ){ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġraw Ġ= Ġany čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġindex Ġ= Ġi čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" invoke Ġ: Ġ Ġraw Ġ Ġ$ raw ") čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Intent Ġ= ĠIntent (). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponent Ġ= ĠComponent Name (" com . chen cc . android stud yn otes code ", ĠStub Activity :: class . java . name ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput Extra ( EXTRA _ TARGET _ INT ENT , Ġraw ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġargs [ index ] Ġ= Ġnew Intent ; čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmethod . invoke ( I Activity Task Manager , Ġ* args ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) čĊčĊĠĠĠĠĠĠĠ Ġm Instance Field . set ( singleton , Ġproxy ) čĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ čĊĠĠĠĠĠĠĠ Ġe . printStackTrace () čĊĠĠĠ Ġ} č Ċ } čĊč Ċ private Ġfun Ġhook I Activity Manager (){ čĊĠĠĠ Ġtry Ġ{ čĊĠĠĠĠĠĠĠ Ġval Ġsingleton Field Ġ= Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . O ){ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġactivity Manager Ġ= ĠClass . forName (" android . app . Activity Manager ") čĊĠĠĠĠĠĠĠĠĠĠĠ Ġactivity Manager . getDeclared Field (" I Activity Manager Singleton ") čĊĠĠĠĠĠĠĠ Ġ} else Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġactivity Manager Ġ= ĠClass . forName (" android . app . Activity Manager Native ") čĊĠĠĠĠĠĠĠĠĠĠĠ Ġactivity Manager . getDeclared Field (" g Default ") čĊĠĠĠĠĠĠĠ Ġ}. apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġval Ġsingleton Ġ= Ġsingleton Field . get ( null ) čĊĠĠĠĠĠĠĠ Ġ// æĭ¿ I Activity Manager å¯¹è±¡ čĊĠĠĠĠĠĠĠ Ġval Ġsingleton Class Ġ= ĠClass . forName (" android . util . Singleton ") čĊĠĠĠĠĠĠĠ Ġval Ġm Instance Field Ġ= Ġsingleton Class . getDeclared Field (" m Instance "). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ// åİŁå§ĭ çļĦ I Activity Manager čĊĠĠĠĠĠĠĠ Ġval Ġraw I Activity Manager Ġ= Ġm Instance Field . get ( singleton ) čĊĠĠĠĠĠĠĠ Ġ// åĪĽå»ºä¸Ģä¸ª I Activity Manager ä»£çĲĨ å¯¹è±¡ čĊĠĠĠĠĠĠĠ Ġval Ġproxy Ġ= ĠProxy . new Proxy Instance ( Thread . currentThread (). context ClassLoader , čĊĠĠĠĠĠĠĠĠĠĠĠ ĠarrayOf ( Class . forName (" android . app . I Activity Manager ")), čĊĠĠĠĠĠĠĠĠĠĠĠ ĠInvocation Handler Ġ{ Ġproxy , Ġmethod , Ġargs Ġ-> čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" hook I Activity Manager : Ġ Ġmethod Ġ: Ġ${ method . name }") čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġåľ¨ è¿ĻéĩĮ æį¢ æİī çľŁ æŃ£ è¦ģ åĲ¯åĬ¨ çļĦ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġraw Ġ: ĠIntent ? Ġ= Ġnull čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġindex Ġ= Ġ- 1 čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(" startActivity " Ġ== Ġmethod . name ){ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" invoke Ġ: ĠstartActivity Ġ åĲ¯åĬ¨ åĩĨå¤ĩ ") čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġargs . forEach Indexed Ġ{ Ġi , Ġany Ġ-> čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( any Ġis ĠIntent ){ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġraw Ġ= Ġany čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġindex Ġ= Ġi čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" invoke : Ġ Ġraw Ġ: Ġ${ raw }") čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ä»£ æĽ¿ çļĦ Intent čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Intent Ġ= ĠIntent (). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponent Ġ= ĠComponent Name (" com . chen cc . android stud yn otes code ", ĠStub Activity :: class . java . name ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput Extra ( EXTRA _ TARGET _ INT ENT , Ġraw ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġargs [ index ] Ġ= Ġnew Intent čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmethod . invoke ( raw I Activity Manager , Ġ* args ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) čĊĠĠĠĠĠĠĠ Ġm Instance Field . set ( singleton , Ġproxy ) čĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ čĊĠĠĠĠĠĠĠ Ġe . printStackTrace () čĊĠĠĠ Ġ} č Ċ } čĊčĊč Ċ fun Ġhook Handler (){ čĊĠĠĠ Ġtry Ġ{ čĊĠĠĠĠĠĠĠ Ġval Ġfor Name Ġ= ĠClass . forName (" android . app . ActivityThread ") čĊĠĠĠĠĠĠĠ Ġval Ġs Current ActivityThread Field Ġ= Ġfor Name . getDeclared Field (" s Current ActivityThread "). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġval Ġs Current ActivityThread Ġ= Ġs Current ActivityThread Field . get ( null ) čĊčĊĠĠĠĠĠĠĠ Ġval Ġm H Field Ġ= Ġfor Name . getDeclared Field (" m H "). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġval Ġm H Ġ= Ġm H Field . get ( s Current ActivityThread ) Ġas ĠHandler čĊĠĠĠĠĠĠĠ Ġval Ġm Callback Field Ġ= ĠHandler :: class . java . getDeclared Field (" m Callback "). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠ Ġ}. set ( m H , Ġobject Ġ: ĠHandler . Callback Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġhandle Message ( msg : ĠMessage ): ĠBoolean Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" handle Message : Ġ Ġwhat Ġ: Ġ Ġ${ msg . what } Ġ Ġobj Ġ Ġ: Ġ${ msg ?. obj }") čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen ( msg . what ){ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ä»İ Android P å¼Ģå§ĭ éĩį æŀĦ äºĨ çĬ¶æĢģ æ¨¡å¼ı čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// public Ġstatic Ġfinal Ġint ĠEXEC UTE _ TRANSACTION Ġ= Ġ 1 5 9 ; čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ é¦ĸåħĪ ä¸Ģä¸ª app Ġ åıªæľī ä¸Ģä¸ª ActivityThread Ġ çĦ¶åĲİ å°± åıªæľī ä¸Ģä¸ª m H čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// æĪĳä»¬ app æīĢæľīçļĦ activity çļĦ çĶŁåĳ½ åĳ¨æľŁ çļĦ å¤ĦçĲĨ éĥ½ åľ¨ m H çļĦ handle Message éĩĮéĿ¢ å¤ĦçĲĨ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// åľ¨ Android Ġ 8 . 0 ä¹ĭåīį ï¼Į ä¸įåĲĮçļĦ çĶŁåĳ½ åĳ¨æľŁ å¯¹åºĶ ä¸įåĲĮçļĦ msg . what å¤ĦçĲĨ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// åľ¨ Android Ġ 9 . 0 Ġ æĶ¹ æĪĲ äºĨ åħ¨éĥ¨ çĶ± EXECUTE _ TRANSACTION æĿ¥ å¤ĦçĲĨ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// æīĢä»¥ è¿ĻéĩĮ ç¬¬ ä¸Ģæ¬¡ m Activity Callbacks æĺ¯ MainActivity çļĦ çĶŁåĳ½ åĳ¨æľŁ åĽŀè°ĥ çļĦ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 0 0 Ġ-> { čĊčĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġobj Ġ= Ġmsg . obj čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" handle Message : Ġ Ġobj Ġ: Ġ$ obj ") čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠclassName Ġ= Ġ" android . app . ActivityThread . Activity Client Record " čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( obj :: class . java . canonical Name Ġ== ĠclassName ){ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġintent Field Ġ= Ġ Ġobj :: class . java . getDeclared Field (" intent "). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġintent Ġ= Ġintent Field . get ( obj ) Ġas ĠIntent čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintent . apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Intent Ġ= Ġget Parcelable Extra < Intent >( EXTRA _ TARGET _ INT ENT ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintent . component Ġ= Ġtarget Intent ?. component čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 5 9 Ġ-> Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġobj Ġ= Ġmsg . obj čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" handle Message : Ġ Ġobj Ġ: Ġ$ obj ") čĊčĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm Activity Callbacks Field Ġ= Ġobj :: class . java . getDeclared Field (" m Activity Callbacks "). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm Activity Callbacks Ġ= Ġm Activity Callbacks Field . get ( obj ) Ġas ĠList < Any > čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Activity Callbacks . isNotEmpty ()){ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" handle Message : Ġm Activity Callbacks Ġsize Ġ: Ġ${ m Activity Callbacks . size }") čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠclassName Ġ= Ġ" android . app . server transaction . Launch Activity Item " čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Activity Callbacks [ 0 ]:: class . java . canonical Name Ġ== ĠclassName ){ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġobj Ġ= Ġm Activity Callbacks [ 0 ] čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġintent Field Ġ= Ġobj :: class . java . getDeclared Field (" m Intent "). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġintent Ġ= Ġintent Field . get ( obj ) Ġas ĠIntent čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintent . apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Intent Ġ= Ġget Parcelable Extra < Intent >( EXTRA _ TARGET _ INT ENT ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintent . component Ġ= Ġtarget Intent ?. component čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm H . handle Message ( msg ); čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ}) čĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ čĊĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" hook Handler : Ġ Ġe Ġ: Ġ Ġ${ e . message }") čĊĠĠĠĠĠĠĠ Ġe . printStackTrace () čĊĠĠĠ Ġ} č Ċ } čĊčĊč Ċ fun Ġhook Instrumentation ( activity Ġ: ĠActivity ){ čĊĠĠĠ Ġtry Ġ{ čĊĠĠĠĠĠĠĠ Ġval Ġactivity Class Ġ= Ġactivity :: class . java čĊĠĠĠĠĠĠĠ Ġ// ĠéĢļè¿ĩ Ġactivity . class Ġæĭ ¿ åĪ° Ġm Instrumentation Ġ åŃĹæ®µ čĊĠĠĠĠĠĠĠ Ġval Ġm Instrumentation Field Ġ= Ġactivity Class . getDeclared Field (" m Instrumentation "). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġval Ġm Instrumentation Ġ= Ġm Instrumentation Field . get ( activity ) Ġas ĠInstrument ation čĊĠĠĠĠĠĠĠ Ġ// åĪĽå»º ä»£çĲĨ å¯¹è±¡ , æ³¨æĦı äºĨ åĽłä¸º Instrumentation æĺ¯ ç±» ï¼Į ä¸įæĺ¯ æİ¥åı£ Ġ æīĢä»¥ æĪĳä»¬ åıªèĥ½ çĶ¨ éĿĻæĢģ ä»£çĲĨ čĊĠĠĠĠĠĠĠ Ġval Ġinstrument ation Proxy Ġ= ĠProxy Instrumentation ( m Instrumentation ) čĊĠĠĠĠĠĠĠ Ġ// ĠæĽ ¿ æį¢ čĊĠĠĠĠĠĠĠ Ġm Instrumentation Field . set ( activity , Ġinstrument ation Proxy ) čĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ čĊĠĠĠĠĠĠĠ Ġe . printStackTrace () čĊĠĠĠ Ġ} č Ċ } čĊč Ċ private Ġclass ĠProxy Instrumentation ( val Ġm Base Ġ: ĠInstrument ation ) Ġ: ĠInstrument ation (){ čĊčĊĠĠĠ Ġfun Ġexec Start Activity ( čĊĠĠĠĠĠĠĠ Ġwho : ĠContext ?, Ġcontext Thread : ĠI Binder ?, Ġtoken : ĠI Binder ?, Ġtarget : ĠActivity ?, čĊĠĠĠĠĠĠĠ Ġintent : ĠIntent ?, Ġrequest Code : ĠInt , Ġoptions : ĠBundle ? čĊĠĠĠ Ġ): ĠActivity Result ? { čĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" æī§è¡Į äºĨ startActivity , ĠåıĤæķ° å¦Ĥä¸ĭ : Ġ" Ġ+ Ġ" who Ġ= Ġ[" Ġ+ Ġwho Ġ+ Ġ" ], Ġ" Ġ+ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" context Thread Ġ= Ġ[" Ġ+ Ġcontext Thread Ġ+ Ġ" ], Ġtoken Ġ= Ġ[" Ġ+ Ġtoken Ġ+ Ġ" ], Ġ" Ġ+ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" target Ġ= Ġ[" Ġ+ Ġtarget Ġ+ Ġ" ], Ġintent Ġ= Ġ[" Ġ+ Ġintent Ġ+ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ], Ġrequest Code Ġ= Ġ[" Ġ+ Ġrequest Code Ġ+ Ġ" ], Ġoptions Ġ= Ġ[" Ġ+ Ġoptions Ġ+ Ġ"] "); čĊčĊĠĠĠĠĠĠĠ Ġtry Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexec Start Activity Ġ= ĠInstrument ation :: class . java . getDeclared Method (" exec Start Activity ", čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContext :: class . java , ĠI Binder :: class . java , ĠI Binder :: class . java Ġ, ĠActivity :: class . java Ġ, čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIntent :: class . java , ĠInt :: class . java , ĠBundle :: class . java ). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġexec Start Activity . invoke ( m Base , Ġwho , čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext Thread , Ġtoken , Ġtarget , Ġintent , Ġrequest Code , Ġoptions ) Ġas ĠActivity Result čĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġ ĠRuntimeException (" do Ġnot Ġsupport !!! Ġpl s Ġadapt Ġit ") čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġoverride Ġfun Ġnew Activity ( cl : ĠClassLoader ?, ĠclassName : ĠString ?, Ġintent : ĠIntent ?): ĠActivity Ġ{ čĊĠĠĠĠĠĠĠ Ġreturn Ġm Base . new Activity ( cl , ĠclassName , Ġintent ) čĊĠĠĠ Ġ} č Ċ } čĊč Ċ fun Ġhook ActivityThread Instrumentation (){ čĊĠĠĠ Ġtry Ġ{ čĊĠĠĠĠĠĠĠ Ġval Ġactivity Thread Class Ġ= ĠClass . forName (" android . app . ActivityThread ") čĊĠĠĠĠĠĠĠ Ġval Ġcurrent ActivityThread Method Ġ= Ġactivity Thread Class . getDeclared Method (" current ActivityThread "). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ// Ġthread Activity Ġå¯¹è±¡ čĊĠĠĠĠĠĠĠ Ġval Ġcurrent ActivityThread Ġ= Ġcurrent ActivityThread Method . invoke ( null ) čĊčĊĠĠĠĠĠĠĠ Ġval Ġm Instrumentation Field Ġ= Ġactivity Thread Class . getDeclared Field (" m Instrumentation "). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Accessible Ġ= Ġtrue čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġval Ġm Instrumentation Ġ= Ġm Instrumentation Field . get ( current ActivityThread ) Ġas ĠInstrument ation čĊĠĠĠĠĠĠĠ Ġval Ġinstrument ation Proxy Ġ= ĠProxy Instrumentation ( m Instrumentation ) čĊĠĠĠĠĠĠĠ Ġm Instrumentation Field . set ( current ActivityThread , Ġinstrument ation Proxy ) čĊčĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ čĊĠĠĠĠĠĠĠ Ġe . printStackTrace () čĊĠĠĠ Ġ} č Ċ }