首先安装Xposed Installer框架,下载Xposed API jar包
链接:https://pan.baidu.com/s/1TGPoldcsi8CvgfCXpTy0Tw 密码:2pa3
1.Android studio 创建一个新工程,在app lib 中导入XposedBridge-jar包,在app中添加该包,以compileOnly files格式
2.在AndroidManifest.xml文件里添加以下配置
<!-- 使 xposed 模块有效 -->
<meta-data android:name="xposedmodule"
android:value="true"/>
<!-- xposed 模块名称,我们可以随便起一个和模块功能相似的即可 -->
<meta-data android:name="xposeddescription"
android:value="修改设备IMEI"/>
<!-- xposed 模块最低版本 -->
<meta-data android:name="xposedminversion"
android:value="54"/>
3.创建activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="20dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv1"
android:layout_width="80dp"
android:layout_height="20dp"
android:layout_weight="1"
android:text="one" />
<TextView
android:id="@+id/tv2"
android:layout_width="80dp"
android:layout_height="20dp"
android:layout_weight="1"
android:text="two" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<EditText
android:id="@+id/imei_et"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="40dp"
android:hint="输入修改IMEI值" />
<Button
android:id="@+id/btn_Save"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="Button" />
</LinearLayout>
</LinearLayout>
4.实现主界面MainActvity,主要有实例化控制,判断获取权限,文本设置显示当前手机IMEI,IMSI值,文本输入框获取值,Button设置点击事件。
public class MainActivity extends AppCompatActivity {
private TextView tv1;
private TextView tv2;
final int MY_PERMIEAD_CONTACTS = 1;
private EditText imeitx;
private Button btnSave;
private TelephonyManager Phone;
@SuppressLint("MissingPermission")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//实例化控件
tv1 = findViewById(R.id.tv1);
tv2 = findViewById(R.id.tv2);
imeitx = findViewById(R.id.imei_et);
btnSave = findViewById(R.id.btn_Save);
Phone = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
// 点击按钮,将数据保存到SharedPreference中
btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
saveData();//点击保存sp键值对数据
}
});
//获取权限状态
int permissionCheck =
ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE);
//判断权限是否开启
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_PHONE_STATE}, MY_PERMIEAD_CONTACTS);
} else {
//设置显示文本的数据
tv1.setText("IMEI:" + Phone.getDeviceId());
tv2.setText("IMSI:" + Phone.getSubscriberId());
}
}
private void saveData() {
try {
//sp键值对保存,文本框里数据
SharedPreferences sh = this.getSharedPreferences("sPref", Context.MODE_WORLD_READABLE);
SharedPreferences.Editor sPre = sh.edit();
sPre.putString("imei", imeitx.getText().toString());
sPre.apply();
Toast.makeText(MainActivity.this, "修改成功", Toast.LENGTH_SHORT).show();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
4.创建Xposed实现类,实现接口IXposedHookLoadPackage ,重写handleLoadPackage方法,在该方法里实现具体hook操作,运行成功就可以完成修改了。
public class Main implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
//获得Sharedpreference保存的数据
final XSharedPreferences sPre = new XSharedPreferences(this.getClass().getPackage().getName(), "sPref");
XposedHelpers.findAndHookMethod(TelephonyManager.class.getName(), loadPackageParam.classLoader, "getDeviceId", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
//具体的hook操作就这一行,设置getDeviceId()的返回值
param.setResult(sPre.getString("imei", null));
//打印log
XposedBridge.log("hook ---getDeviceId***after " + param.getResult());
}
});
}
}
5.最后一步别忘了,创建assets文件夹,创建xposed_init文件
文件写入内容为app包名.Xposed主类名
6.如此就可以运行,软重启修改IMEI了。
7,注意可能会遇到的问题
问题一:Setting里Instant Run 默认设置勾选,会使编译加快,但会对xposed框架有影响,编译会没有结果,应该去掉√。
问题二:gradle文件里设置libs,这样会把jar包加入到APK,而手机Xposed Installer里已经有该jar包了,两个存在就会有冲突。如此Xposed日志里会报错,所以应用里的Xposed.jar不能导入,然后如下就会好。
coz
Hook(钩子)实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出(要hook函数触发),在没有到达目的窗口前,钩子程序就先捕获该消息,钩子函数先得到控制权。这时钩子函数就可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。pzompileOnly files('lib/XposedBridgeApi-82.jar')
总结:Xposed框架hook的实用性,当其他APP执行函数、Android系统函数运行前/后,劫持它们的输入值,输出值,并且改变,传递这些值。可以给应用打补丁,也可以该设备信息,这次的例子就是改变了系统的IMEI值。
hook前 IMEI
hook后 :IMEI
还有什么问题不明白,或者不会
欢迎加入我的Java与Android逆向开发交流QQ群,一起学习,一起进步。