-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
98 lines (54 loc) · 167 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Shoewann's Personal Blog</title>
<subtitle>移动端应用相关技术记录总结</subtitle>
<link href="https://shoewann0402.github.io/atom.xml" rel="self"/>
<link href="https://shoewann0402.github.io/"/>
<updated>2024-12-25T10:21:20.708Z</updated>
<id>https://shoewann0402.github.io/</id>
<author>
<name>Shoewann</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>Android 之 “摇一摇”广告机制逆向分析</title>
<link href="https://shoewann0402.github.io/posts/e3313220.html"/>
<id>https://shoewann0402.github.io/posts/e3313220.html</id>
<published>2024-12-25T03:03:56.000Z</published>
<updated>2024-12-25T10:21:20.708Z</updated>
<content type="html"><![CDATA[<p><img src="/posts/e3313220/65d74dee-3a8a-4b8b-abf8-b8091e4e7a59.jpeg" alt="alt text"></p><span id="more"></span><h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><blockquote><ul><li>摇一摇”开屏广告是一种通过摇动手机触发广告跳转的广告形式,由芒果TV发明并申请了相关专利。</li><li>该功能在App中普遍存在,但由于其高灵敏度,常在非用户主动操作的情况下触发广告跳转,侵犯用户权益,</li><li>工信部发布通知,要求移动互联网应用不得利用高灵敏度“摇一摇”等方式诱导用户操作。</li></ul></blockquote><h2 id="实现机制"><a href="#实现机制" class="headerlink" title="实现机制"></a>实现机制</h2><p>“摇一摇”广告功能通常通过调用手机中的加速度、重力、陀螺仪等一种或多种传感器实现,当用户摇动手机触发相应的传感器阈值后可实现广告交互。</p><h2 id="监管要求"><a href="#监管要求" class="headerlink" title="监管要求"></a>监管要求</h2><p>根据电信终端产业协会发布的(T/TAF078.7-2022)《APP用户权益保障测评规范 第7部分:欺骗误导强迫行为》</p><blockquote><ul><li>加速度不小于15m/s²</li><li>转动角度不小于35°</li><li>操作时间不少于3秒</li></ul></blockquote><h2 id="定位函数"><a href="#定位函数" class="headerlink" title="定位函数"></a>定位函数</h2><p>实现原理分析可知,App注册传感器监听器之后,需要传递一个监听器对象,这个对象包含了 <strong>onSensorChanged</strong> 和 <strong>onAccuracyChanged</strong> 两个方法,对安装包进行反编译查找 <strong>onSensorChanged</strong> 相关代码</p><h2 id="分析案例"><a href="#分析案例" class="headerlink" title="分析案例"></a>分析案例</h2><h3 id="京东广告"><a href="#京东广告" class="headerlink" title="京东广告"></a>京东广告</h3><p>示例应用:喜马拉雅.apk</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.jd.ad.sdk.bl.dynamicrender;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> android.content.Context;</span><br><span class="line"><span class="keyword">import</span> android.hardware.Sensor;</span><br><span class="line"><span class="keyword">import</span> android.hardware.SensorEvent;</span><br><span class="line"><span class="keyword">import</span> android.hardware.SensorEventListener;</span><br><span class="line"><span class="keyword">import</span> android.hardware.SensorManager;</span><br><span class="line"><span class="keyword">import</span> com.umeng.analytics.pro.ak;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* loaded from: classes13.dex */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">ShakeListener</span> <span class="keyword">implements</span> <span class="title class_">SensorEventListener</span> {</span><br><span class="line"> <span class="keyword">public</span> SensorManager jad_an;</span><br><span class="line"> <span class="keyword">public</span> <span class="type">int</span> jad_bo;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="title function_">ShakeListener</span><span class="params">(Context context, <span class="type">int</span> i)</span> {</span><br><span class="line"> <span class="built_in">this</span>.jad_bo = <span class="number">19</span>;</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="built_in">this</span>.jad_an = (SensorManager) context.getSystemService(ak.ac);</span><br><span class="line"> } <span class="keyword">catch</span> (SecurityException e2) {</span><br><span class="line"> e2.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">this</span>.jad_bo = i;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span> <span class="comment">// android.hardware.SensorEventListener</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onAccuracyChanged</span><span class="params">(Sensor sensor, <span class="type">int</span> i)</span> {</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span> <span class="comment">// android.hardware.SensorEventListener</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onSensorChanged</span><span class="params">(SensorEvent sensorEvent)</span> {</span><br><span class="line"> <span class="keyword">if</span> (sensorEvent.sensor.getType() == <span class="number">1</span>) {</span><br><span class="line"> <span class="type">float</span>[] fArr = sensorEvent.values;</span><br><span class="line"> <span class="keyword">if</span> (Math.sqrt(Math.pow(fArr[<span class="number">2</span>], <span class="number">2.0d</span>) + Math.pow(fArr[<span class="number">1</span>], <span class="number">2.0d</span>) + Math.pow(fArr[<span class="number">0</span>], <span class="number">2.0d</span>)) > <span class="built_in">this</span>.jad_bo) {</span><br><span class="line"> onShake();</span><br><span class="line"> unregister();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">onShake</span><span class="params">()</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">register</span><span class="params">()</span> {</span><br><span class="line"> <span class="type">SensorManager</span> <span class="variable">sensorManager</span> <span class="operator">=</span> <span class="built_in">this</span>.jad_an;</span><br><span class="line"> <span class="keyword">if</span> (sensorManager != <span class="literal">null</span>) {</span><br><span class="line"> sensorManager.registerListener(<span class="built_in">this</span>, sensorManager.getDefaultSensor(<span class="number">1</span>), <span class="number">2</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">unregister</span><span class="params">()</span> {</span><br><span class="line"> <span class="type">SensorManager</span> <span class="variable">sensorManager</span> <span class="operator">=</span> <span class="built_in">this</span>.jad_an;</span><br><span class="line"> <span class="keyword">if</span> (sensorManager != <span class="literal">null</span>) {</span><br><span class="line"> sensorManager.unregisterListener(<span class="built_in">this</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>在 <strong>onSensorChanged</strong>方法中,它使用的算法</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (Math.sqrt(Math.pow(fArr[<span class="number">2</span>], <span class="number">2.0d</span>) + Math.pow(fArr[<span class="number">1</span>], <span class="number">2.0d</span>) + Math.pow(fArr[<span class="number">0</span>], <span class="number">2.0d</span>)) > <span class="built_in">this</span>.jad_bo) {</span><br><span class="line"> onShake();</span><br><span class="line"> unregister();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>通过计算三轴值分别平方的和,再开方,与 <strong>this.jad_bo</strong> 的值进行比较,如果大于则进入摇一摇逻辑。</p><p>在 <strong>ShakeListener</strong> 的构造函数中 <strong>this.jad_bo</strong> 的默认值是 19,通过第二个参数 i 赋值动态的阀值给 <strong>this.jad_bo</strong></p><h3 id="淘宝广告"><a href="#淘宝广告" class="headerlink" title="淘宝广告"></a>淘宝广告</h3><p>示例应用:天猫.apk</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> android.taobao.windvane.jsbridge.api;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> android.content.Context;</span><br><span class="line"><span class="keyword">import</span> android.hardware.Sensor;</span><br><span class="line"><span class="keyword">import</span> android.hardware.SensorEvent;</span><br><span class="line"><span class="keyword">import</span> android.hardware.SensorEventListener;</span><br><span class="line"><span class="keyword">import</span> android.hardware.SensorManager;</span><br><span class="line"><span class="keyword">import</span> android.taobao.windvane.util.TaoLog;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* loaded from: classes.dex */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ShakeListener</span> <span class="keyword">implements</span> <span class="title class_">SensorEventListener</span> {</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">int</span> <span class="variable">SPEED_THRESHOLD</span> <span class="operator">=</span> <span class="number">10</span>;</span><br><span class="line"> <span class="keyword">private</span> <span class="type">long</span> mCheckFrequency;</span><br><span class="line"> <span class="keyword">private</span> Context mContext;</span><br><span class="line"> <span class="keyword">private</span> <span class="type">long</span> mLastUpdateTime;</span><br><span class="line"> <span class="keyword">private</span> <span class="type">float</span> mLastX;</span><br><span class="line"> <span class="keyword">private</span> <span class="type">float</span> mLastY;</span><br><span class="line"> <span class="keyword">private</span> <span class="type">float</span> mLastZ;</span><br><span class="line"> <span class="keyword">private</span> SensorManager mSensorManager;</span><br><span class="line"> <span class="keyword">private</span> OnShakeListener mShakeListener;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* loaded from: classes.dex */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">OnShakeListener</span> {</span><br><span class="line"> <span class="keyword">void</span> <span class="title function_">onShake</span><span class="params">()</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="title function_">ShakeListener</span><span class="params">(Context context, <span class="type">long</span> j)</span> {</span><br><span class="line"> <span class="built_in">this</span>.mContext = context;</span><br><span class="line"> <span class="built_in">this</span>.mCheckFrequency = j;</span><br><span class="line"> start();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span> <span class="comment">// android.hardware.SensorEventListener</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onAccuracyChanged</span><span class="params">(Sensor sensor, <span class="type">int</span> i)</span> {</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span> <span class="comment">// android.hardware.SensorEventListener</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onSensorChanged</span><span class="params">(SensorEvent sensorEvent)</span> {</span><br><span class="line"> OnShakeListener onShakeListener;</span><br><span class="line"> <span class="keyword">if</span> (sensorEvent.sensor.getType() != <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="type">long</span> <span class="variable">currentTimeMillis</span> <span class="operator">=</span> System.currentTimeMillis();</span><br><span class="line"> <span class="keyword">if</span> (currentTimeMillis - <span class="built_in">this</span>.mLastUpdateTime < <span class="built_in">this</span>.mCheckFrequency) {</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="type">float</span>[] fArr = sensorEvent.values;</span><br><span class="line"> <span class="type">float</span> <span class="variable">f</span> <span class="operator">=</span> fArr[<span class="number">0</span>];</span><br><span class="line"> <span class="type">float</span> <span class="variable">f2</span> <span class="operator">=</span> fArr[<span class="number">1</span>];</span><br><span class="line"> <span class="type">float</span> <span class="variable">f3</span> <span class="operator">=</span> fArr[<span class="number">2</span>];</span><br><span class="line"> <span class="type">float</span> <span class="variable">f4</span> <span class="operator">=</span> f - <span class="built_in">this</span>.mLastX;</span><br><span class="line"> <span class="type">float</span> <span class="variable">f5</span> <span class="operator">=</span> f2 - <span class="built_in">this</span>.mLastY;</span><br><span class="line"> <span class="type">float</span> <span class="variable">f6</span> <span class="operator">=</span> f3 - <span class="built_in">this</span>.mLastZ;</span><br><span class="line"> <span class="keyword">if</span> (Math.sqrt((f4 * f4) + (f5 * f5) + (f6 * f6)) > <span class="number">10.0d</span> && (onShakeListener = <span class="built_in">this</span>.mShakeListener) != <span class="literal">null</span> && onShakeListener != <span class="literal">null</span> && Math.abs(<span class="built_in">this</span>.mLastX) > <span class="number">0.0f</span> && Math.abs(<span class="built_in">this</span>.mLastY) > <span class="number">0.0f</span> && Math.abs(<span class="built_in">this</span>.mLastZ) > <span class="number">0.0f</span>) {</span><br><span class="line"> <span class="built_in">this</span>.mShakeListener.onShake();</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">this</span>.mLastUpdateTime = currentTimeMillis;</span><br><span class="line"> <span class="built_in">this</span>.mLastX = f;</span><br><span class="line"> <span class="built_in">this</span>.mLastY = f2;</span><br><span class="line"> <span class="built_in">this</span>.mLastZ = f3;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">pause</span><span class="params">()</span> {</span><br><span class="line"> <span class="type">SensorManager</span> <span class="variable">sensorManager</span> <span class="operator">=</span> <span class="built_in">this</span>.mSensorManager;</span><br><span class="line"> <span class="keyword">if</span> (sensorManager != <span class="literal">null</span>) {</span><br><span class="line"> sensorManager.unregisterListener(<span class="built_in">this</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">resume</span><span class="params">()</span> {</span><br><span class="line"> <span class="type">SensorManager</span> <span class="variable">sensorManager</span> <span class="operator">=</span> <span class="built_in">this</span>.mSensorManager;</span><br><span class="line"> <span class="keyword">if</span> (sensorManager == <span class="literal">null</span> || sensorManager.registerListener(<span class="built_in">this</span>, sensorManager.getDefaultSensor(<span class="number">1</span>), <span class="number">2</span>)) {</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">this</span>.mSensorManager.unregisterListener(<span class="built_in">this</span>);</span><br><span class="line"> TaoLog.m263w(<span class="string">"ShakeListener"</span>, <span class="string">"start: Accelerometer not supported"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setOnShakeListener</span><span class="params">(OnShakeListener onShakeListener)</span> {</span><br><span class="line"> <span class="built_in">this</span>.mShakeListener = onShakeListener;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">start</span><span class="params">()</span> {</span><br><span class="line"> <span class="type">SensorManager</span> <span class="variable">sensorManager</span> <span class="operator">=</span> (SensorManager) <span class="built_in">this</span>.mContext.getSystemService(<span class="string">"sensor"</span>);</span><br><span class="line"> <span class="built_in">this</span>.mSensorManager = sensorManager;</span><br><span class="line"> <span class="keyword">if</span> (sensorManager == <span class="literal">null</span>) {</span><br><span class="line"> TaoLog.m263w(<span class="string">"ShakeListener"</span>, <span class="string">"start: Sensors not supported"</span>);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">if</span> (sensorManager.registerListener(<span class="built_in">this</span>, sensorManager.getDefaultSensor(<span class="number">1</span>), <span class="number">2</span>)) {</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">this</span>.mSensorManager.unregisterListener(<span class="built_in">this</span>);</span><br><span class="line"> TaoLog.m263w(<span class="string">"ShakeListener"</span>, <span class="string">"start: Accelerometer not supported"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">stop</span><span class="params">()</span> {</span><br><span class="line"> <span class="type">SensorManager</span> <span class="variable">sensorManager</span> <span class="operator">=</span> <span class="built_in">this</span>.mSensorManager;</span><br><span class="line"> <span class="keyword">if</span> (sensorManager != <span class="literal">null</span>) {</span><br><span class="line"> sensorManager.unregisterListener(<span class="built_in">this</span>);</span><br><span class="line"> <span class="built_in">this</span>.mSensorManager = <span class="literal">null</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>在 <strong>onSensorChanged</strong> 的方法中我们可以看到</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (sensorEvent.sensor.getType() != <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>判断传感器类型不是加速度就终止向下执行</p><p>当加速度类型条件满足,首先做了时间间隔的判断</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">long</span> <span class="variable">currentTimeMillis</span> <span class="operator">=</span> System.currentTimeMillis();</span><br><span class="line"><span class="keyword">if</span> (currentTimeMillis - <span class="built_in">this</span>.mLastUpdateTime < <span class="built_in">this</span>.mCheckFrequency) {</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>并接着分别获取了三轴的值</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">float</span>[] fArr = sensorEvent.values;</span><br><span class="line"><span class="type">float</span> <span class="variable">f</span> <span class="operator">=</span> fArr[<span class="number">0</span>];</span><br><span class="line"><span class="type">float</span> <span class="variable">f2</span> <span class="operator">=</span> fArr[<span class="number">1</span>];</span><br><span class="line"><span class="type">float</span> <span class="variable">f3</span> <span class="operator">=</span> fArr[<span class="number">2</span>];</span><br></pre></td></tr></table></figure><p>计算三轴两次的变化差异</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">float</span> <span class="variable">f4</span> <span class="operator">=</span> f - <span class="built_in">this</span>.mLastX;</span><br><span class="line"><span class="type">float</span> <span class="variable">f5</span> <span class="operator">=</span> f2 - <span class="built_in">this</span>.mLastY;</span><br><span class="line"><span class="type">float</span> <span class="variable">f6</span> <span class="operator">=</span> f3 - <span class="built_in">this</span>.mLastZ;</span><br></pre></td></tr></table></figure><p>接着就是一个判断函数</p><p>当满足条件,执行具体的摇一摇函数 <strong>this.mShakeListener.onShake();</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (Math.sqrt((f4 * f4) + (f5 * f5) + (f6 * f6)) > <span class="number">10.0d</span> && (onShakeListener = <span class="built_in">this</span>.mShakeListener) != <span class="literal">null</span> && onShakeListener != <span class="literal">null</span> && Math.abs(<span class="built_in">this</span>.mLastX) > <span class="number">0.0f</span> &&Math.abs(<span class="built_in">this</span>.mLastY) > <span class="number">0.0f</span> && Math.abs(<span class="built_in">this</span>.mLastZ) > <span class="number">0.0f</span>) {</span><br><span class="line"> <span class="built_in">this</span>.mShakeListener.onShake();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>最后, 保存本次的时间戳和三轴值</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">this</span>.mLastUpdateTime = currentTimeMillis;</span><br><span class="line"><span class="built_in">this</span>.mLastX = f;</span><br><span class="line"><span class="built_in">this</span>.mLastY = f2;</span><br><span class="line"><span class="built_in">this</span>.mLastZ = f3;</span><br></pre></td></tr></table></figure><h4 id="分析判断条件"><a href="#分析判断条件" class="headerlink" title="分析判断条件"></a>分析判断条件</h4><h5 id="条件判断-1"><a href="#条件判断-1" class="headerlink" title="条件判断 1"></a>条件判断 1</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Math.sqrt((f4 * f4) + (f5 * f5) + (f6 * f6))><span class="number">10.0d</span></span><br></pre></td></tr></table></figure><p>同样也是,这里计算三轴分别变化差异的平方和,再开方,得到<strong>sqrt</strong> 加速度的值</p><p>判断这个返回值 <strong>sqrt</strong> 是否大于 <strong>10.0d</strong> (单位:m/s²)</p><h5 id="条件判断-2-3"><a href="#条件判断-2-3" class="headerlink" title="条件判断 2/3"></a>条件判断 2/3</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">(onShakeListener = <span class="built_in">this</span>.mShakeListener) != <span class="literal">null</span> && onShakeListener != <span class="literal">null</span> </span><br></pre></td></tr></table></figure><p>接下来重点看这两个函数</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="title function_">ShakeListener</span><span class="params">(Context context, <span class="type">long</span> j)</span> {</span><br><span class="line"> <span class="built_in">this</span>.mContext = context;</span><br><span class="line"> <span class="built_in">this</span>.mCheckFrequency = j;</span><br><span class="line"> start();</span><br><span class="line">}</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setOnShakeListener</span><span class="params">(OnShakeListener onShakeListener)</span> {</span><br><span class="line"> <span class="built_in">this</span>.mShakeListener = onShakeListener;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>ShakeListener(Context context, long j) 是 ShakeListener 类的构造函数,传递了两个参数</p><p>在 setOnShakeListener(OnShakeListener onShakeListener) 方法中,this.mShakeListener 被 onShakeListener 赋值过,如果后续 this.mShakeListener 不再被赋值,那么 this.mShakeListener = onShakeListener;</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">synchronized</span> <span class="keyword">void</span> <span class="title function_">listeningShake</span><span class="params">(WVCallBackContext wVCallBackContext, String str)</span> {</span><br><span class="line"> <span class="type">boolean</span> z;</span><br><span class="line"> <span class="type">WVResult</span> <span class="variable">wVResult</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">WVResult</span>();</span><br><span class="line"> <span class="type">long</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">500</span>;</span><br><span class="line"> <span class="type">long</span> <span class="variable">j2</span> <span class="operator">=</span> <span class="number">1000</span>;</span><br><span class="line"> <span class="type">boolean</span> <span class="variable">z2</span> <span class="operator">=</span> <span class="literal">false</span>;</span><br><span class="line"> <span class="keyword">if</span> (TextUtils.isEmpty(str)) {</span><br><span class="line"> z = <span class="literal">false</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> str = URLDecoder.decode(str, <span class="string">"utf-8"</span>);</span><br><span class="line"> } <span class="keyword">catch</span> (Exception unused) {</span><br><span class="line"> TaoLog.m254e(<span class="string">"WVMotion"</span>, <span class="string">"listeningShake: param decode error, param="</span> + str);</span><br><span class="line"> z2 = <span class="literal">true</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="type">JSONObject</span> <span class="variable">jSONObject</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JSONObject</span>(str);</span><br><span class="line"> z = jSONObject.getBoolean(Baggage.Amnet.TURN_ON);</span><br><span class="line"> j = jSONObject.optLong(<span class="string">"frequency"</span>, <span class="number">500L</span>);</span><br><span class="line"> j2 = jSONObject.optLong(<span class="string">"checkFrequency"</span>, <span class="number">1000L</span>);</span><br><span class="line"> } <span class="keyword">catch</span> (JSONException unused2) {</span><br><span class="line"> TaoLog.m254e(<span class="string">"WVMotion"</span>, <span class="string">"listeningShake: param parse to JSON error, param="</span> + str);</span><br><span class="line"> wVResult.setResult(<span class="string">"HY_PARAM_ERR"</span>);</span><br><span class="line"> wVCallBackContext.error(wVResult);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (z2) {</span><br><span class="line"> <span class="keyword">if</span> (TaoLog.getLogStatus()) {</span><br><span class="line"> TaoLog.m263w(<span class="string">"WVMotion"</span>, <span class="string">"listeningShake: isFail"</span>);</span><br><span class="line"> }</span><br><span class="line"> wVCallBackContext.error(wVResult);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (z) {</span><br><span class="line"> TaoLog.m254e(<span class="string">"WVMotion"</span>, <span class="string">"listeningShake: start ..."</span>);</span><br><span class="line"> <span class="type">ShakeListener</span> <span class="variable">shakeListener</span> <span class="operator">=</span> <span class="built_in">this</span>.mShakeListener;</span><br><span class="line"> <span class="keyword">if</span> (shakeListener != <span class="literal">null</span>) {</span><br><span class="line"> shakeListener.stop();</span><br><span class="line"> }</span><br><span class="line"> <span class="type">ShakeListener</span> <span class="variable">shakeListener2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ShakeListener</span>(<span class="built_in">this</span>.mContext, j2);</span><br><span class="line"> <span class="built_in">this</span>.mShakeListener = shakeListener2;</span><br><span class="line"> shakeListener2.setOnShakeListener(<span class="keyword">new</span> <span class="title class_">MyShakeListener</span>(wVCallBackContext, j));</span><br><span class="line"> wVCallBackContext.success(wVResult);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> TaoLog.m254e(<span class="string">"WVMotion"</span>, <span class="string">"listeningShake: stop."</span>);</span><br><span class="line"> <span class="type">Message</span> <span class="variable">message</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Message</span>();</span><br><span class="line"> message.what = <span class="number">1</span>;</span><br><span class="line"> message.obj = wVCallBackContext;</span><br><span class="line"> <span class="type">Handler</span> <span class="variable">handler</span> <span class="operator">=</span> <span class="built_in">this</span>.handler;</span><br><span class="line"> <span class="keyword">if</span> (handler != <span class="literal">null</span>) {</span><br><span class="line"> handler.sendMessage(message);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>在以上片段中,重点看两句代码</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">ShakeListener</span> <span class="variable">shakeListener2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ShakeListener</span>(<span class="built_in">this</span>.mContext, j2); <span class="comment">// ShakeListener类构造函数 ShakeListener(Context context, long j),被调用初始化</span></span><br><span class="line">shakeListener2.setOnShakeListener(<span class="keyword">new</span> <span class="title class_">MyShakeListener</span>(wVCallBackContext, j)); <span class="comment">// setOnShakeListener(OnShakeListener onShakeListener) 被调用</span></span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">long</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">500</span>; <span class="comment">// setOnShakeListener(OnShakeListener onShakeListener)方法参数 OnShakeListener 的第二个参数 j (默认500)</span></span><br><span class="line"><span class="type">long</span> <span class="variable">j2</span> <span class="operator">=</span> <span class="number">1000</span>; <span class="comment">// ShakeListener类构造函数 第二个参数 j2 传递 (默认1000)</span></span><br></pre></td></tr></table></figure><p>这两个值分别默认 500、100,通过 <strong>listeningShake</strong> 方法第二个参数 str 传入的 String 转成 json 字符串判断是否存在,并动态赋值</p><p>继续看判断的条件 4、5、6 </p><h5 id="条件判断-4-5-6"><a href="#条件判断-4-5-6" class="headerlink" title="条件判断 4/5/6"></a>条件判断 4/5/6</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Math.abs(<span class="built_in">this</span>.mLastX) > <span class="number">0.0f</span> && Math.abs(<span class="built_in">this</span>.mLastY) > <span class="number">0.0f</span> && Math.abs(<span class="built_in">this</span>.mLastZ) > <span class="number">0.0f</span></span><br></pre></td></tr></table></figure><p>已知 this.mLastX / this.mLastY / this.mLastZ 分别表示三轴上一次数据<br>可以分析得知,条件 4、5、6 的意义</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Math.abs(<span class="built_in">this</span>.mLastX) > <span class="number">0.0f</span> <span class="comment">// x轴绝对值大于0</span></span><br><span class="line">Math.abs(<span class="built_in">this</span>.mLastY) > <span class="number">0.0f</span> <span class="comment">// y轴绝对值大于0</span></span><br><span class="line">Math.abs(<span class="built_in">this</span>.mLastZ) > <span class="number">0.0f</span> <span class="comment">// z轴绝对值大于0</span></span><br></pre></td></tr></table></figure><p>即条件4、5、6代表三轴的数据的绝对值都要大于0 </p><h2 id="实现案例"><a href="#实现案例" class="headerlink" title="实现案例"></a>实现案例</h2><p>我们按以上的实现方式,模拟实现一个类似的摇一摇跳转广告示例</p><h3 id="ShakeListener-kt"><a href="#ShakeListener-kt" class="headerlink" title="ShakeListener.kt"></a>ShakeListener.kt</h3><figure class="highlight kt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zcwx.sensorshake</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> android.app.Activity</span><br><span class="line"><span class="keyword">import</span> android.content.Context</span><br><span class="line"><span class="keyword">import</span> android.hardware.Sensor</span><br><span class="line"><span class="keyword">import</span> android.hardware.SensorEvent</span><br><span class="line"><span class="keyword">import</span> android.hardware.SensorEventListener</span><br><span class="line"><span class="keyword">import</span> android.hardware.SensorManager</span><br><span class="line"><span class="keyword">import</span> android.util.Log</span><br><span class="line"><span class="keyword">import</span> android.widget.TextView</span><br><span class="line"><span class="keyword">import</span> java.util.Locale</span><br><span class="line"><span class="keyword">import</span> kotlin.math.acos</span><br><span class="line"><span class="keyword">import</span> kotlin.math.sqrt</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ShakeListener</span>(<span class="comment">//上下文</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">val</span> context: Context,</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">val</span> accLog: TextView,</span><br><span class="line">) : SensorEventListener {</span><br><span class="line"></span><br><span class="line"> <span class="comment">//传感器管理器</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">var</span> sensorManager: SensorManager? = <span class="literal">null</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">//传感器</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">var</span> accSensor: Sensor? = <span class="literal">null</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">//重力感应监听器</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">var</span> onShakeListener: OnShakeListener? = <span class="literal">null</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">//手机上一个位置时重力感应坐标</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">var</span> lastX = <span class="number">0f</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">var</span> lastY = <span class="number">0f</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">var</span> lastZ = <span class="number">0f</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">//构造器</span></span><br><span class="line"> <span class="keyword">init</span> {</span><br><span class="line"> <span class="comment">//获得监听对象</span></span><br><span class="line"> start()</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//开始</span></span><br><span class="line"> <span class="keyword">private</span> <span class="function"><span class="keyword">fun</span> <span class="title">start</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="comment">//获得传感器管理器</span></span><br><span class="line"> sensorManager = context.getSystemService(Context.SENSOR_SERVICE) <span class="keyword">as</span> SensorManager</span><br><span class="line"> <span class="keyword">if</span> (sensorManager != <span class="literal">null</span>) {</span><br><span class="line"> <span class="comment">//获得加速度传感器</span></span><br><span class="line"> accSensor = sensorManager?.getDefaultSensor(<span class="number">1</span>)</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//注册</span></span><br><span class="line"> <span class="keyword">if</span> (accSensor != <span class="literal">null</span>) {</span><br><span class="line"> sensorManager?.registerListener(<span class="keyword">this</span>, accSensor, SensorManager.SENSOR_DELAY_NORMAL)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//停止检测</span></span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">stop</span><span class="params">()</span></span> {</span><br><span class="line"> sensorManager?.unregisterListener(<span class="keyword">this</span>)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//摇晃监听接口</span></span><br><span class="line"> <span class="keyword">interface</span> <span class="title class_">OnShakeListener</span> {</span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">onShake</span><span class="params">()</span></span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//设置重力感应监听器</span></span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">setOnShakeListener</span><span class="params">(listener: <span class="type">OnShakeListener</span>?)</span></span> {</span><br><span class="line"> onShakeListener = listener</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//重力感应器感应获得变化数据</span></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onSensorChanged</span><span class="params">(event: <span class="type">SensorEvent</span>)</span></span> {</span><br><span class="line"> <span class="keyword">when</span> (event.sensor.type) {</span><br><span class="line"> <span class="number">1</span> -> {</span><br><span class="line"> <span class="comment">//获得x,y,z坐标</span></span><br><span class="line"> <span class="keyword">val</span> x = event.values[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">val</span> y = event.values[<span class="number">1</span>]</span><br><span class="line"> <span class="keyword">val</span> z = event.values[<span class="number">2</span>]</span><br><span class="line"></span><br><span class="line"> lastX = x</span><br><span class="line"> lastY = y</span><br><span class="line"> lastZ = z</span><br><span class="line"></span><br><span class="line"> <span class="keyword">val</span> speed = String.format (Locale.getDefault(),<span class="string">"%.1f"</span>, sqrt(lastX * lastX + lastY * lastY + lastZ * lastZ),).toDouble()</span><br><span class="line"></span><br><span class="line"> Log.d(<span class="string">"TAG"</span>, <span class="string">"速度:<span class="variable">$speed</span>"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">val</span> str = <span class="string">"加速度\n"</span> +</span><br><span class="line"> <span class="string">"X:\t<span class="subst">${event.values[<span class="number">0</span>]}</span>\n"</span> +</span><br><span class="line"> <span class="string">"Y:\t<span class="subst">${event.values[<span class="number">1</span>]}</span>\n"</span> +</span><br><span class="line"> <span class="string">"Z:\t<span class="subst">${event.values[<span class="number">2</span>]}</span>\n"</span> +</span><br><span class="line"> <span class="string">"sqrt:\t<span class="variable">$speed</span>\n"</span></span><br><span class="line"></span><br><span class="line"> accLog.text = str</span><br><span class="line"></span><br><span class="line"> <span class="comment">//达到速度阀值,发出提示</span></span><br><span class="line"> <span class="keyword">if</span> (speed >= SPEED_SHRES_HOLD) {</span><br><span class="line"> Log.d(<span class="string">"TAG"</span>, <span class="string">"onSensorChanged: 触发摇一摇,跳转广告页面了..."</span>)</span><br><span class="line"> Log.d(<span class="string">"TAG"</span>, <span class="string">"x:<span class="variable">$x</span>,y:<span class="variable">$y</span>,z:<span class="variable">$z</span>"</span>)</span><br><span class="line"> Log.d(<span class="string">"TAG"</span>, <span class="string">"速度:<span class="variable">$speed</span>"</span>)</span><br><span class="line"> onShakeListener!!.onShake()</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onAccuracyChanged</span><span class="params">(sensor: <span class="type">Sensor</span>, accuracy: <span class="type">Int</span>)</span></span> {</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">companion</span> <span class="keyword">object</span> {</span><br><span class="line"> <span class="comment">//速度阈值</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">const</span> <span class="keyword">val</span> SPEED_SHRES_HOLD = <span class="number">15</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="MainActivity-kt"><a href="#MainActivity-kt" class="headerlink" title="MainActivity.kt"></a>MainActivity.kt</h3><figure class="highlight kt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zcwx.sensorshake</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> android.content.Intent</span><br><span class="line"><span class="keyword">import</span> android.net.Uri</span><br><span class="line"><span class="keyword">import</span> android.os.Bundle</span><br><span class="line"><span class="keyword">import</span> android.os.VibrationEffect</span><br><span class="line"><span class="keyword">import</span> android.os.Vibrator</span><br><span class="line"><span class="keyword">import</span> android.os.VibratorManager</span><br><span class="line"><span class="keyword">import</span> android.util.Log</span><br><span class="line"><span class="keyword">import</span> android.widget.Toast</span><br><span class="line"><span class="keyword">import</span> androidx.activity.enableEdgeToEdge</span><br><span class="line"><span class="keyword">import</span> androidx.appcompat.app.AppCompatActivity</span><br><span class="line"><span class="keyword">import</span> androidx.core.view.ViewCompat</span><br><span class="line"><span class="keyword">import</span> androidx.core.view.WindowInsetsCompat</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MainActivity</span> : <span class="type">AppCompatActivity</span>() {</span><br><span class="line"></span><br><span class="line"> <span class="keyword">companion</span> <span class="keyword">object</span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">const</span> <span class="keyword">val</span> TAG = <span class="string">"MainActivity"</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">lateinit</span> <span class="keyword">var</span> shakeListener: ShakeListener</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onCreate</span><span class="params">(savedInstanceState: <span class="type">Bundle</span>?)</span></span> {</span><br><span class="line"> <span class="keyword">super</span>.onCreate(savedInstanceState)</span><br><span class="line"> enableEdgeToEdge()</span><br><span class="line"> setContentView(R.layout.activity_main)</span><br><span class="line"> ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -></span><br><span class="line"> <span class="keyword">val</span> systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())</span><br><span class="line"> v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)</span><br><span class="line"> insets</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> shakeListener = ShakeListener(<span class="keyword">this</span>, findViewById(R.id.tvAccLog)) <span class="comment">//创建一个对象</span></span><br><span class="line"> shakeListener.setOnShakeListener(<span class="keyword">object</span>: ShakeListener.OnShakeListener{</span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onShake</span><span class="params">()</span></span> {</span><br><span class="line"> Toast.makeText(<span class="keyword">this</span><span class="symbol">@MainActivity</span>, <span class="string">"摇一摇,手机摇晃了🫨"</span>, Toast.LENGTH_SHORT).show()</span><br><span class="line"> onVibrator().let {</span><br><span class="line"> openLinkInBrowser()</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onDestroy</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">super</span>.onDestroy()</span><br><span class="line"> shakeListener.stop() <span class="comment">//停止监听</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="function"><span class="keyword">fun</span> <span class="title">openLinkInBrowser</span><span class="params">()</span></span> {</span><br><span class="line"> Log.d(TAG, <span class="string">"openLinkInBrowser: "</span>)</span><br><span class="line"> <span class="keyword">val</span> url = <span class="string">"https://www.apple.com/"</span> <span class="comment">// 要打开的链接地址</span></span><br><span class="line"> <span class="keyword">val</span> intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))</span><br><span class="line"> startActivity(intent)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="function"><span class="keyword">fun</span> <span class="title">onVibrator</span><span class="params">()</span></span> {</span><br><span class="line"> Log.d(TAG, <span class="string">"onVibrator: "</span>)</span><br><span class="line"> <span class="keyword">val</span> vibrator:Vibrator</span><br><span class="line"> <span class="keyword">if</span> (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.S) {</span><br><span class="line"> <span class="keyword">val</span> vibratorManager: VibratorManager = getSystemService(VIBRATOR_MANAGER_SERVICE) <span class="keyword">as</span> VibratorManager</span><br><span class="line"> vibrator= vibratorManager.defaultVibrator</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> vibrator= getSystemService(VIBRATOR_SERVICE) <span class="keyword">as</span> Vibrator</span><br><span class="line"> }</span><br><span class="line"> vibrator.vibrate(VibrationEffect.createOneShot(<span class="number">500</span>, <span class="number">255</span>))</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="AndroidManifest-xml"><a href="#AndroidManifest-xml" class="headerlink" title="AndroidManifest.xml"></a>AndroidManifest.xml</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">uses-permission</span> <span class="attr">android:name</span>=<span class="string">"android.permission.VIBRATE"</span> /></span></span><br></pre></td></tr></table></figure><h3 id="运行"><a href="#运行" class="headerlink" title="运行"></a>运行</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">2024-12-25 14:28:08.830 6734-6734 ShakeListener com.zcwx.sensorshake D x:0.51834464,y:-0.094570965,z:9.829395 speed:9.8</span><br><span class="line">2024-12-25 14:28:09.030 6734-6734 ShakeListener com.zcwx.sensorshake D x:0.5177461,y:-0.091578215,z:9.829993 speed:9.8</span><br><span class="line">2024-12-25 14:28:09.227 6734-6734 ShakeListener com.zcwx.sensorshake D x:0.5177461,y:-0.093373865,z:9.829395 speed:9.8</span><br><span class="line">2024-12-25 14:28:09.424 6734-6734 ShakeListener com.zcwx.sensorshake D x:0.5177461,y:-0.093972415,z:9.831789 speed:9.8</span><br><span class="line">2024-12-25 14:28:09.631 6734-6734 ShakeListener com.zcwx.sensorshake D x:19.515951,y:-0.094570965,z:9.834184 speed:21.9</span><br><span class="line">2024-12-25 14:28:09.636 6734-6734 ShakeListener com.zcwx.sensorshake D onSensorChanged: 触发摇一摇,跳转广告页面了...</span><br><span class="line">2024-12-25 14:28:09.636 6734-6734 ShakeListener com.zcwx.sensorshake D x:19.515951,y:-0.094570965,z:9.834184</span><br><span class="line">2024-12-25 14:28:09.636 6734-6734 ShakeListener com.zcwx.sensorshake D 速度:21.9</span><br><span class="line">2024-12-25 14:28:09.643 6734-6734 MainActivity com.zcwx.sensorshake D onVibrator: </span><br><span class="line">2024-12-25 14:28:09.647 6734-6734 MainActivity com.zcwx.sensorshake D openLinkInBrowser: </span><br><span class="line">2024-12-25 14:28:09.827 6734-6734 ShakeListener com.zcwx.sensorshake D x:0.5177461,y:-0.092176765,z:9.835381 speed:9.8</span><br><span class="line">2024-12-25 14:28:10.024 6734-6734 ShakeListener com.zcwx.sensorshake D x:0.521936,y:-0.093972415,z:9.834782 speed:9.8</span><br></pre></td></tr></table></figure><p><img src="/posts/e3313220/Screenshot_20241225_141909.png"></p><h3 id="合规检测"><a href="#合规检测" class="headerlink" title="合规检测"></a>合规检测</h3><h4 id="检测加速度不小于15m-s²"><a href="#检测加速度不小于15m-s²" class="headerlink" title="检测加速度不小于15m/s²"></a>检测加速度不小于15m/s²</h4><p>假如,现在需要模拟手机摇一摇来测试广告的阀值,检测广告是否合规,只考虑加速度的情况下</p><p>可以通过Frida Hook的方式,模拟加速度数据</p><p>hook_sensor.js</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> isHooked = <span class="literal">false</span>;</span><br><span class="line"><span class="keyword">var</span> <span class="variable constant_">SPEED_SHRES_HOLD</span> = <span class="number">15</span> <span class="comment">// 假定阀值</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">main</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="title class_">Java</span>.<span class="title function_">perform</span>(<span class="keyword">function</span> (<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">var</span> <span class="title class_">Random</span> = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">"java.util.Random"</span>);</span><br><span class="line"> <span class="keyword">var</span> random = <span class="title class_">Random</span>.$new()</span><br><span class="line"> <span class="keyword">var</span> <span class="title class_">SystemSensorManagerSensorEventQueue</span> = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">"android.hardware.SystemSensorManager$SensorEventQueue"</span>);</span><br><span class="line"> <span class="title class_">SystemSensorManagerSensorEventQueue</span>.<span class="property">dispatchSensorEvent</span>.<span class="property">implementation</span> = <span class="keyword">function</span> (<span class="params">type, values, accuracy, timestamp</span>) {</span><br><span class="line"> <span class="keyword">if</span> (type === <span class="number">11</span>) { <span class="comment">// ACCELEROMETER 的值为 11</span></span><br><span class="line"> <span class="keyword">if</span> (!isHooked) {</span><br><span class="line"> isHooked = <span class="literal">true</span>;</span><br><span class="line"> <span class="comment">// 原始的x, y, z值</span></span><br><span class="line"> <span class="keyword">var</span> originalX = values[<span class="number">0</span>];</span><br><span class="line"> <span class="keyword">var</span> originalY = values[<span class="number">1</span>];</span><br><span class="line"> <span class="keyword">var</span> originalZ = values[<span class="number">2</span>];</span><br><span class="line"> <span class="comment">// 计算原始的加速度大小</span></span><br><span class="line"> <span class="keyword">var</span> originalSpeed = <span class="title class_">Math</span>.<span class="title function_">sqrt</span>(<span class="title class_">Math</span>.<span class="title function_">pow</span>(originalX, <span class="number">2.0</span>) + <span class="title class_">Math</span>.<span class="title function_">pow</span>(originalY, <span class="number">2.0</span>) + <span class="title class_">Math</span>.<span class="title function_">pow</span>(originalZ, <span class="number">2.0</span>));</span><br><span class="line"> <span class="comment">// 打印原始值</span></span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"\n原始值: [ x="</span> + originalX + <span class="string">", y="</span> + originalY + <span class="string">", z="</span> + originalZ + <span class="string">"] speed="</span> + originalSpeed + <span class="string">" m/s^2"</span>);</span><br><span class="line"> <span class="comment">// 模拟摇一摇操作,设置加速度值</span></span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"\n模拟摇一摇操作,设置加速度值"</span>);</span><br><span class="line"> <span class="comment">// 随机选择x, y, z中的一个值进行调整</span></span><br><span class="line"> <span class="keyword">var</span> indexToAdjust = random.<span class="title function_">nextInt</span>(<span class="number">3</span>);</span><br><span class="line"> <span class="keyword">var</span> newValues = [originalX, originalY, originalZ];</span><br><span class="line"> <span class="keyword">if</span> (<span class="variable constant_">SPEED_SHRES_HOLD</span> < <span class="number">9.8</span>) <span class="variable constant_">SPEED_SHRES_HOLD</span> = <span class="number">9.8</span>;</span><br><span class="line"> <span class="comment">// 随机生成新的值</span></span><br><span class="line"> <span class="keyword">if</span> (indexToAdjust == <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">var</span> xSquared = (<span class="title class_">Math</span>.<span class="title function_">pow</span>(<span class="variable constant_">SPEED_SHRES_HOLD</span>, <span class="number">2.0</span>)) - (<span class="title class_">Math</span>.<span class="title function_">pow</span>(newValues[<span class="number">1</span>], <span class="number">2.0</span>) + <span class="title class_">Math</span>.<span class="title function_">pow</span>(newValues[<span class="number">2</span>], <span class="number">2.0</span>));</span><br><span class="line"> <span class="keyword">if</span> (xSquared < <span class="number">0</span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(<span class="string">"Cannot generate valid acceleration X values."</span>);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> newValues[<span class="number">0</span>] = <span class="title class_">Math</span>.<span class="title function_">sqrt</span>(xSquared);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (indexToAdjust == <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">var</span> ySquared = (<span class="title class_">Math</span>.<span class="title function_">pow</span>(<span class="variable constant_">SPEED_SHRES_HOLD</span>, <span class="number">2.0</span>)) - (<span class="title class_">Math</span>.<span class="title function_">pow</span>(newValues[<span class="number">0</span>], <span class="number">2.0</span>) + <span class="title class_">Math</span>.<span class="title function_">pow</span>(newValues[<span class="number">2</span>], <span class="number">2.0</span>));</span><br><span class="line"> <span class="keyword">if</span> (ySquared < <span class="number">0</span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(<span class="string">"Cannot generate valid acceleration Y values."</span>);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> newValues[<span class="number">1</span>] = <span class="title class_">Math</span>.<span class="title function_">sqrt</span>(ySquared);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (indexToAdjust == <span class="number">2</span>) {</span><br><span class="line"> <span class="keyword">var</span> zSquared = (<span class="title class_">Math</span>.<span class="title function_">pow</span>(<span class="variable constant_">SPEED_SHRES_HOLD</span>, <span class="number">2.0</span>)) - (<span class="title class_">Math</span>.<span class="title function_">pow</span>(newValues[<span class="number">0</span>], <span class="number">2.0</span>) + <span class="title class_">Math</span>.<span class="title function_">pow</span>(newValues[<span class="number">1</span>], <span class="number">2.0</span>));</span><br><span class="line"> <span class="keyword">if</span> (zSquared < <span class="number">0</span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(<span class="string">"Cannot generate valid acceleration Z values."</span>);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> newValues[<span class="number">2</span>] = <span class="title class_">Math</span>.<span class="title function_">sqrt</span>(zSquared);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 取出新的值</span></span><br><span class="line"> <span class="keyword">var</span> newX = newValues[<span class="number">0</span>];</span><br><span class="line"> <span class="keyword">var</span> newY = newValues[<span class="number">1</span>];</span><br><span class="line"> <span class="keyword">var</span> newZ = newValues[<span class="number">2</span>];</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 计算新的加速度</span></span><br><span class="line"> <span class="keyword">var</span> newSpeed = <span class="title class_">Math</span>.<span class="title function_">sqrt</span>(<span class="title class_">Math</span>.<span class="title function_">pow</span>(newX, <span class="number">2.0</span>) + <span class="title class_">Math</span>.<span class="title function_">pow</span>(newY, <span class="number">2.0</span>) + <span class="title class_">Math</span>.<span class="title function_">pow</span>(newZ, <span class="number">2.0</span>));</span><br><span class="line"> <span class="comment">// 设置新的加速度值</span></span><br><span class="line"> values[<span class="number">0</span>] = newX;</span><br><span class="line"> values[<span class="number">1</span>] = newY;</span><br><span class="line"> values[<span class="number">2</span>] = newZ;</span><br><span class="line"> <span class="comment">// 打印新的值和新的加速度大小</span></span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"\n新的值: [ x="</span> + newX + <span class="string">", y="</span> + newY + <span class="string">", z="</span> + newZ + <span class="string">"] speed="</span> + newSpeed + <span class="string">" m/s^2"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">dispatchSensorEvent</span>.<span class="title function_">call</span>(<span class="variable language_">this</span>, type, values, accuracy, timestamp);</span><br><span class="line"> };</span><br><span class="line"> });</span><br><span class="line">}</span><br><span class="line"><span class="built_in">setTimeout</span>(main, <span class="number">5000</span>); <span class="comment">// 执行脚本,5秒后触发main函数</span></span><br></pre></td></tr></table></figure><p>执行hook 脚本 hook_sensor.js,输出结果</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">(.<span class="property">venv</span>) ~<span class="regexp">/frida-agent-example $ frida -U -f com.zcwx.sensorshake -l ./</span>android/hook_sensor.<span class="property">js</span></span><br><span class="line"> ____</span><br><span class="line"> / _ | <span class="title class_">Frida</span> <span class="number">16.4</span><span class="number">.8</span> - A world-<span class="keyword">class</span> <span class="title class_">dynamic</span> instrumentation toolkit</span><br><span class="line"> | (_| |</span><br><span class="line"> > _ | <span class="title class_">Commands</span>:</span><br><span class="line"> <span class="regexp">/_/</span> |_| help -> <span class="title class_">Displays</span> the help system</span><br><span class="line"> . . . . object? -> <span class="title class_">Display</span> information about <span class="string">'object'</span></span><br><span class="line"> . . . . exit/quit -> <span class="title class_">Exit</span></span><br><span class="line"> . . . .</span><br><span class="line"> . . . . <span class="title class_">More</span> info at <span class="attr">https</span>:<span class="comment">//frida.re/docs/home/</span></span><br><span class="line"> . . . .</span><br><span class="line"> . . . . <span class="title class_">Connected</span> to <span class="title class_">LE2110</span> (id=988b0e34)</span><br><span class="line"><span class="title class_">Spawned</span> <span class="string">`com.zcwx.sensorshake`</span>. <span class="title class_">Resuming</span> main thread! </span><br><span class="line">[<span class="title class_">LE2110</span>::com.<span class="property">zcwx</span>.<span class="property">sensorshake</span> ]-></span><br><span class="line">原始值: [ x=<span class="number">0.33279404044151306</span>, y=<span class="number">8.785523414611816</span>, z=<span class="number">4.349067211151123</span>] speed=<span class="number">9.80869813732463</span> m/s^<span class="number">2</span></span><br><span class="line"></span><br><span class="line">模拟摇一摇操作,设置加速度值</span><br><span class="line"></span><br><span class="line">新的值: [ x=<span class="number">11.3534220710849</span>, y=<span class="number">8.785523414611816</span>, z=<span class="number">4.349067211151123</span>] speed=<span class="number">15.000000000000002</span> m/s^<span class="number">2</span></span><br><span class="line">[<span class="title class_">LE2110</span>::com.<span class="property">zcwx</span>.<span class="property">sensorshake</span> ]-></span><br></pre></td></tr></table></figure><p>静态情况下,加速度为9.8 m/s²,通过Hook的方式,模拟出加速度为15+ m/s²,从而自动触发阀值,跳转模拟的广告页面</p>]]></content>
<summary type="html"><p><img src="/posts/e3313220/65d74dee-3a8a-4b8b-abf8-b8091e4e7a59.jpeg" alt="alt text"></p></summary>
<category term="Android" scheme="https://shoewann0402.github.io/categories/Android/"/>
<category term="逆向分析" scheme="https://shoewann0402.github.io/tags/%E9%80%86%E5%90%91%E5%88%86%E6%9E%90/"/>
<category term="摇一摇" scheme="https://shoewann0402.github.io/tags/%E6%91%87%E4%B8%80%E6%91%87/"/>
<category term="广告" scheme="https://shoewann0402.github.io/tags/%E5%B9%BF%E5%91%8A/"/>
<category term="frida" scheme="https://shoewann0402.github.io/tags/frida/"/>
</entry>
<entry>
<title>在 HarmonyOS 中如何使用 Native C++</title>
<link href="https://shoewann0402.github.io/posts/92e22166.html"/>
<id>https://shoewann0402.github.io/posts/92e22166.html</id>
<published>2024-12-19T01:28:27.000Z</published>
<updated>2024-12-19T03:19:46.631Z</updated>
<content type="html"><![CDATA[<p><img src="/posts/92e22166/image.png"></p><span id="more"></span><h2 id="环境"><a href="#环境" class="headerlink" title="环境"></a>环境</h2><blockquote><ul><li>工具: <a href="https://developer.huawei.com/consumer/cn/deveco-studio/">HUAWEI DevEco Studio</a></li></ul></blockquote><p><img src="/posts/92e22166/about-deveco-studio.png"></p><blockquote><ul><li>设备: 支持HarmonyOS NEXT 的设备(真机/模拟器)</li></ul></blockquote><h2 id="创建项目"><a href="#创建项目" class="headerlink" title="创建项目"></a>创建项目</h2><p>新建一个项目,选择 [Native C++] 的模版</p><p><img src="/posts/92e22166/image.png"></p><p>然后生成一个默认的工程</p><blockquote><p>API 版本 : <strong>5.0.1 (API 13)</strong></p></blockquote><p><img src="/posts/92e22166/default_project.png"></p><h2 id="分析项目"><a href="#分析项目" class="headerlink" title="分析项目"></a>分析项目</h2><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { hilog } <span class="keyword">from</span> <span class="string">'@kit.PerformanceAnalysisKit'</span>;</span><br><span class="line"><span class="keyword">import</span> testNapi <span class="keyword">from</span> <span class="string">'libentry.so'</span>;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Entry</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line">struct <span class="title class_">Index</span> {</span><br><span class="line"> <span class="meta">@State</span> <span class="attr">message</span>: <span class="built_in">string</span> = <span class="string">'Hello World'</span>;</span><br><span class="line"></span><br><span class="line"> <span class="title function_">build</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="title class_">Row</span>() {</span><br><span class="line"> <span class="title class_">Column</span>() {</span><br><span class="line"> <span class="title class_">Text</span>(<span class="variable language_">this</span>.<span class="property">message</span>)</span><br><span class="line"> .<span class="title function_">fontSize</span>(<span class="number">50</span>)</span><br><span class="line"> .<span class="title function_">fontWeight</span>(<span class="title class_">FontWeight</span>.<span class="property">Bold</span>)</span><br><span class="line"> .<span class="title function_">onClick</span>(<span class="function">() =></span> {</span><br><span class="line"> hilog.<span class="title function_">info</span>(<span class="number">0x0000</span>, <span class="string">'testTag'</span>, <span class="string">'Test NAPI 2 + 3 = %{public}d'</span>, testNapi.<span class="title function_">add</span>(<span class="number">2</span>, <span class="number">3</span>));</span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> .<span class="title function_">width</span>(<span class="string">'100%'</span>)</span><br><span class="line"> }</span><br><span class="line"> .<span class="title function_">height</span>(<span class="string">'100%'</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>分析这个默认工程,根据index.ets代码显示,是在Native下注册是add的计算方法,通过传入两个参数计算和,文中传入了 2 和 3,当点击界面上的Hello world 文本时调用计算方法,日志输出如下</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">12-19 55333-55333 A00000/com..../testTag com.xw....lication I Test NAPI 2 + 3 = 5</span><br></pre></td></tr></table></figure><p>点击16行,testNapi.add() 方法跳过去,在 <strong>index.d.ts</strong> 中定义了接口方法</p><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="attr">add</span>: <span class="function">(<span class="params"><span class="attr">a</span>: <span class="built_in">number</span>, <span class="attr">b</span>: <span class="built_in">number</span></span>) =></span> <span class="built_in">number</span>;</span><br></pre></td></tr></table></figure><p>这个 testNapi 又是通过 <strong>libentry.so</strong> 引入的</p><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> testNapi <span class="keyword">from</span> <span class="string">'libentry.so'</span>;</span><br></pre></td></tr></table></figure><p>在 <strong>CMakeLists</strong> 15行 我们可以链接库的地方</p><p><img src="/posts/92e22166/default_project_cmake.png"></p><p>接着打开 cpp 目录下的 <strong>napi_init.cpp</strong> 文件</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"napi/native_api.h"</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">static</span> napi_value <span class="title">Add</span><span class="params">(napi_env env, napi_callback_info info)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="type">size_t</span> argc = <span class="number">2</span>;</span><br><span class="line"> napi_value args[<span class="number">2</span>] = {<span class="literal">nullptr</span>};</span><br><span class="line"></span><br><span class="line"> <span class="built_in">napi_get_cb_info</span>(env, info, &argc, args , <span class="literal">nullptr</span>, <span class="literal">nullptr</span>);</span><br><span class="line"></span><br><span class="line"> napi_valuetype valuetype0;</span><br><span class="line"> <span class="built_in">napi_typeof</span>(env, args[<span class="number">0</span>], &valuetype0);</span><br><span class="line"></span><br><span class="line"> napi_valuetype valuetype1;</span><br><span class="line"> <span class="built_in">napi_typeof</span>(env, args[<span class="number">1</span>], &valuetype1);</span><br><span class="line"></span><br><span class="line"> <span class="type">double</span> value0;</span><br><span class="line"> <span class="built_in">napi_get_value_double</span>(env, args[<span class="number">0</span>], &value0);</span><br><span class="line"></span><br><span class="line"> <span class="type">double</span> value1;</span><br><span class="line"> <span class="built_in">napi_get_value_double</span>(env, args[<span class="number">1</span>], &value1);</span><br><span class="line"></span><br><span class="line"> napi_value sum;</span><br><span class="line"> <span class="built_in">napi_create_double</span>(env, value0 + value1, &sum);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> sum;</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function">EXTERN_C_START</span></span><br><span class="line"><span class="function"><span class="type">static</span> napi_value <span class="title">Init</span><span class="params">(napi_env env, napi_value exports)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> napi_property_descriptor desc[] = {</span><br><span class="line"> { <span class="string">"add"</span>, <span class="literal">nullptr</span>, Add, <span class="literal">nullptr</span>, <span class="literal">nullptr</span>, <span class="literal">nullptr</span>, napi_default, <span class="literal">nullptr</span> }</span><br><span class="line"> };</span><br><span class="line"> <span class="built_in">napi_define_properties</span>(env, exports, <span class="built_in">sizeof</span>(desc) / <span class="built_in">sizeof</span>(desc[<span class="number">0</span>]), desc);</span><br><span class="line"> <span class="keyword">return</span> exports;</span><br><span class="line">}</span><br><span class="line">EXTERN_C_END</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> napi_module demoModule = {</span><br><span class="line"> .nm_version = <span class="number">1</span>,</span><br><span class="line"> .nm_flags = <span class="number">0</span>,</span><br><span class="line"> .nm_filename = <span class="literal">nullptr</span>,</span><br><span class="line"> .nm_register_func = Init,</span><br><span class="line"> .nm_modname = <span class="string">"entry"</span>,</span><br><span class="line"> .nm_priv = ((<span class="type">void</span>*)<span class="number">0</span>),</span><br><span class="line"> .reserved = { <span class="number">0</span> },</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">extern</span> <span class="string">"C"</span> __attribute__((constructor)) <span class="function"><span class="type">void</span> <span class="title">RegisterEntryModule</span><span class="params">(<span class="type">void</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="built_in">napi_module_register</span>(&demoModule);</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>按照以上的使用流程,接下来实现一个类似的示例</p><h2 id="修改项目"><a href="#修改项目" class="headerlink" title="修改项目"></a>修改项目</h2><blockquote><p>以下通过C API 获取设备信息 <a href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V13/_device_info-V13">DeviceInfo</a></p></blockquote><h3 id="链接"><a href="#链接" class="headerlink" title="链接"></a>链接</h3><p><strong>CMakeList.txt</strong></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># the minimum version of CMake.</span></span><br><span class="line"><span class="built_in">cmake_minimum_required</span>(VERSION <span class="number">3.5</span><span class="number">.0</span>)</span><br><span class="line"><span class="built_in">project</span>(HMBehavior)</span><br><span class="line"></span><br><span class="line"><span class="built_in">set</span>(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(DEFINED PACKAGE_FIND_FILE)</span><br><span class="line"> <span class="built_in">include</span>(${PACKAGE_FIND_FILE})</span><br><span class="line"><span class="built_in">endif</span>()</span><br><span class="line"></span><br><span class="line"><span class="built_in">include_directories</span>(${NATIVERENDER_ROOT_PATH}</span><br><span class="line"> ${NATIVERENDER_ROOT_PATH}/include)</span><br><span class="line"></span><br><span class="line"><span class="built_in">add_library</span>(entry SHARED napi_init.cpp)</span><br><span class="line"><span class="built_in">target_link_libraries</span>(entry PUBLIC libace_napi.z.so)</span><br><span class="line"># 设备信息</span><br><span class="line"><span class="built_in">target_link_libraries</span>(entry PUBLIC libdeviceinfo_ndk.z.so)</span><br></pre></td></tr></table></figure><h3 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h3><p>在 <strong>napi_init.cpp</strong> 里定义一个函数 <strong>GetDeviceInfo</strong>,实现具体设备信息获取的逻辑</p><p>导包</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"napi/native_api.h"</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">"deviceinfo.h"</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><cstdlib></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><cstring></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><string></span></span></span><br></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 获取设备信息</span></span><br><span class="line"><span class="comment"> * @param env</span></span><br><span class="line"><span class="comment"> * @param </span></span><br><span class="line"><span class="comment"> * @return</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="type">static</span> napi_value <span class="title">GetDeviceInfo</span><span class="params">(napi_env env, napi_callback_info)</span> </span>{</span><br><span class="line"></span><br><span class="line"> std::string deviceType = <span class="string">"设备类型: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetDeviceType</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string manufacture = <span class="string">"设备制造商: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetManufacture</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string brand = <span class="string">"设备设备品牌: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetBrand</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string marketName = <span class="string">"外部产品系列: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetMarketName</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string productSeries = <span class="string">"产品系列: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetProductSeries</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string productModel = <span class="string">"认证型号: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetProductModel</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string softwareModel = <span class="string">"内部软件子型号: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetSoftwareModel</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string hardwareModel = <span class="string">"硬件版本号: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetHardwareModel</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string bootloaderVersion = <span class="string">"Bootloader版本号: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetBootloaderVersion</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string abiList = <span class="string">"应用二进制接口(Abi): "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetAbiList</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string securityPatchTag = <span class="string">"安全补丁级别: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetSecurityPatchTag</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string displayVersion = <span class="string">"产品版本: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetDisplayVersion</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string IncrementalVersion = <span class="string">"差异版本: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetIncrementalVersion</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string OSReleaseType = <span class="string">"系统的发布类型: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetOsReleaseType</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string OSFullName = <span class="string">"完整的系统版本名: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetOSFullName</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string sdkApiVersion = <span class="string">"系统软件API版本: "</span> + std::<span class="built_in">to_string</span>(<span class="built_in">OH_GetSdkApiVersion</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string firstApiVersion = <span class="string">"首个版本系统软件API版本: "</span> + std::<span class="built_in">to_string</span>(<span class="built_in">OH_GetFirstApiVersion</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string versionId = <span class="string">"版本ID: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetVersionId</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string buildType = <span class="string">"系统的构建类型: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetBuildType</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string buildUser = <span class="string">"系统的构建用户: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetBuildUser</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string buildHost = <span class="string">"系统的构建主机: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetBuildHost</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string buildTime = <span class="string">"完整系统的构建时间: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetBuildTime</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string buildRootHash = <span class="string">"系统的构建版本Hash: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetBuildRootHash</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string distributionOSName = <span class="string">"ISV发行系统版本名称: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetDistributionOSName</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string distributionOSVersion = <span class="string">"ISV发行版系统版本号: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetDistributionOSVersion</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string distributionOSApiVersion =<span class="string">"ISV发行版系统api版本: "</span> + std::<span class="built_in">to_string</span>(<span class="built_in">OH_GetDistributionOSApiVersion</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"> std::string distributionOSReleaseType =<span class="string">"ISV发行版系统类型: "</span> + std::<span class="built_in">string</span>(<span class="built_in">OH_GetDistributionOSReleaseType</span>()) + <span class="string">"\n"</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 获取每个属性的长度</span></span><br><span class="line"> <span class="type">size_t</span> length1 = <span class="built_in">strlen</span>(deviceType.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length2 = <span class="built_in">strlen</span>(manufacture.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length3 = <span class="built_in">strlen</span>(brand.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length4 = <span class="built_in">strlen</span>(marketName.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length5 = <span class="built_in">strlen</span>(productSeries.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length6 = <span class="built_in">strlen</span>(productModel.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length7 = <span class="built_in">strlen</span>(softwareModel.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length8 = <span class="built_in">strlen</span>(hardwareModel.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length9 = <span class="built_in">strlen</span>(bootloaderVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length10 = <span class="built_in">strlen</span>(abiList.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length11 = <span class="built_in">strlen</span>(securityPatchTag.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length12 = <span class="built_in">strlen</span>(displayVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length13 = <span class="built_in">strlen</span>(IncrementalVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length14 = <span class="built_in">strlen</span>(OSReleaseType.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length15 = <span class="built_in">strlen</span>(OSFullName.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length16 = <span class="built_in">strlen</span>(sdkApiVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length17 = <span class="built_in">strlen</span>(firstApiVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length18 = <span class="built_in">strlen</span>(versionId.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length19 = <span class="built_in">strlen</span>(buildType.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length20 = <span class="built_in">strlen</span>(buildUser.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length21 = <span class="built_in">strlen</span>(buildHost.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length22 = <span class="built_in">strlen</span>(buildTime.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length23 = <span class="built_in">strlen</span>(buildRootHash.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length24 = <span class="built_in">strlen</span>(distributionOSName.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length25 = <span class="built_in">strlen</span>(distributionOSVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length26 = <span class="built_in">strlen</span>(distributionOSApiVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="type">size_t</span> length27 = <span class="built_in">strlen</span>(distributionOSReleaseType.<span class="built_in">c_str</span>());</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 计算拼接后的长度</span></span><br><span class="line"> <span class="type">size_t</span> resultLength = length1 + length2 + length3 + length4 + length5 + length6 + length7 + length8 + length9 +</span><br><span class="line"> length10 + length11 + length12 + length13 + length14 + length15 + length16 + length17 +</span><br><span class="line"> length18 + length19 + length20 + length21 + length22 + length23 + length24 + length25 +</span><br><span class="line"> length26 + length27;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 分配内存以存储拼接后的字符串</span></span><br><span class="line"> <span class="type">char</span> *resultStr = (<span class="type">char</span> *)<span class="built_in">malloc</span>(resultLength + <span class="number">1</span>);</span><br><span class="line"> <span class="comment">// 拼接字符串</span></span><br><span class="line"> <span class="built_in">strcpy</span>(resultStr, deviceType.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, manufacture.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, brand.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, marketName.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, productSeries.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, productModel.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, softwareModel.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, hardwareModel.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, bootloaderVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, abiList.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, securityPatchTag.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, displayVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, IncrementalVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, OSReleaseType.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, OSFullName.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, sdkApiVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, firstApiVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, versionId.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, buildType.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, buildUser.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, buildHost.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, buildTime.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, buildRootHash.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, distributionOSName.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, distributionOSVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, distributionOSApiVersion.<span class="built_in">c_str</span>());</span><br><span class="line"> <span class="built_in">strcat</span>(resultStr, distributionOSReleaseType.<span class="built_in">c_str</span>());</span><br><span class="line"></span><br><span class="line"> napi_value result;</span><br><span class="line"> <span class="built_in">napi_create_string_utf8</span>(env, resultStr, resultLength, &result);</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">EXTERN_C_START</span></span><br><span class="line"><span class="function"><span class="type">static</span> napi_value <span class="title">Init</span><span class="params">(napi_env env, napi_value exports)</span> </span>{</span><br><span class="line"> </span><br><span class="line"> napi_property_descriptor desc[] = {</span><br><span class="line"> <span class="comment">// 设备信息</span></span><br><span class="line"> {<span class="string">"getDeviceInfo"</span>, <span class="literal">nullptr</span>, GetDeviceInfo, <span class="literal">nullptr</span>, <span class="literal">nullptr</span>, <span class="literal">nullptr</span>, napi_default, <span class="literal">nullptr</span>}</span><br><span class="line"> };</span><br><span class="line"> <span class="built_in">napi_define_properties</span>(env, exports, <span class="built_in">sizeof</span>(desc) / <span class="built_in">sizeof</span>(desc[<span class="number">0</span>]), desc);</span><br><span class="line"> <span class="keyword">return</span> exports;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="定义模块"><a href="#定义模块" class="headerlink" title="定义模块"></a>定义模块</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">EXTERN_C_END</span><br><span class="line"><span class="type">static</span> napi_module demoModule = {</span><br><span class="line"> .nm_version = <span class="number">1</span>,</span><br><span class="line"> .nm_flags = <span class="number">0</span>,</span><br><span class="line"> .nm_filename = <span class="literal">nullptr</span>,</span><br><span class="line"> .nm_register_func = Init,</span><br><span class="line"> .nm_modname = <span class="string">"entry"</span>,</span><br><span class="line"> .nm_priv = ((<span class="type">void</span> *)<span class="number">0</span>),</span><br><span class="line"> .reserved = {<span class="number">0</span>},</span><br><span class="line">};</span><br></pre></td></tr></table></figure><h3 id="注册模块"><a href="#注册模块" class="headerlink" title="注册模块"></a>注册模块</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">extern</span> <span class="string">"C"</span> __attribute__((constructor)) <span class="function"><span class="type">void</span> <span class="title">RegisterEntryModule</span><span class="params">(<span class="type">void</span>)</span> </span>{ <span class="built_in">napi_module_register</span>(&demoModule); }</span><br></pre></td></tr></table></figure><h3 id="定义调用函数"><a href="#定义调用函数" class="headerlink" title="定义调用函数"></a>定义调用函数</h3><p><strong>index.d.ts</strong></p><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="attr">getDeviceInfo</span>: <span class="function">() =></span> <span class="built_in">string</span>;</span><br></pre></td></tr></table></figure><h3 id="引入"><a href="#引入" class="headerlink" title="引入"></a>引入</h3><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { getDeviceInfo } <span class="keyword">from</span> <span class="string">'libentry.so'</span>;</span><br></pre></td></tr></table></figure><h3 id="调用"><a href="#调用" class="headerlink" title="调用"></a>调用</h3><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">val deviceinfo = <span class="title function_">getDeviceInfo</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">error</span>(deviceinfo);</span><br></pre></td></tr></table></figure><h2 id="运行项目"><a href="#运行项目" class="headerlink" title="运行项目"></a>运行项目</h2><h3 id="输出"><a href="#输出" class="headerlink" title="输出"></a>输出</h3><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">12</span>-<span class="number">19</span> <span class="number">11</span>:<span class="number">08</span>:<span class="number">10.384</span> <span class="number">21645</span>-<span class="number">21645</span> <span class="variable constant_">A03D00</span>/com.../<span class="variable constant_">JSAPP</span> com.<span class="property">xw</span>....<span class="property">lication</span> E 设备类型: phone, 厂家:<span class="variable constant_">HUAWEI</span>, 品牌:<span class="variable constant_">HUAWEI</span>, 外部产品系列:<span class="variable constant_">HUAWEI</span> <span class="title class_">Mate</span> <span class="number">60</span>, 产品系列:<span class="variable constant_">BRA</span>, 认证型号:<span class="variable constant_">BRA</span>-<span class="title class_">AL00</span>, 内部软件子型号:<span class="variable constant_">BRA</span>-<span class="title class_">AL00</span>, 硬件版本号:<span class="title class_">HL1FLSM</span>, 硬件<span class="title class_">Profile</span>:<span class="keyword">default</span>, <span class="title class_">Bootloader</span>版本号:bootloader, 应用二进制接口(<span class="title class_">Abi</span>)列表:arm64-v8a, 安全补丁级别:<span class="number">2024</span>/<span class="number">11</span>/<span class="number">01</span>, 产品版本:<span class="variable constant_">BRA</span>-<span class="title class_">AL00</span> <span class="number">5.0</span><span class="number">.0</span><span class="number">.110</span>(<span class="title class_">SP6C</span>00E107R4P22), 差异版本号:<span class="keyword">default</span>, 系统的发布类型:<span class="title class_">Beta3</span>, 系统版本:<span class="title class_">OpenHarmony</span>-<span class="number">5.0</span><span class="number">.1</span><span class="number">.107</span>(<span class="title class_">Beta3</span>), <span class="title class_">Major</span>版本号:<span class="number">5</span>, <span class="title class_">Senior</span>版本号:<span class="number">0</span>, <span class="title class_">Feature</span>版本号:<span class="number">1</span>, <span class="title class_">Build</span>版本号:<span class="number">107</span>, 系统软件<span class="variable constant_">API</span>版本:<span class="number">13</span>, 首个版本系统软件<span class="variable constant_">API</span>版本:<span class="number">1</span>, 版本<span class="variable constant_">ID</span>:phone/<span class="variable constant_">HUAWEI</span>/<span class="variable constant_">HUAWEI</span>/<span class="variable constant_">BRA</span>/<span class="title class_">OpenHarmony</span>-<span class="number">5.0</span><span class="number">.1</span><span class="number">.107</span>(<span class="title class_">Beta3</span>)/<span class="variable constant_">BRA</span>-<span class="title class_">AL00</span>/<span class="variable constant_">BRA</span>-<span class="title class_">AL00</span>/<span class="number">13</span>/<span class="keyword">default</span>/<span class="keyword">default</span>, 构建类型:<span class="keyword">default</span>, 构建用户:<span class="keyword">default</span>, 构建主机:<span class="keyword">default</span>, 构建时间:<span class="keyword">default</span>, 构建版本<span class="title class_">Hash</span>:<span class="keyword">default</span>, 发行版系统名称:, 发行版系统版本号:<span class="number">5.0</span><span class="number">.0</span>, 发行版系统api版本:<span class="number">50001</span>, 发行版系统api版本名称:<span class="number">5.0</span><span class="number">.1</span>, 发行版系统类型:<span class="title class_">Beta3</span>, 开发者匿名设备标识符(<span class="variable constant_">ODID</span>): 2699128d-<span class="number">5975</span>-<span class="number">8985</span>-8af4-bb30ce52....</span><br></pre></td></tr></table></figure><h2 id="效果图"><a href="#效果图" class="headerlink" title="效果图"></a>效果图</h2><p><img src="/posts/92e22166/demo_output_result.png" alt="alt text"></p>]]></content>
<summary type="html"><p><img src="/posts/92e22166/image.png"></p></summary>
<category term="HarmonyOS" scheme="https://shoewann0402.github.io/categories/HarmonyOS/"/>
<category term="HarmonyOS" scheme="https://shoewann0402.github.io/tags/HarmonyOS/"/>
<category term="Native" scheme="https://shoewann0402.github.io/tags/Native/"/>
<category term="so" scheme="https://shoewann0402.github.io/tags/so/"/>
<category term="cmake" scheme="https://shoewann0402.github.io/tags/cmake/"/>
</entry>
<entry>
<title>iOS 16 设备如何越狱</title>
<link href="https://shoewann0402.github.io/posts/b3a0121c.html"/>
<id>https://shoewann0402.github.io/posts/b3a0121c.html</id>
<published>2024-12-18T07:37:45.000Z</published>
<updated>2024-12-19T01:17:04.506Z</updated>
<content type="html"><![CDATA[<p><img src="/posts/b3a0121c/image.png"></p><span id="more"></span><h2 id="环境"><a href="#环境" class="headerlink" title="环境"></a>环境</h2><blockquote><ul><li>工具: <a href="https://palera.in/">Palera1n</a> (A8 ~ A11)</li><li>设备: iPhone 8 (A11) 、iOS 16.7.10</li></ul></blockquote><h2 id="越狱"><a href="#越狱" class="headerlink" title="越狱"></a>越狱</h2><blockquote><ul><li>无根越狱: palera1n -l (rootless)</li><li>有根越狱: palera1n -f (rootful)</li></ul></blockquote><p>这里我们使用有根越狱: <strong>palera1n -f (rootful)</strong> 的方式</p><h3 id="创建有根越狱-fakeFS"><a href="#创建有根越狱-fakeFS" class="headerlink" title="创建有根越狱 fakeFS"></a>创建有根越狱 fakeFS</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line">$ palera1n -f -c</span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># palera1n: v2.0.2 </span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># ======== Made by =======</span></span><br><span class="line"><span class="comment"># Made by: Nick Chan, Ploosh, Khcrysalis, Mineek, staturnz, kok3shidoll, HAHALOSAH </span></span><br><span class="line"><span class="comment"># ======== Thanks to =======</span></span><br><span class="line"><span class="comment"># Thanks to: llsc12, Nebula, Lrdsnow, nikias (libimobiledevice),</span></span><br><span class="line"><span class="comment"># checkra1n team (Siguza, axi0mx, littlelailo et al.),</span></span><br><span class="line"><span class="comment"># Procursus Team (Hayden Seay, Cameron Katri, Keto et.al)</span></span><br><span class="line"><span class="comment"># ==========================</span></span><br><span class="line"></span><br><span class="line"> - [12/18/24 14:11:14] <Info>: Waiting <span class="keyword">for</span> devices</span><br><span class="line"> - [12/18/24 14:11:15] <Info>: Entering recovery mode</span><br><span class="line"> - [12/18/24 14:11:25] <Info>: Press Enter when ready <span class="keyword">for</span> DFU mode</span><br><span class="line"></span><br><span class="line">Hold volume down + side button (0)</span><br><span class="line">Hold volume down button (3)</span><br><span class="line"> - [12/18/24 14:11:39] <Info>: Device entered DFU mode successfully</span><br><span class="line"> - [12/18/24 14:11:40] <Info>: About to execute checkra1n</span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Checkra1n 0.1337.3</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Proudly written in nano</span></span><br><span class="line"><span class="comment"># (c) 2019-2023 Kim Jong Cracks</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#======== Made by =======</span></span><br><span class="line"><span class="comment"># argp, axi0mx, danyl931, jaywalker, kirb, littlelailo, nitoTV</span></span><br><span class="line"><span class="comment"># never_released, nullpixel, pimskeks, qwertyoruiop, sbingner, siguza</span></span><br><span class="line"><span class="comment">#======== Thanks to =======</span></span><br><span class="line"><span class="comment"># haifisch, jndok, jonseals, xerub, lilstevie, psychotea, sferrini</span></span><br><span class="line"><span class="comment"># Cellebrite (ih8sn0w, cjori, ronyrus et al.)</span></span><br><span class="line"><span class="comment">#==========================</span></span><br><span class="line"></span><br><span class="line"> - [12/18/24 14:11:40] <Verbose>: Starting thread <span class="keyword">for</span> Apple TV 4K Advanced board</span><br><span class="line"> - [12/18/24 14:11:40] <Info>: Waiting <span class="keyword">for</span> DFU mode devices</span><br><span class="line"> - [12/18/24 14:11:43] <Verbose>: DFU mode device found</span><br><span class="line"> - [12/18/24 14:11:43] <Info>: Checking <span class="keyword">if</span> device is ready</span><br><span class="line"> - [12/18/24 14:11:43] <Verbose>: Attempting to perform checkm8 on 8015 11</span><br><span class="line"> - [12/18/24 14:11:43] <Info>: Setting up the exploit</span><br><span class="line"> - [12/18/24 14:11:43] <Verbose>: == checkm8 setup stage ==</span><br><span class="line"> - [12/18/24 14:11:43] <Verbose>: Entered initial checkm8 state after 1 steps</span><br><span class="line"> - [12/18/24 14:11:44] <Verbose>: Stalled input endpoint after 3084 steps</span><br><span class="line"> - [12/18/24 14:11:45] <Verbose>: DFU mode device disconnected</span><br><span class="line"> - [12/18/24 14:11:45] <Verbose>: DFU mode device found</span><br><span class="line"> - [12/18/24 14:11:45] <Verbose>: == checkm8 trigger stage ==</span><br><span class="line"> - [12/18/24 14:11:45] <Info>: Checkmate!</span><br><span class="line"> - [12/18/24 14:11:45] <Verbose>: Device should now reconnect <span class="keyword">in</span> download mode</span><br><span class="line"> - [12/18/24 14:11:45] <Verbose>: DFU mode device disconnected</span><br><span class="line"> - [12/18/24 14:11:51] <Info>: Entered download mode</span><br><span class="line"> - [12/18/24 14:11:51] <Verbose>: Download mode device found</span><br><span class="line"> - [12/18/24 14:11:51] <Info>: Booting PongoOS...</span><br><span class="line"> - [12/18/24 14:11:53] <Info>: Found PongoOS USB Device</span><br><span class="line"> - [12/18/24 14:11:54] <Info>: Booting Kernel...</span><br><span class="line"> - [12/18/24 14:11:54] <Info>: Please <span class="built_in">wait</span> up to 10 minutes <span class="keyword">for</span> the fakefs to be created.</span><br><span class="line"> - [12/18/24 14:11:54] <Info>: Once the device reboots into recovery mode, run again without the -c (Create FakeFS) option to jailbreak.</span><br></pre></td></tr></table></figure><h3 id="有根越狱"><a href="#有根越狱" class="headerlink" title="有根越狱"></a>有根越狱</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line">$ palera1n -f</span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># palera1n: v2.0.2 </span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># ======== Made by =======</span></span><br><span class="line"><span class="comment"># Made by: Nick Chan, Ploosh, Khcrysalis, Mineek, staturnz, kok3shidoll, HAHALOSAH </span></span><br><span class="line"><span class="comment"># ======== Thanks to =======</span></span><br><span class="line"><span class="comment"># Thanks to: llsc12, Nebula, Lrdsnow, nikias (libimobiledevice),</span></span><br><span class="line"><span class="comment"># checkra1n team (Siguza, axi0mx, littlelailo et al.),</span></span><br><span class="line"><span class="comment"># Procursus Team (Hayden Seay, Cameron Katri, Keto et.al)</span></span><br><span class="line"><span class="comment"># ==========================</span></span><br><span class="line"></span><br><span class="line"> - [12/18/24 14:19:18] <Info>: Waiting <span class="keyword">for</span> devices</span><br><span class="line"> - [12/18/24 14:19:19] <Info>: Press Enter when ready <span class="keyword">for</span> DFU mode</span><br><span class="line"></span><br><span class="line">Hold volume down + side button (0)</span><br><span class="line">Hold volume down button (3)</span><br><span class="line"> - [12/18/24 14:19:37] <Info>: Device entered DFU mode successfully</span><br><span class="line"> - [12/18/24 14:19:37] <Info>: About to execute checkra1n</span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Checkra1n 0.1337.3</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Proudly written in nano</span></span><br><span class="line"><span class="comment"># (c) 2019-2023 Kim Jong Cracks</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#======== Made by =======</span></span><br><span class="line"><span class="comment"># argp, axi0mx, danyl931, jaywalker, kirb, littlelailo, nitoTV</span></span><br><span class="line"><span class="comment"># never_released, nullpixel, pimskeks, qwertyoruiop, sbingner, siguza</span></span><br><span class="line"><span class="comment">#======== Thanks to =======</span></span><br><span class="line"><span class="comment"># haifisch, jndok, jonseals, xerub, lilstevie, psychotea, sferrini</span></span><br><span class="line"><span class="comment"># Cellebrite (ih8sn0w, cjori, ronyrus et al.)</span></span><br><span class="line"><span class="comment">#==========================</span></span><br><span class="line"></span><br><span class="line"> - [12/18/24 14:19:38] <Verbose>: Starting thread <span class="keyword">for</span> Apple TV 4K Advanced board</span><br><span class="line"> - [12/18/24 14:19:38] <Info>: Waiting <span class="keyword">for</span> DFU mode devices</span><br><span class="line"> - [12/18/24 14:19:42] <Verbose>: DFU mode device found</span><br><span class="line"> - [12/18/24 14:19:42] <Info>: Checking <span class="keyword">if</span> device is ready</span><br><span class="line"> - [12/18/24 14:19:42] <Verbose>: Attempting to perform checkm8 on 8015 11</span><br><span class="line"> - [12/18/24 14:19:42] <Info>: Setting up the exploit</span><br><span class="line"> - [12/18/24 14:19:42] <Verbose>: == checkm8 setup stage ==</span><br><span class="line"> - [12/18/24 14:19:42] <Verbose>: Entered initial checkm8 state after 1 steps</span><br><span class="line"> - [12/18/24 14:19:42] <Verbose>: Stalled input endpoint after 439 steps</span><br><span class="line"> - [12/18/24 14:19:42] <Verbose>: DFU mode device disconnected</span><br><span class="line"> - [12/18/24 14:19:42] <Verbose>: DFU mode device found</span><br><span class="line"> - [12/18/24 14:19:42] <Verbose>: == checkm8 trigger stage ==</span><br><span class="line"> - [12/18/24 14:19:42] <Info>: Checkmate!</span><br><span class="line"> - [12/18/24 14:19:42] <Verbose>: Device should now reconnect <span class="keyword">in</span> download mode</span><br><span class="line"> - [12/18/24 14:19:42] <Verbose>: DFU mode device disconnected</span><br><span class="line"> - [12/18/24 14:19:49] <Info>: Entered download mode</span><br><span class="line"> - [12/18/24 14:19:49] <Verbose>: Download mode device found</span><br><span class="line"> - [12/18/24 14:19:49] <Info>: Booting PongoOS...</span><br><span class="line"> - [12/18/24 14:19:51] <Info>: Found PongoOS USB Device</span><br><span class="line"> - [12/18/24 14:19:51] <Info>: Booting Kernel...</span><br></pre></td></tr></table></figure><h3 id="安装市场和必要插件"><a href="#安装市场和必要插件" class="headerlink" title="安装市场和必要插件"></a>安装市场和必要插件</h3><blockquote><ul><li>越狱完成后,成功进入系统会显示<strong>Palera1n的开机画面</strong></li><li>进入SpringBoard后,会有<strong>palera1n的图标</strong>加载出现(最后一个图标)</li></ul></blockquote><p><strong>满足以上两点,代表越狱流程顺利完成</strong></p><p><img src="/posts/b3a0121c/20241218_142212_274.png"></p><p>① 点击进入palera1n应用</p><p><img src="/posts/b3a0121c/20241218_142346_906.png"></p><p>② 点击Sileo,安装市场</p><p><img src="/posts/b3a0121c/20241218_142405_369.png"></p><p>③ 设置SSH, mobile默认密码</p><p><img src="/posts/b3a0121c/20241218_142414_585.png"></p><p>④ Sileo市场安装成功</p><p><img src="/posts/b3a0121c/20241218_142458_967.png"></p><p>⑤ 进入Sileo市场, 安装好以下几个基本必要的插件</p><blockquote><ul><li>openssh (SSH访问到iPhone设备内部)</li><li>Ellekit (所有运行插件的基础库)</li><li>Appsync (绕过app的证书签名校验)</li></ul></blockquote><h3 id="修改SSH密码"><a href="#修改SSH密码" class="headerlink" title="修改SSH密码"></a>修改SSH密码</h3><p>通过上面设置的mobile用户SSH进入手机内部</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ ssh [email protected]</span><br><span class="line">([email protected]) Password <span class="keyword">for</span> mobile@iPhone:</span><br></pre></td></tr></table></figure><p>修改root用户的密码</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">sudo</span> passwd root</span><br><span class="line"></span><br><span class="line">We trust you have received the usual lecture from the <span class="built_in">local</span> System</span><br><span class="line">Administrator. It usually boils down to these three things:</span><br><span class="line"></span><br><span class="line"> <span class="comment">#1) Respect the privacy of others.</span></span><br><span class="line"> <span class="comment">#2) Think before you type.</span></span><br><span class="line"> <span class="comment">#3) With great power comes great responsibility.</span></span><br><span class="line"></span><br><span class="line">For security reasons, the password you <span class="built_in">type</span> will not be visible.</span><br><span class="line"></span><br><span class="line">[meow] password <span class="keyword">for</span> mobile: </span><br><span class="line">Changing password <span class="keyword">for</span> root.</span><br><span class="line">Old Password:</span><br><span class="line">New Password:</span><br><span class="line">Retype New Password:</span><br><span class="line"></span><br><span class="line"><span class="comment">################################### WARNING ###################################</span></span><br><span class="line"><span class="comment"># This tool does not update the login keychain password. #</span></span><br><span class="line"><span class="comment"># To update it, run `security set-keychain-password` as the user in question, #</span></span><br><span class="line"><span class="comment"># or as root providing a path to such user's login keychain. #</span></span><br><span class="line"><span class="comment">###############################################################################</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>切换到root用户下,验证当前用户是否是root</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">sudo</span> su</span><br><span class="line">iPhone:/private/var/mobile root# <span class="built_in">whoami</span></span><br><span class="line">root</span><br><span class="line">iPhone:/private/var/mobile root# </span><br></pre></td></tr></table></figure><p>至此,我们在iPhone 8 (iOS 16)设备越狱环境基本上配置完成,可以完成后续的各种逆向和DIY等玩法了</p><p>越狱完成,如果我们想恢复到原始系统,那么就要移除越狱</p><h2 id="移除越狱"><a href="#移除越狱" class="headerlink" title="移除越狱"></a>移除越狱</h2><p>以Rootful有根越狱为例</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line">$ palera1n -f --force-revert</span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># palera1n: v2.0.2 </span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># ======== Made by =======</span></span><br><span class="line"><span class="comment"># Made by: Nick Chan, Ploosh, Khcrysalis, Mineek, staturnz, kok3shidoll, HAHALOSAH </span></span><br><span class="line"><span class="comment"># ======== Thanks to =======</span></span><br><span class="line"><span class="comment"># Thanks to: llsc12, Nebula, Lrdsnow, nikias (libimobiledevice),</span></span><br><span class="line"><span class="comment"># checkra1n team (Siguza, axi0mx, littlelailo et al.),</span></span><br><span class="line"><span class="comment"># Procursus Team (Hayden Seay, Cameron Katri, Keto et.al)</span></span><br><span class="line"><span class="comment"># ==========================</span></span><br><span class="line"></span><br><span class="line"> - [12/19/24 08:44:11] <Info>: Waiting <span class="keyword">for</span> devices</span><br><span class="line"> - [12/19/24 08:44:11] <Info>: Entering recovery mode</span><br><span class="line"> - [12/19/24 08:44:22] <Info>: Press Enter when ready <span class="keyword">for</span> DFU mode</span><br><span class="line"></span><br><span class="line">Hold volume down + side button (0)</span><br><span class="line">Hold volume down button (4)</span><br><span class="line"> - [12/19/24 08:44:37] <Info>: Device entered DFU mode successfully</span><br><span class="line"> - [12/19/24 08:44:37] <Info>: About to execute checkra1n</span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Checkra1n 0.1337.3</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Proudly written in nano</span></span><br><span class="line"><span class="comment"># (c) 2019-2023 Kim Jong Cracks</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#======== Made by =======</span></span><br><span class="line"><span class="comment"># argp, axi0mx, danyl931, jaywalker, kirb, littlelailo, nitoTV</span></span><br><span class="line"><span class="comment"># never_released, nullpixel, pimskeks, qwertyoruiop, sbingner, siguza</span></span><br><span class="line"><span class="comment">#======== Thanks to =======</span></span><br><span class="line"><span class="comment"># haifisch, jndok, jonseals, xerub, lilstevie, psychotea, sferrini</span></span><br><span class="line"><span class="comment"># Cellebrite (ih8sn0w, cjori, ronyrus et al.)</span></span><br><span class="line"><span class="comment">#==========================</span></span><br><span class="line"></span><br><span class="line"> - [12/19/24 08:44:38] <Verbose>: Starting thread <span class="keyword">for</span> Apple TV 4K Advanced board</span><br><span class="line"> - [12/19/24 08:44:38] <Info>: Waiting <span class="keyword">for</span> DFU mode devices</span><br><span class="line"> - [12/19/24 08:44:42] <Verbose>: DFU mode device found</span><br><span class="line"> - [12/19/24 08:44:42] <Info>: Checking <span class="keyword">if</span> device is ready</span><br><span class="line"> - [12/19/24 08:44:42] <Verbose>: Attempting to perform checkm8 on 8015 11</span><br><span class="line"> - [12/19/24 08:44:42] <Info>: Setting up the exploit</span><br><span class="line"> - [12/19/24 08:44:42] <Verbose>: == checkm8 setup stage ==</span><br><span class="line"> - [12/19/24 08:44:42] <Verbose>: Entered initial checkm8 state after 1 steps</span><br><span class="line"> - [12/19/24 08:44:42] <Verbose>: Stalled input endpoint after 606 steps</span><br><span class="line"> - [12/19/24 08:44:42] <Verbose>: DFU mode device disconnected</span><br><span class="line"> - [12/19/24 08:44:42] <Verbose>: DFU mode device found</span><br><span class="line"> - [12/19/24 08:44:42] <Verbose>: == checkm8 trigger stage ==</span><br><span class="line"> - [12/19/24 08:44:45] <Info>: Checkmate!</span><br><span class="line"> - [12/19/24 08:44:45] <Verbose>: Device should now reconnect <span class="keyword">in</span> download mode</span><br><span class="line"> - [12/19/24 08:44:45] <Verbose>: DFU mode device disconnected</span><br><span class="line"> - [12/19/24 08:44:51] <Info>: Entered download mode</span><br><span class="line"> - [12/19/24 08:44:51] <Verbose>: Download mode device found</span><br><span class="line"> - [12/19/24 08:44:51] <Info>: Booting PongoOS...</span><br><span class="line"> - [12/19/24 08:44:53] <Info>: Found PongoOS USB Device</span><br><span class="line"> - [12/19/24 08:44:53] <Info>: Booting Kernel...</span><br></pre></td></tr></table></figure><p>重启之后进入系统,会弹窗需要<strong>再次重启移除越狱</strong>或者<strong>进入恢复模式重新越狱</strong></p><p><img src="/posts/b3a0121c/20241219_084540_996.png"></p><p>这里我们点击<strong>Reboot now</strong>, 重启设备开机<strong>看不到palera1n的开机动画</strong>,进入系统也<strong>没有palera1n的桌面图标</strong></p><p>至此移除越狱成功</p><p><img src="/posts/b3a0121c/20241219_090151_523.png"></p><h3 id="相关文献"><a href="#相关文献" class="headerlink" title="相关文献"></a>相关文献</h3><p>本文简要的记录 iOS 16 越狱和移除越狱流程, 更多玩法或其他内容,请参阅以下文献</p><blockquote><ul><li><a href="https://ios.cfw.guide/get-started/">CFW iOS Guide</a></li><li><a href="https://dkxuanye.cn/">玄烨品果</a></li></ul></blockquote>]]></content>
<summary type="html"><p><img src="/posts/b3a0121c/image.png"></p></summary>
<category term="iOS" scheme="https://shoewann0402.github.io/categories/iOS/"/>
<category term="jailbreak" scheme="https://shoewann0402.github.io/tags/jailbreak/"/>
<category term="iOS" scheme="https://shoewann0402.github.io/tags/iOS/"/>
<category term="reverse" scheme="https://shoewann0402.github.io/tags/reverse/"/>
</entry>
</feed>