刚安卓逆向入门,认识到java hook的实用性后决定动手开发xp模块,不详细介绍原理,大概百度一下会更有收获,虽然关于模块开发的文章也不少,但是在自己动手开发时仍遇到一些问题,事无巨细,决定写一篇博客记录下来。
今天Xposed安卓7版本正式发布,机友们有福了。
开发环境
1 android studio
2 android 5.0 三星手机 J7
3 Xp框架
开发步骤
1 进行java hook前肯定要清楚目标应用的java层逻辑;这里我们自己动手开发一个简单的应用。
2 准备依赖包
3 模块实现
4 设置模块入口点
第一步 理清目标应用的java逻辑(自己动手开发应用替代)
这里我们简单开发一个应用,只有一个界面,只有一个Button,点击Button后Toast显示Hello world 字符串
贴上代码,大概需要懂一点开发。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnShow = (Button) findViewById(R.id.show);
btnShow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String temp = getTestString();
Toast.makeText(MainActivity.this,temp,Toast.LENGTH_SHORT).show();
}
});
}
这里看到我们的所要显示的字符串从getTestString()中获得
private String getTestString(){
return "hello world";
}
我们通过hook后希望点击Button后显示“Hello android”,显然getTestString()就是我们的目标,我们贴上完整
package com.example.administrator.javahooktest;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button btnShow;
private String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnShow = (Button) findViewById(R.id.show);
btnShow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String temp = getTestString();
Toast.makeText(MainActivity.this,temp,Toast.LENGTH_SHORT).show();
}
});
}
private String getTestString(){
return "hello world";
}
}
可得我们的目标是com.example.administrator.javahooktest包下MainActivity来下的getTestString()函数。
第二步 准备xp依赖包
下载api-82.jar api-82-sources.jar
链接点击打开链接
第三步 模块实现
1 讲依赖包拷贝到libs目录下
2 修改 build.gradle
修改 dependencies
dependencies {
provided 'de.robv.android.xposed:api:82'
provided 'de.robv.android.xposed:api:82:sources'
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
}
原为
3 修改manifeses文件
在application子标签下添加 meta-data
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposeddescription"
android:value="xpose模块测试" />
<meta-data
android:name="xposedminversion"
android:value="54" />
第一条标识是否为xp模块,第二条是说明,第三条设置最低版本
4 进行工具类开发,注意不要在Activity中实现,会出异常,原因暂时不知。
这里新建XPmodule类实现IXposedHookLoadPackage接口,并实现其handleLoadPackage(...)方法
通过第一步我们已知我们的目标是com.example.administrator.javahooktest包下MainActivity来下的getTestString()函数。
这里首先匹配我们的目标包名 com.example.administrator.javahooktest 再通过classLoader加载我们的目标类,传入的参数是我们目标类MainActivity的完整路径。
最后通过XposedHelpsers 找到并hook我们目标函数,这里会让我们实现两个方法
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
这个函数可在找到目标函数后 执行目标函数前执行
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
param.setResult("Hello Android");
}
这个函数可在正常执行目标函数后在return前执行,我们在这个函数中修改目标函数的返回结果,通过param.setResult(...),当然事前我们已经知道目标函数返回的是一个字符串。
贴上完整代码
package com.example.administrator.myxposedmodule;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
/**
*
*/
public class XPmodule implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if(loadPackageParam.packageName.equals("com.example.administrator.javahooktest")){
Class testClass = loadPackageParam.classLoader.loadClass("com.example.administrator.javahooktest.MainActivity");
XposedHelpers.findAndHookMethod(testClass, "getTestString", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
param.setResult("Hello Android");
}
});
}
}
}
到这里,可能遇到一个问题,我们知道函数是可进行重载的,假如我们的目标函数有参数呢,并且存在不同形式参数的重载函数怎么办???
这里我们看到我们是通过XposedHelpers.findAndHookMethod(...)找到目标函数,跟进
这里清楚看到第三项是一个可变参数,Object... parameterTypesAndCallback根据名称以后类内代码,我们猜到这个可变参数的最后一项是hook的回调函数,而这个参数的其他项则应该是我们目标函数所传入参数决定的。事实上确实如此,在这个可变参数的中我们需要传入目标函数参数的Class类型。例 假如函数getTestString中有一个String参数,即getTestString(String s),我们就应该在这个可变参数中传入String.class,以此类推实际上需要传入所有参数的class。
5 创建xposed_init,写入我们工具类的入口
首先创建assets文件夹
再创建xposed_init文件
在xposed_init文件中添加我们的工具类入口的完整路径 包名 + 类名
至此,我们的开发完成,最后需要注意的是要通过签名打包后的apk文件安装。
刚android逆向入门,决定每周一更,欢迎关注,同时有什么问题可加q1254553524