<div id="article_content" class="article_content">
<p><span style="font-size:14px; color:#009900"> </span><span style="font-size:14px; color:#009900">前言:<span style="font-family:宋体; line-height:28px; text-indent:28px; background-color:rgb(249,249,249)">Zygote 是 <a href="http://lib.csdn.net/base/15" class="replace_word" title="undefined" target="_blank" style="color:#df3434; font-weight:bold;">Android</a> 的核心,每打开一个 app,Zygote 就会 fork 一个虚拟机实例来运行
app,基于Xposed我们可以使用Android hook技术对APK中的方法进行调试、关键API拦截、外挂等。</span></span></p>
<p style="text-indent:28px"><span style="font-family:宋体; font-size:14px; color:#ff0000"><span style="line-height:28px; background-color:rgb(249,249,249)">这篇文章建立在Xposed模块开发的基础之上,没有开发过Xposed模块的请先看这篇入门教程《<a target="_blank" href="http://blog.csdn.net/chenhao0428/article/details/51360554" style="text-decoration:none; font-family:'Microsoft YaHei'; line-height:30px">Xposed模块开发入门教程</a>》</span></span></p>
<p style="text-indent:28px"><span style="line-height:28px; font-family:宋体; font-size:24px; background-color:rgb(249,249,249)"><span style="color:#3366ff">一、微信运动修改步数原理</span></span></p>
<p style="text-indent:28px"><span style="line-height:28px; font-family:宋体; background-color:rgb(249,249,249)"><span style="font-size:18px"><span style="color:#009900">当点击微信运动排行榜的时候微信APP会获取手机上计数传感器的数值,然后传感器会返回我们行走的步数。此时我们使用Xposed框架来hook计数传感器的队列函数dispatchSensorEvent(),该函数在android.hardware.SystemSensorManager$SensorEventQueue这个类中。当询问传感器的时候我们在数值上加上相应步数返回给微信运动达到欺骗效果。<span style="font-family:Menlo,Monaco,Consolas,'Courier New',monospace; line-height:28px; background-color:rgb(249,242,244)"></span></span></span></span></p>
<p style="text-indent:28px"><span style="line-height:28px; font-family:宋体; background-color:rgb(249,249,249)"><span style="font-size:24px; color:#3366ff">二、开发Xposed模块</span></span></p>
<p style="text-indent:28px"><span style="line-height:28px; font-family:宋体; background-color:rgb(249,249,249)"><span style="font-size:18px; color:#009900">1.新建一个类WeixinSport,具体代码如下:</span></span></p>
<p style="text-indent:28px"><span style="line-height:28px; font-family:宋体; background-color:rgb(249,249,249)"></span></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 444px; top: 767px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_1" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span> com.example.administrator.weixinsport; </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">import</span><span> </span><span class="keyword">static</span><span> de.robv.android.xposed.XposedHelpers.findClass; </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">import</span><span> java.lang.reflect.Field; </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">import</span><span> android.hardware.Sensor; </span></span></li><li class=""><span><span class="keyword">import</span><span> android.util.SparseArray; </span></span></li><li class="alt"><span> </span></li><li class=""><span><span class="keyword">import</span><span> de.robv.android.xposed.IXposedHookLoadPackage; </span></span></li><li class="alt"><span><span class="keyword">import</span><span> de.robv.android.xposed.XC_MethodHook; </span></span></li><li class=""><span><span class="keyword">import</span><span> de.robv.android.xposed.XposedBridge; </span></span></li><li class="alt"><span><span class="keyword">import</span><span> de.robv.android.xposed.callbacks.XC_LoadPackage; </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="comment">/**</span> </span></li><li class=""><span><span class="comment"> * Created by Administrator on 2016/5/11.</span> </span></li><li class="alt"><span><span class="comment"> */</span><span> </span></span></li><li class=""><span><span class="keyword">public</span><span> </span><span class="keyword">class</span><span> WeixinSport </span><span class="keyword">implements</span><span> IXposedHookLoadPackage { </span></span></li><li class="alt"><span> </span></li><li class=""><span> <span class="keyword">private</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">int</span><span> stepCount = </span><span class="number">1</span><span>; </span></span></li><li class="alt"><span> </span></li><li class=""><span> <span class="annotation">@Override</span><span> </span></span></li><li class="alt"><span> <span class="keyword">public</span><span> </span><span class="keyword">void</span><span> handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) </span><span class="keyword">throws</span><span> Throwable { </span></span></li><li class=""><span> </span></li><li class="alt"><span> <span class="comment">// filter</span><span> </span></span></li><li class=""><span> <span class="keyword">if</span><span> (!loadPackageParam.packageName.equals(</span><span class="string">"com.tencent.mm"</span><span>)) { </span></span></li><li class="alt"><span> <span class="keyword">return</span><span>; </span></span></li><li class=""><span> } </span></li><li class="alt"><span> </span></li><li class=""><span> <span class="keyword">final</span><span> Class<?> sensorEL = findClass(</span><span class="string">"android.hardware.SystemSensorManager$SensorEventQueue"</span><span>, loadPackageParam.classLoader); </span></span></li><li class="alt"><span> </span></li><li class=""><span> XposedBridge.hookAllMethods(sensorEL, <span class="string">"dispatchSensorEvent"</span><span>, </span><span class="keyword">new</span><span> XC_MethodHook() { </span></span></li><li class="alt"><span> </span></li><li class=""><span> <span class="annotation">@Override</span><span> </span></span></li><li class="alt"><span> <span class="keyword">protected</span><span> </span><span class="keyword">void</span><span> beforeHookedMethod(MethodHookParam param) </span><span class="keyword">throws</span><span> Throwable { </span></span></li><li class=""><span> ((<span class="keyword">float</span><span>[]) param.args[</span><span class="number">1</span><span>])[</span><span class="number">0</span><span>] = ((</span><span class="keyword">float</span><span>[]) param.args[</span><span class="number">1</span><span>])[</span><span class="number">0</span><span>] + </span><span class="number">1168</span><span> * stepCount; </span></span></li><li class="alt"><span> stepCount++; </span></li><li class=""><span> </span></li><li class="alt"><span> Field field = param.thisObject.getClass().getEnclosingClass().getDeclaredField(<span class="string">"sHandleToSensor"</span><span>); </span></span></li><li class=""><span> field.setAccessible(<span class="keyword">true</span><span>); </span></span></li><li class="alt"><span> </span></li><li class=""><span> <span class="keyword">int</span><span> handle = (Integer) param.args[</span><span class="number">0</span><span>]; </span></span></li><li class="alt"><span> Sensor sensor = ((SparseArray<Sensor>) field.get(<span class="number">0</span><span>)).get(handle); </span></span></li><li class=""><span> XposedBridge.log(<span class="string">"sensor = "</span><span> + sensor); </span></span></li><li class="alt"><span> } </span></li><li class=""><span> }); </span></li><li class="alt"><span> } </span></li><li class=""><span>} </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="java" style="color: rgb(0, 153, 0); font-size: 18px; display: none;">package com.example.administrator.weixinsport;
import static de.robv.android.xposed.XposedHelpers.findClass;
import java.lang.reflect.Field;
import android.hardware.Sensor;
import android.util.SparseArray;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
/**
* Created by Administrator on 2016/5/11.
*/
public class WeixinSport implements IXposedHookLoadPackage {
private static int stepCount = 1;
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
// filter
if (!loadPackageParam.packageName.equals("com.tencent.mm")) {
return;
}
final Class<?> sensorEL = findClass("android.hardware.SystemSensorManager$SensorEventQueue", loadPackageParam.classLoader);
XposedBridge.hookAllMethods(sensorEL, "dispatchSensorEvent", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
((float[]) param.args[1])[0] = ((float[]) param.args[1])[0] + 1168 * stepCount;
stepCount++;
Field field = param.thisObject.getClass().getEnclosingClass().getDeclaredField("sHandleToSensor");
field.setAccessible(true);
int handle = (Integer) param.args[0];
Sensor sensor = ((SparseArray<Sensor>) field.get(0)).get(handle);
XposedBridge.log("sensor = " + sensor);
}
});
}
}</pre><p></p>
<p style="color:rgb(0,153,0); font-size:18px">这段代码中我们首先通过equals("com.tencent.mm")过滤出了来自微信的请求:</p>
<p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 444px; top: 1744px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">if</span><span> (!loadPackageParam.packageName.equals(</span><span class="string">"com.tencent.mm"</span><span>)) { </span></span></li><li class=""><span> <span class="keyword">return</span><span>; </span></span></li><li class="alt"><span> } </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="java" style="color: rgb(0, 153, 0); font-size: 18px; display: none;">if (!loadPackageParam.packageName.equals("com.tencent.mm")) {
return;
}</pre><p></p>
<p style="color:rgb(0,153,0); font-size:18px">然后<code style="font-family:Menlo,Monaco,Consolas,'Courier New',monospace; padding:2px 4px; line-height:28px; background-color:rgb(249,242,244)">hook了android.hardware.SystemSensorManager$SensorEventQueue</code><span style="font-family:Helvetica,Arial,'Hiragino Sans GB',sans-serif; line-height:28px">这个类中的</span><code style="font-family:Menlo,Monaco,Consolas,'Courier New',monospace; padding:2px 4px; line-height:28px; background-color:rgb(249,242,244)">dispatchSensorEvent()</code><span style="font-family:Helvetica,Arial,'Hiragino Sans GB',sans-serif; line-height:28px">函数:</span></p>
<p style="color:rgb(0,153,0); font-size:18px"><span style="font-family:Helvetica,Arial,'Hiragino Sans GB',sans-serif; line-height:28px"></span></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 444px; top: 1923px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_3" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">final</span><span> Class<?> sensorEL = findClass(</span><span class="string">"android.hardware.SystemSensorManager$SensorEventQueue"</span><span>, loadPackageParam.classLoader); </span></span></li><li class=""><span> </span></li><li class="alt"><span> XposedBridge.hookAllMethods(sensorEL, <span class="string">"dispatchSensorEvent"</span><span>, </span><span class="keyword">new</span><span> XC_MethodHook() </span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">final Class<?> sensorEL = findClass("android.hardware.SystemSensorManager$SensorEventQueue", loadPackageParam.classLoader);
XposedBridge.hookAllMethods(sensorEL, "dispatchSensorEvent", new XC_MethodHook()</pre><p></p>
<p><span style="font-family:Helvetica,Arial,'Hiragino Sans GB',sans-serif; line-height:28px"></span></p>
<p style="color:rgb(0,153,0); font-size:18px">在计数传感器将步数返回微信运动之前修改步数,加上了1168步:</p>
<p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 444px; top: 2072px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_4" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>((</span><span class="keyword">float</span><span>[]) param.args[</span><span class="number">1</span><span>])[</span><span class="number">0</span><span>] = ((</span><span class="keyword">float</span><span>[]) param.args[</span><span class="number">1</span><span>])[</span><span class="number">0</span><span>] + </span><span class="number">1168</span><span> * stepCount; </span></span></li><li class=""><span> stepCount++; </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png"></a></div></div><pre name="code" class="java" style="color: rgb(0, 153, 0); font-size: 18px; display: none;">((float[]) param.args[1])[0] = ((float[]) param.args[1])[0] + 1168 * stepCount;
stepCount++;</pre><p></p>
<p style="color:rgb(0,153,0); font-size:18px">为了便于调试,将传感器的一些数据打印了出来:</p>
<p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 444px; top: 2203px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_5" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_5" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=5&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">int</span><span> handle = (Integer) param.args[</span><span class="number">0</span><span>]; </span></span></li><li class=""><span> Sensor sensor = ((SparseArray<Sensor>) field.get(<span class="number">0</span><span>)).get(handle); </span></span></li><li class="alt"><span> XposedBridge.log(<span class="string">"sensor = "</span><span> + sensor); </span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="java" style="color: rgb(0, 153, 0); font-size: 18px; display: none;">int handle = (Integer) param.args[0];
Sensor sensor = ((SparseArray<Sensor>) field.get(0)).get(handle);
XposedBridge.log("sensor = " + sensor);</pre><p></p>
<p style="color:rgb(0,153,0)"><span style="font-size:18px">2.修改xposed_init</span></p>
<p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 444px; top: 2352px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_6" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_6" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=6&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>com.example.administrator.weixinsport.WeixinSport </span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png"></a></div></div><pre name="code" class="java" style="color: rgb(0, 153, 0); font-size: 18px; display: none;">com.example.administrator.weixinsport.WeixinSport</pre><p></p>
<p style="color:rgb(0,153,0); font-size:18px">将xposed_init的入口设定为该WeixinSport类。</p>
<p style="font-size:18px"><span style="color:#990000">注:该类中的代码参考了乌云上蒸米大神的文章,该文章地址:http://drops.wooyun.org/tips/8416</span></p>
<p><span style="font-size:24px; color:#3366ff">三、测试</span></p>
<p><span style="font-size:18px; color:#009900">将该APK安装重启后打开微信运动,行走几步后再点击排行榜,发现步数增加了1168。</span></p>
<p><span style="font-size:18px; color:#009900"><img src="https://img-blog.csdn.net/20160517172051968?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt=""><br>
</span></p>
<p><span style="font-size:18px; color:#009900"><span style="color:rgb(255,0,0); font-family:Arial; font-size:32px; line-height:26px"><br>
</span></span></p>
<p><span style="font-size:18px; color:#009900"><span style="color:rgb(255,0,0); font-family:Arial; font-size:32px; line-height:26px">完整源码下载请点击<a target="_blank" href="http://download.csdn.net/detail/chenhao0428/9521553">这里</a></span><span style="color:rgb(255,0,0); font-family:Arial; font-size:32px; line-height:26px">。</span><br>
</span></p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
<p><span style="font-size:14px; color:#009900"> </span><span style="font-size:14px; color:#009900">前言:<span style="font-family:宋体; line-height:28px; text-indent:28px; background-color:rgb(249,249,249)">Zygote 是 <a href="http://lib.csdn.net/base/15" class="replace_word" title="undefined" target="_blank" style="color:#df3434; font-weight:bold;">Android</a> 的核心,每打开一个 app,Zygote 就会 fork 一个虚拟机实例来运行
app,基于Xposed我们可以使用Android hook技术对APK中的方法进行调试、关键API拦截、外挂等。</span></span></p>
<p style="text-indent:28px"><span style="font-family:宋体; font-size:14px; color:#ff0000"><span style="line-height:28px; background-color:rgb(249,249,249)">这篇文章建立在Xposed模块开发的基础之上,没有开发过Xposed模块的请先看这篇入门教程《<a target="_blank" href="http://blog.csdn.net/chenhao0428/article/details/51360554" style="text-decoration:none; font-family:'Microsoft YaHei'; line-height:30px">Xposed模块开发入门教程</a>》</span></span></p>
<p style="text-indent:28px"><span style="line-height:28px; font-family:宋体; font-size:24px; background-color:rgb(249,249,249)"><span style="color:#3366ff">一、微信运动修改步数原理</span></span></p>
<p style="text-indent:28px"><span style="line-height:28px; font-family:宋体; background-color:rgb(249,249,249)"><span style="font-size:18px"><span style="color:#009900">当点击微信运动排行榜的时候微信APP会获取手机上计数传感器的数值,然后传感器会返回我们行走的步数。此时我们使用Xposed框架来hook计数传感器的队列函数dispatchSensorEvent(),该函数在android.hardware.SystemSensorManager$SensorEventQueue这个类中。当询问传感器的时候我们在数值上加上相应步数返回给微信运动达到欺骗效果。<span style="font-family:Menlo,Monaco,Consolas,'Courier New',monospace; line-height:28px; background-color:rgb(249,242,244)"></span></span></span></span></p>
<p style="text-indent:28px"><span style="line-height:28px; font-family:宋体; background-color:rgb(249,249,249)"><span style="font-size:24px; color:#3366ff">二、开发Xposed模块</span></span></p>
<p style="text-indent:28px"><span style="line-height:28px; font-family:宋体; background-color:rgb(249,249,249)"><span style="font-size:18px; color:#009900">1.新建一个类WeixinSport,具体代码如下:</span></span></p>
<p style="text-indent:28px"><span style="line-height:28px; font-family:宋体; background-color:rgb(249,249,249)"></span></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 444px; top: 767px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_1" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span> com.example.administrator.weixinsport; </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">import</span><span> </span><span class="keyword">static</span><span> de.robv.android.xposed.XposedHelpers.findClass; </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">import</span><span> java.lang.reflect.Field; </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">import</span><span> android.hardware.Sensor; </span></span></li><li class=""><span><span class="keyword">import</span><span> android.util.SparseArray; </span></span></li><li class="alt"><span> </span></li><li class=""><span><span class="keyword">import</span><span> de.robv.android.xposed.IXposedHookLoadPackage; </span></span></li><li class="alt"><span><span class="keyword">import</span><span> de.robv.android.xposed.XC_MethodHook; </span></span></li><li class=""><span><span class="keyword">import</span><span> de.robv.android.xposed.XposedBridge; </span></span></li><li class="alt"><span><span class="keyword">import</span><span> de.robv.android.xposed.callbacks.XC_LoadPackage; </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="comment">/**</span> </span></li><li class=""><span><span class="comment"> * Created by Administrator on 2016/5/11.</span> </span></li><li class="alt"><span><span class="comment"> */</span><span> </span></span></li><li class=""><span><span class="keyword">public</span><span> </span><span class="keyword">class</span><span> WeixinSport </span><span class="keyword">implements</span><span> IXposedHookLoadPackage { </span></span></li><li class="alt"><span> </span></li><li class=""><span> <span class="keyword">private</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">int</span><span> stepCount = </span><span class="number">1</span><span>; </span></span></li><li class="alt"><span> </span></li><li class=""><span> <span class="annotation">@Override</span><span> </span></span></li><li class="alt"><span> <span class="keyword">public</span><span> </span><span class="keyword">void</span><span> handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) </span><span class="keyword">throws</span><span> Throwable { </span></span></li><li class=""><span> </span></li><li class="alt"><span> <span class="comment">// filter</span><span> </span></span></li><li class=""><span> <span class="keyword">if</span><span> (!loadPackageParam.packageName.equals(</span><span class="string">"com.tencent.mm"</span><span>)) { </span></span></li><li class="alt"><span> <span class="keyword">return</span><span>; </span></span></li><li class=""><span> } </span></li><li class="alt"><span> </span></li><li class=""><span> <span class="keyword">final</span><span> Class<?> sensorEL = findClass(</span><span class="string">"android.hardware.SystemSensorManager$SensorEventQueue"</span><span>, loadPackageParam.classLoader); </span></span></li><li class="alt"><span> </span></li><li class=""><span> XposedBridge.hookAllMethods(sensorEL, <span class="string">"dispatchSensorEvent"</span><span>, </span><span class="keyword">new</span><span> XC_MethodHook() { </span></span></li><li class="alt"><span> </span></li><li class=""><span> <span class="annotation">@Override</span><span> </span></span></li><li class="alt"><span> <span class="keyword">protected</span><span> </span><span class="keyword">void</span><span> beforeHookedMethod(MethodHookParam param) </span><span class="keyword">throws</span><span> Throwable { </span></span></li><li class=""><span> ((<span class="keyword">float</span><span>[]) param.args[</span><span class="number">1</span><span>])[</span><span class="number">0</span><span>] = ((</span><span class="keyword">float</span><span>[]) param.args[</span><span class="number">1</span><span>])[</span><span class="number">0</span><span>] + </span><span class="number">1168</span><span> * stepCount; </span></span></li><li class="alt"><span> stepCount++; </span></li><li class=""><span> </span></li><li class="alt"><span> Field field = param.thisObject.getClass().getEnclosingClass().getDeclaredField(<span class="string">"sHandleToSensor"</span><span>); </span></span></li><li class=""><span> field.setAccessible(<span class="keyword">true</span><span>); </span></span></li><li class="alt"><span> </span></li><li class=""><span> <span class="keyword">int</span><span> handle = (Integer) param.args[</span><span class="number">0</span><span>]; </span></span></li><li class="alt"><span> Sensor sensor = ((SparseArray<Sensor>) field.get(<span class="number">0</span><span>)).get(handle); </span></span></li><li class=""><span> XposedBridge.log(<span class="string">"sensor = "</span><span> + sensor); </span></span></li><li class="alt"><span> } </span></li><li class=""><span> }); </span></li><li class="alt"><span> } </span></li><li class=""><span>} </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="java" style="color: rgb(0, 153, 0); font-size: 18px; display: none;">package com.example.administrator.weixinsport;
import static de.robv.android.xposed.XposedHelpers.findClass;
import java.lang.reflect.Field;
import android.hardware.Sensor;
import android.util.SparseArray;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
/**
* Created by Administrator on 2016/5/11.
*/
public class WeixinSport implements IXposedHookLoadPackage {
private static int stepCount = 1;
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
// filter
if (!loadPackageParam.packageName.equals("com.tencent.mm")) {
return;
}
final Class<?> sensorEL = findClass("android.hardware.SystemSensorManager$SensorEventQueue", loadPackageParam.classLoader);
XposedBridge.hookAllMethods(sensorEL, "dispatchSensorEvent", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
((float[]) param.args[1])[0] = ((float[]) param.args[1])[0] + 1168 * stepCount;
stepCount++;
Field field = param.thisObject.getClass().getEnclosingClass().getDeclaredField("sHandleToSensor");
field.setAccessible(true);
int handle = (Integer) param.args[0];
Sensor sensor = ((SparseArray<Sensor>) field.get(0)).get(handle);
XposedBridge.log("sensor = " + sensor);
}
});
}
}</pre><p></p>
<p style="color:rgb(0,153,0); font-size:18px">这段代码中我们首先通过equals("com.tencent.mm")过滤出了来自微信的请求:</p>
<p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 444px; top: 1744px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">if</span><span> (!loadPackageParam.packageName.equals(</span><span class="string">"com.tencent.mm"</span><span>)) { </span></span></li><li class=""><span> <span class="keyword">return</span><span>; </span></span></li><li class="alt"><span> } </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="java" style="color: rgb(0, 153, 0); font-size: 18px; display: none;">if (!loadPackageParam.packageName.equals("com.tencent.mm")) {
return;
}</pre><p></p>
<p style="color:rgb(0,153,0); font-size:18px">然后<code style="font-family:Menlo,Monaco,Consolas,'Courier New',monospace; padding:2px 4px; line-height:28px; background-color:rgb(249,242,244)">hook了android.hardware.SystemSensorManager$SensorEventQueue</code><span style="font-family:Helvetica,Arial,'Hiragino Sans GB',sans-serif; line-height:28px">这个类中的</span><code style="font-family:Menlo,Monaco,Consolas,'Courier New',monospace; padding:2px 4px; line-height:28px; background-color:rgb(249,242,244)">dispatchSensorEvent()</code><span style="font-family:Helvetica,Arial,'Hiragino Sans GB',sans-serif; line-height:28px">函数:</span></p>
<p style="color:rgb(0,153,0); font-size:18px"><span style="font-family:Helvetica,Arial,'Hiragino Sans GB',sans-serif; line-height:28px"></span></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 444px; top: 1923px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_3" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">final</span><span> Class<?> sensorEL = findClass(</span><span class="string">"android.hardware.SystemSensorManager$SensorEventQueue"</span><span>, loadPackageParam.classLoader); </span></span></li><li class=""><span> </span></li><li class="alt"><span> XposedBridge.hookAllMethods(sensorEL, <span class="string">"dispatchSensorEvent"</span><span>, </span><span class="keyword">new</span><span> XC_MethodHook() </span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">final Class<?> sensorEL = findClass("android.hardware.SystemSensorManager$SensorEventQueue", loadPackageParam.classLoader);
XposedBridge.hookAllMethods(sensorEL, "dispatchSensorEvent", new XC_MethodHook()</pre><p></p>
<p><span style="font-family:Helvetica,Arial,'Hiragino Sans GB',sans-serif; line-height:28px"></span></p>
<p style="color:rgb(0,153,0); font-size:18px">在计数传感器将步数返回微信运动之前修改步数,加上了1168步:</p>
<p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 444px; top: 2072px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_4" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>((</span><span class="keyword">float</span><span>[]) param.args[</span><span class="number">1</span><span>])[</span><span class="number">0</span><span>] = ((</span><span class="keyword">float</span><span>[]) param.args[</span><span class="number">1</span><span>])[</span><span class="number">0</span><span>] + </span><span class="number">1168</span><span> * stepCount; </span></span></li><li class=""><span> stepCount++; </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png"></a></div></div><pre name="code" class="java" style="color: rgb(0, 153, 0); font-size: 18px; display: none;">((float[]) param.args[1])[0] = ((float[]) param.args[1])[0] + 1168 * stepCount;
stepCount++;</pre><p></p>
<p style="color:rgb(0,153,0); font-size:18px">为了便于调试,将传感器的一些数据打印了出来:</p>
<p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 444px; top: 2203px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_5" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_5" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=5&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">int</span><span> handle = (Integer) param.args[</span><span class="number">0</span><span>]; </span></span></li><li class=""><span> Sensor sensor = ((SparseArray<Sensor>) field.get(<span class="number">0</span><span>)).get(handle); </span></span></li><li class="alt"><span> XposedBridge.log(<span class="string">"sensor = "</span><span> + sensor); </span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="java" style="color: rgb(0, 153, 0); font-size: 18px; display: none;">int handle = (Integer) param.args[0];
Sensor sensor = ((SparseArray<Sensor>) field.get(0)).get(handle);
XposedBridge.log("sensor = " + sensor);</pre><p></p>
<p style="color:rgb(0,153,0)"><span style="font-size:18px">2.修改xposed_init</span></p>
<p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 444px; top: 2352px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_6" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_6" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=6&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>com.example.administrator.weixinsport.WeixinSport </span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png"></a></div></div><pre name="code" class="java" style="color: rgb(0, 153, 0); font-size: 18px; display: none;">com.example.administrator.weixinsport.WeixinSport</pre><p></p>
<p style="color:rgb(0,153,0); font-size:18px">将xposed_init的入口设定为该WeixinSport类。</p>
<p style="font-size:18px"><span style="color:#990000">注:该类中的代码参考了乌云上蒸米大神的文章,该文章地址:http://drops.wooyun.org/tips/8416</span></p>
<p><span style="font-size:24px; color:#3366ff">三、测试</span></p>
<p><span style="font-size:18px; color:#009900">将该APK安装重启后打开微信运动,行走几步后再点击排行榜,发现步数增加了1168。</span></p>
<p><span style="font-size:18px; color:#009900"><img src="https://img-blog.csdn.net/20160517172051968?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt=""><br>
</span></p>
<p><span style="font-size:18px; color:#009900"><span style="color:rgb(255,0,0); font-family:Arial; font-size:32px; line-height:26px"><br>
</span></span></p>
<p><span style="font-size:18px; color:#009900"><span style="color:rgb(255,0,0); font-family:Arial; font-size:32px; line-height:26px">完整源码下载请点击<a target="_blank" href="http://download.csdn.net/detail/chenhao0428/9521553">这里</a></span><span style="color:rgb(255,0,0); font-family:Arial; font-size:32px; line-height:26px">。</span><br>
</span></p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</div>