mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 09:45:19 +08:00
301 lines
76 KiB
JavaScript
301 lines
76 KiB
JavaScript
import{_ as o,r as p,o as c,c as i,b as s,d as n,e as l,a as e}from"./app-BpUB8-Q8.js";const r={},t=e(`<h1 id="用法示例" tabindex="-1"><a class="header-anchor" href="#用法示例" aria-hidden="true">#</a> 用法示例</h1><blockquote><p>这里介绍了 <code>YukiHookAPI</code> 的基本工作方式以及列举了简单的 Hook 例子和常用功能。</p></blockquote><h2 id="结构图解" tabindex="-1"><a class="header-anchor" href="#结构图解" aria-hidden="true">#</a> 结构图解</h2><blockquote><p>下方的结构描述了 <code>YukiHookAPI</code> 的基本工作方式和原理。</p></blockquote><div class="language-text" data-ext="text"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#adbac7;">Host Environment</span></span>
|
||
<span class="line"><span style="color:#adbac7;">└─ YukiMemberHookCreator</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └─ Class</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └─ MemberHookCreator</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └─ Member</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> ├─ Before</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └─ After</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> MemberHookCreator</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └─ Member</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> ├─ Before</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └─ After</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> ...</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> YukiResourcesHookCreator</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └─ Resources</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └─ ResourcesHookCreator</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └─ Drawable</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └─ Replace</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> ResourcesHookCreator</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └─ Layout</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └─ Inject</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> ...</span></span>
|
||
<span class="line"><span style="color:#adbac7;"></span></span></code></pre></div><blockquote><p>上方的结构换做代码将可写为如下形式。</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// KavaRef 写法</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">TargetClass.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">before</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">after</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><details><summary>点击查看以往写法</summary><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 旧版 (1.2.x-1.3.0 (不含)) 写法</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">TargetClass.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> { </span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">before</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">after</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"><span style="color:#768390;">// 旧版写法</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">TargetClass.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> { </span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">injectMember</span><span style="color:#ADBAC7;"> { </span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> { </span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">beforeHook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">afterHook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></details><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// Resources Hook (2.0.0 将停止支持)</span></span>
|
||
<span class="line"><span style="color:#DCBDFB;">resources</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">injectResource</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">conditions</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">replaceTo</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">.)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="demo" tabindex="-1"><a class="header-anchor" href="#demo" aria-hidden="true">#</a> Demo</h2><blockquote><p>你可以在下方找到 API 提供的 Demo 来学习 <code>YukiHookAPI</code> 的使用方法。</p></blockquote>`,11),d={href:"https://github.com/HighCapable/YukiHookAPI/tree/master/samples/demo-app",target:"_blank",rel:"noopener noreferrer"},A={href:"https://github.com/HighCapable/YukiHookAPI/tree/master/samples/demo-module",target:"_blank",rel:"noopener noreferrer"},u=s("p",null,"同时安装宿主和模块 Demo,通过激活模块来测试宿主中被 Hook 的功能。",-1),y=s("h2",{id:"一个简单的-hook-例子",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#一个简单的-hook-例子","aria-hidden":"true"},"#"),n(" 一个简单的 Hook 例子")],-1),D=s("blockquote",null,[s("p",null,"这里给出了 Hook APP、Hook 系统框架与 Hook Resources 等例子,可供参考。")],-1),B={class:"custom-container tip"},v=s("p",{class:"custom-container-title"},"小提示",-1),C=s("code",null,"1.3.0",-1),m=s("code",null,"YukiHookAPI",-1),b={href:"https://github.com/HighCapable/KavaRef",target:"_blank",rel:"noopener noreferrer"},k=s("code",null,"KavaRef",-1),h=s("code",null,"YukiHookAPI",-1),F=e(`<h3 id="hook-app" tabindex="-1"><a class="header-anchor" href="#hook-app" aria-hidden="true">#</a> Hook APP</h3><p>假设,我们要 Hook <code>com.android.browser</code> 中的 <code>onCreate</code> 方法并弹出一个对话框。</p><p>在 <code>encase</code> 方法体中添加代码。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">loadApp</span><span style="color:#ADBAC7;">(name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.android.browser"</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> Activity::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> { </span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"onCreate"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(Bundle::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">after</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> AlertDialog.</span><span style="color:#DCBDFB;">Builder</span><span style="color:#ADBAC7;">(</span><span style="color:#DCBDFB;">instance</span><span style="color:#ADBAC7;">())</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">setTitle</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"Hooked"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">setMessage</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"I am hook!"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">setPositiveButton</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"OK"</span><span style="color:#ADBAC7;">, </span><span style="color:#6CB6FF;">null</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">show</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>至此,<code>onCreate</code> 方法将被成功 Hook 并在 <code>com.android.browser</code> 中的每个 <code>Activity</code> 启动时弹出此对话框。</p><p>那么,我想继续 Hook <code>onStart</code> 方法要怎么做呢?</p><p>我们可以对 <code>Activity::class.resolve()</code> 使用 Kotlin 的 <code>apply</code> 方法创建一个调用空间。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">loadApp</span><span style="color:#ADBAC7;">(name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.android.browser"</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> Activity::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">apply</span><span style="color:#ADBAC7;"> { </span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> { </span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"onCreate"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(Bundle::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">after</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> AlertDialog.</span><span style="color:#DCBDFB;">Builder</span><span style="color:#ADBAC7;">(</span><span style="color:#DCBDFB;">instance</span><span style="color:#ADBAC7;">())</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">setTitle</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"Hooked"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">setMessage</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"I am hook!"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">setPositiveButton</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"OK"</span><span style="color:#ADBAC7;">, </span><span style="color:#6CB6FF;">null</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">show</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> { </span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"onStart"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParameters</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">after</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>对于当前项目下没有的 <code>Class</code>,你可以使用 <code>stub</code> 方式或 <code>String.toClass(...)</code> 方法来得到需要 Hook 的类。</p><p>比如,我要得到 <code>com.example.demo.TestClass</code>。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#96D0FF;">"com.example.demo.TestClass"</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toClass</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>若 <code>com.example.demo</code> 是你要 Hook 的 APP,那么写法可以更简单。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#96D0FF;">"</span><span style="color:#6CB6FF;">$packageName</span><span style="color:#96D0FF;">.TestClass"</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toClass</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>若这个 <code>Class</code> 不是马上就能被得到的,你可以使用 <code>lazyClass(...)</code> 来定义它。</p><blockquote><p>示例如下</p></blockquote><p>定义 <code>TestClass</code>。</p><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> TestClass </span><span style="color:#F47067;">by</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">lazyClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"com.example.demo.TestClass"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>在适当的时候使用它。</p><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">TestClass.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../api/public/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator#memberhookcreator-class">MemberHookCreator</a>。</p></div><h3 id="hook-zygote" tabindex="-1"><a class="header-anchor" href="#hook-zygote" aria-hidden="true">#</a> Hook Zygote</h3><p>在 APP 启动时,新的进程被 fork 后的第一个事件 <code>initZygote</code>。</p><p>假设我们要全局 Hook 一个 APP <code>Activity</code> 的 <code>onCreate</code> 事件</p><p>在 <code>encase</code> 方法体中添加代码。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">loadZygote</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> Activity::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"onCreate"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(Bundle::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">after</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container warning"><p class="custom-container-title">注意</p><p>在 <strong>loadZygote</strong> 中进行的功能十分有限,几乎很少的情况下需要用到 <strong>loadZygote</strong> 方法。</p></div><h3 id="hook-系统框架" tabindex="-1"><a class="header-anchor" href="#hook-系统框架" aria-hidden="true">#</a> Hook 系统框架</h3><p>在 <code>YukiHookAPI</code> 中,Hook 系统框架的实现非常简单。</p><p>假设,你要得到 <code>ApplicationInfo</code> 与 <code>PackageInfo</code> 并对它们进行一些操作。</p><p>在 <code>encase</code> 方法体中添加代码。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">loadSystem</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> ApplicationInfo::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> PackageInfo::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container danger"><p class="custom-container-title">特别注意</p><p><strong>loadZygote</strong> 与 <strong>loadSystem</strong> 有直接性区别,<strong>loadZygote</strong> 会在 <strong>initZygote</strong> 中装载,系统框架被视为 <strong>loadApp(name = "android")</strong> 而存在,若要 Hook 系统框架,可直接使用 <strong>loadSystem</strong>。</p></div><h3 id="hook-resources" tabindex="-1"><a class="header-anchor" href="#hook-resources" aria-hidden="true">#</a> Hook Resources</h3><div class="custom-container warning"><p class="custom-container-title">注意</p><p>此功能将在 <strong>2.0.0</strong> 版本停止支持并移除。</p></div><p>假设,我们要 Hook <code>com.android.browser</code> 中 <code>string</code> 类型的 <code>app_name</code> 内容替换为 <code>123</code>。</p><p>在 <code>encase</code> 方法体中添加代码。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">loadApp</span><span style="color:#ADBAC7;">(name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.android.browser"</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">resources</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">injectResource</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">conditions</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"app_name"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">string</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">replaceTo</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"123"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>若当前 APP 使用 <code>app_name</code> 设置了标题栏文本,则它就会变成我们的 <code>123</code>。</p><p>你还可以使用当前 Xposed 模块的 Resources 替换 Hook APP 的 Resources。</p><p>假设,我们要继续 Hook <code>com.android.browser</code> 中 <code>mipmap</code> 类型的 <code>ic_launcher</code>。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">loadApp</span><span style="color:#ADBAC7;">(name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.android.browser"</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">resources</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">injectResource</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">conditions</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"ic_launcher"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">mipmap</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">replaceToModuleResource</span><span style="color:#ADBAC7;">(R.mipmap.ic_launcher)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>至此目标 APP 的图标将会被替换为我们设置的图标。</p><p>若你想替换系统框架的资源,同样也可以这样实现,只需要把 <code>loadApp</code> 换成 <code>loadZygote</code> 即可。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">loadZygote</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">resources</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../api/public/com/highcapable/yukihookapi/hook/core/YukiResourcesHookCreator#resourceshookcreator-class">ResourcesHookCreator</a>。</p></div><h3 id="解除-hook" tabindex="-1"><a class="header-anchor" href="#解除-hook" aria-hidden="true">#</a> 解除 Hook</h3><p>原生的 Xposed 为我们提供了一个 <code>XC_MethodHook.Unhook</code> 功能,可以从 Hook 队列中将当前 Hook 移除,<code>YukiHookAPI</code> 同样可以实现此功能。</p><p>第一种方法,保存当前注入对象的 <code>Result</code> 实例,在适当的时候和地方调用 <code>remove</code> 即可解除该注入对象。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 设置一个变量保存当前实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> hookResult </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"test"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> Void.TYPE</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">after</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#768390;">// 在适当的时候调用如下方法即可</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">hookResult.</span><span style="color:#DCBDFB;">remove</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>第二种方法,在 Hook 回调方法中调用 <code>removeSelf</code> 移除自身。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> { </span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"test"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> Void.TYPE</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">after</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 直接调用如下方法即可</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">removeSelf</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../api/public/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator#memberhookcreator-class">MemberHookCreator</a>。</p></div><h2 id="异常处理" tabindex="-1"><a class="header-anchor" href="#异常处理" aria-hidden="true">#</a> 异常处理</h2><blockquote><p><code>YukiHookAPI</code> 重新设计了对异常的监听,任何异常都不会在 Hook 过程中抛出,避免打断下一个 Hook 流程导致 Hook 进程“死掉”。</p></blockquote><h3 id="监听异常" tabindex="-1"><a class="header-anchor" href="#监听异常" aria-hidden="true">#</a> 监听异常</h3><p>你可以处理 Hook 方法过程发生的异常。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">result</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 处理 Hook 开始时的异常</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onHookingFailure</span><span style="color:#ADBAC7;"> {}</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 处理 Hook 过程中的异常</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onConductFailure</span><span style="color:#ADBAC7;"> { param, throwable </span><span style="color:#F47067;">-></span><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 处理全部异常</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onAllFailure</span><span style="color:#ADBAC7;"> {}</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在 Resources Hook 时此方法同样适用。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">injectResource</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">result</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 处理 Hook 时的任意异常</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onHookingFailure</span><span style="color:#ADBAC7;"> {}</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>(旧版本适用)</strong> 你还可以处理 Hook 的 <code>Class</code> 不存在时发生的异常。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">TargetClass.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">injectMember</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">onHookClassNotFoundFailure</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>(旧版本适用)</strong> 你还可以处理查找方法时的异常。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">onNoSuchMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../api/public/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator#result-class">MemberHookCreator.Result</a>、<a href="../api/public/com/highcapable/yukihookapi/hook/core/YukiResourcesHookCreator#result-class">ResourcesHookCreator.Result</a>。</p></div><p>这里介绍了可能发生的常见异常,若要了解更多请参考 <a href="../config/api-exception">API 异常处理</a>。</p>`,80),g={class:"custom-container warning"},q=s("p",{class:"custom-container-title"},"注意",-1),x=s("code",null,"KavaRef",-1),H={href:"https://highcapable.github.io/KavaRef/zh-cn/library/kavaref-core#%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86",target:"_blank",rel:"noopener noreferrer"},f=s("code",null,"KavaRef",-1),P=e(`<h3 id="抛出异常" tabindex="-1"><a class="header-anchor" href="#抛出异常" aria-hidden="true">#</a> 抛出异常</h3><p>在某些情况下,你可以<strong>手动抛出异常</strong>来达到提醒某些功能存在问题的目的。</p><p>上面已经介绍过,在 <code>hook</code> 方法体内抛出的异常会被 <code>YukiHookAPI</code> 接管,避免打断下一个 Hook 流程导致 Hook 进程“死掉”。</p><p>以下是 <code>YukiHookAPI</code> 接管时这些异常的运作方式。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// <情景1></span></span>
|
||
<span class="line"><span style="color:#DCBDFB;">injectMember</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">throw</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">RuntimeException</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"Exception Test"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">afterHook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">result</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 能够捕获到 RuntimeException</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onHookingFailure</span><span style="color:#ADBAC7;"> {}</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"><span style="color:#768390;">// <情景2></span></span>
|
||
<span class="line"><span style="color:#DCBDFB;">injectMember</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">afterHook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">throw</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">RuntimeException</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"Exception Test"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">result</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 能够捕获到 RuntimeException</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onConductFailure</span><span style="color:#ADBAC7;"> { param, throwable </span><span style="color:#F47067;">-></span><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>以上情景只会在 (Xposed) 宿主环境被处理,不会对宿主自身造成任何影响。</p><p>若我们想将这些异常直接抛给宿主,原生的 Xposed 为我们提供了 <code>param.throwable</code> 方法,<code>YukiHookAPI</code> 同样可以实现此功能。</p><p>若想在 Hook 回调方法体中将一个异常直接抛给宿主,可以有如下实现方法。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">after</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">RuntimeException</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"Exception Test"</span><span style="color:#ADBAC7;">).</span><span style="color:#DCBDFB;">throwToApp</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你也可以直接在 Hook 回调方法体中抛出异常,然后标识将异常抛给宿主。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">after</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">throw</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">RuntimeException</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"Exception Test"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">onFailureThrowToApp</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>以上两种方法均可在宿主接收到异常从而使宿主进程崩溃。</p><div class="custom-container warning"><p class="custom-container-title">注意</p><p>为了保证 Hook 调用域与宿主内调用域相互隔离,异常只有在 <strong>before</strong> 与 <strong>after</strong> 回调方法体中才能抛给宿主。</p></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../api/public/com/highcapable/yukihookapi/hook/param/HookParam#throwable-throwtoapp-i-ext-method">Throwable.throwToApp</a>、<a href="../api/public/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator#hookcallback-class">YukiMemberHookCreator.MemberMookCreator.HookCallback</a>。</p></div><h2 id="扩展用法" tabindex="-1"><a class="header-anchor" href="#扩展用法" aria-hidden="true">#</a> 扩展用法</h2><blockquote><p>你可以在 Hook 过程中使用下面的方法方便地实现各种判断和功能。</p></blockquote><h3 id="多个宿主" tabindex="-1"><a class="header-anchor" href="#多个宿主" aria-hidden="true">#</a> 多个宿主</h3><p>如果你的模块需要同时处理多个 APP 的 Hook 事件,你可以使用 <code>loadApp</code> 方法体来区分你要 Hook 的 APP。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">loadApp</span><span style="color:#ADBAC7;">(name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.android.browser"</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"><span style="color:#DCBDFB;">loadApp</span><span style="color:#ADBAC7;">(name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.android.phone"</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../api/public/com/highcapable/yukihookapi/hook/param/PackageParam#loadapp-method">PackageParam.loadApp</a>。</p></div><h3 id="多个进程" tabindex="-1"><a class="header-anchor" href="#多个进程" aria-hidden="true">#</a> 多个进程</h3><p>如果你 Hook 的宿主 APP 有多个进程,你可以使用 <code>withProcess</code> 方法体来对它们分别进行 Hook。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">withProcess</span><span style="color:#ADBAC7;">(mainProcessName) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"><span style="color:#DCBDFB;">withProcess</span><span style="color:#ADBAC7;">(name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"</span><span style="color:#6CB6FF;">$packageName</span><span style="color:#96D0FF;">:tool"</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../api/public/com/highcapable/yukihookapi/hook/param/PackageParam#withprocess-method">PackageParam.withProcess</a>。</p></div><h2 id="写法优化" tabindex="-1"><a class="header-anchor" href="#写法优化" aria-hidden="true">#</a> 写法优化</h2><p>为了使代码更加简洁,你可以删去 <code>YukiHookAPI</code> 的名称,将你的 <code>onHook</code> 入口写作 <strong>lambda</strong> 形式。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onHook</span><span style="color:#ADBAC7;">() </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">encase</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你还可以在仅需要一个 Hook 回调事件的时候简写 <code>hook { ... }</code> 方法体。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">Activity::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">after</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="xposed-模块状态" tabindex="-1"><a class="header-anchor" href="#xposed-模块状态" aria-hidden="true">#</a> Xposed 模块状态</h2><p>通常情况下,Xposed 模块的开发者都会去选择读取当前 Xposed 模块的激活信息以更好地向用户展示当前功能的生效状态。</p><p>除了基本的 Hook 功能,<code>YukiHookAPI</code> 还为开发者设计了一套 Xposed 模块状态判断的功能,如激活状态、Hook Framework 信息。</p><h3 id="判断自身激活状态" tabindex="-1"><a class="header-anchor" href="#判断自身激活状态" aria-hidden="true">#</a> 判断自身激活状态</h3><p>通常情况下,我们会选择写一个方法,使其返回 <code>false</code>,然后 Hook 掉这个方法使其返回 <code>true</code> 来证明 Hook 已经生效。</p><p>在 <code>YukiHookAPI</code> 中你完全不需要再这么做了,<code>YukiHookAPI</code> 已经帮你封装好了这个操作,你可以直接进行使用。</p><p>现在,你可以直接使用 <code>YukiHookAPI.Status.isXposedModuleActive</code> 在模块中判断自身是否被激活。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">if</span><span style="color:#ADBAC7;">(YukiHookAPI.Status.isXposedModuleActive) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>由于一些特殊原因,在太极、无极中的模块无法使用标准方法检测激活状态。</p><p>此时你可以使用 <code>YukiHookAPI.Status.isTaiChiModuleActive</code> 判断自身是否被激活。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">if</span><span style="color:#ADBAC7;">(YukiHookAPI.Status.isTaiChiModuleActive) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>若你想使用两者得兼的判断方案,<code>YukiHookAPI</code> 同样为你封装了便捷的方式。</p><p>此时你可以使用 <code>YukiHookAPI.Status.isModuleActive</code> 判断自身是否在 Xposed 或太极、无极中被激活。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">if</span><span style="color:#ADBAC7;">(YukiHookAPI.Status.isModuleActive) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../api/public/com/highcapable/yukihookapi/YukiHookAPI#status-object">YukiHookAPI.Status</a>。</p></div><div class="custom-container warning"><p class="custom-container-title">注意</p><p>如果你的模块 API 版本高于 29 且正在目标 API 为 29 以上的系统中运行,你需要在 <strong>AndroidManifest.xml</strong> 中添加如下权限声明才能正常判断模块在太极、无极中的激活状态。</p><blockquote><p>示例如下</p></blockquote><div class="language-xml line-numbers-mode" data-ext="xml"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;"><</span><span style="color:#8DDB8C;">queries</span><span style="color:#ADBAC7;">></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> <</span><span style="color:#8DDB8C;">intent</span><span style="color:#ADBAC7;">></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> <</span><span style="color:#8DDB8C;">action</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">android:name</span><span style="color:#ADBAC7;">=</span><span style="color:#96D0FF;">"android.intent.action.MAIN"</span><span style="color:#ADBAC7;"> /></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </</span><span style="color:#8DDB8C;">intent</span><span style="color:#ADBAC7;">></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"></</span><span style="color:#8DDB8C;">queries</span><span style="color:#ADBAC7;">></span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>还有一种方案,你可以直接声明 <strong>android.permission.QUERY_ALL_PACKAGES</strong> 权限,但是不推荐且会被代码检查警告。</p><blockquote><p>示例如下</p></blockquote><div class="language-xml line-numbers-mode" data-ext="xml"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;"><</span><span style="color:#8DDB8C;">uses-permission</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">android:name</span><span style="color:#ADBAC7;">=</span><span style="color:#96D0FF;">"android.permission.QUERY_ALL_PACKAGES"</span><span style="color:#ADBAC7;"> /></span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>若模块激活判断中包含太极、无极中的激活状态,就必须将模块的 <strong>Application</strong> 继承于 <strong>ModuleApplication</strong> 或直接使用 <strong>ModuleApplication</strong>。</p></div><h3 id="获取-hook-framework-信息" tabindex="-1"><a class="header-anchor" href="#获取-hook-framework-信息" aria-hidden="true">#</a> 获取 Hook Framework 信息</h3><p>除了判断自身激活状态之外,你还可以通过 <code>YukiHookAPI.Status</code> 中的 <code>Executor</code> 来获取当前 Hook Framework 的相关信息。</p><p>例如我们可以使用 <code>YukiHookAPI.Status.Executor.name</code> 来获取当前 Hook Framework 的名称。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> frameworkName </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> YukiHookAPI.Status.Executor.name</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>我们还可以使用 <code>YukiHookAPI.Status.Executor.apiLevel</code> 来获取当前 Hook Framework 的 API Level。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> frameworkApiLevel </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> YukiHookAPI.Status.Executor.apiLevel</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../api/public/com/highcapable/yukihookapi/YukiHookAPI#executor-object">YukiHookAPI.Status.Executor</a>。</p></div><div class="custom-container warning"><p class="custom-container-title">注意</p><p><strong>1.0.91</strong> 版本后的 <strong>YukiHookAPI</strong> 修改了获取 Xposed 模块状态的逻辑判断方式,现在你可以在模块与 Hook APP (宿主) 中同时使用此 API;</p><p>需要确保 <strong>InjectYukiHookWithXposed.isUsingXposedModuleStatus</strong> 是启用状态;</p><p><strong>YukiHookAPI</strong> 仅对已知的获取方式进行了对接,除了提供标准 API 的 Hook Framework 之外,其它情况下模块可能都将无法判断自己是否被激活或是获取 Hook Framework 的相关信息。</p></div>`,65);function Y(_,I){const a=p("ExternalLinkIcon");return c(),i("div",null,[t,s("ul",null,[s("li",null,[s("p",null,[n("宿主 APP Demo "),s("a",d,[n("点击这里查看"),l(a)])])]),s("li",null,[s("p",null,[n("模块 APP Demo "),s("a",A,[n("点击这里查看"),l(a)])])])]),u,y,D,s("div",B,[v,s("p",null,[n("从 "),C,n(" 版本开始,"),m,n(" 已将自身的反射 API 部分迁移至 "),s("a",b,[n("KavaRef"),l(a)]),n(",下方演示部分的反射 API 均使用了 "),k,n(" 的写法,我们不再推荐使用 "),h,n(" 自身的反射 API。")])]),F,s("div",g,[q,s("p",null,[x,n(" 的异常将由其自身单独管理,详细的配置方案你可以参考 "),s("a",H,[n("这里"),l(a)]),n(",这将跳转到 "),f,n(" 的文档。")])]),P])}const w=o(r,[["render",Y],["__file","example.html.vue"]]);export{w as default};
|