何为hook
Hook英文翻译过来就是“钩子”的意思,那我们在什么时候使用这个“钩子”呢?
我们知道,在Android操作系统中系统维护着自己的一套事件分发机制。应用程序,包括应用触发事件和后台逻辑处理,也是根据事件流程一步步的向下执行。而“钩子”的意思,就是在事件传送到终点前截获并监控事件的传输,像个钩子勾上事件一样。并且能够在勾上事件时,处理一些自己特定的事件。如下图所示:
Hook的这个本领,使它能够将自身的代码“融入”被勾住(Hook)的程序的进程中,成为目标进程的一个部分。我们也知道,在Android系统中使用了沙箱机制,普通用户程序的进程空间都是独立的,程序的运行彼此间都不受干扰。
这就使我们希望通过一个程序改变其他程序的某些行为的想法不能直接实现,但是Hook的出现给我们开拓了解决此类问题的道路。当然,根据Hook对象与Hook后处理的事件方式不同,Hook还分为不同的种类,如消息Hook、API Hook等。
注:上述言论来自北漂周大神http://blog.csdn.net/yzzst/article/details/47318751
主要功能就是,修改或者监听他人程序方法的返回值,这逼装的瞬间就给满分。
https://github.com/rovo89
框架由上面三部分构成。
既然能够hook其他程序的api,相比也会修改底层代码,而Xposed主要是来修改系统的app_process,它集成在XposedInstaller中,所以只要运行XposedInstall打包的apk点击“安装/更新”就可以了。
而XposedBridge则是一个jar包,提供hook相关的api.
除了XposedInstall这个安装器,还有wsm,据说是为了兼容miui而有的,两者主要目的都差不多,具体可百度之.
接下来就来看看hook的魅力,导入XposedBridgeApi-54.jar包,因为正常的compile files(‘lib/XposedBridgeApi-54.jar’)之后,运行会报错,IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation”。 故使用 provided files(‘lib/XposedBridgeApi-54.jar’)
public class Main implements IXposedHookLoadPackage{
//handleLoadPackage方法可以捕捉指定包名
@Override
public void handleLoadPackage(LoadPackageParam arg0) throws Throwable {
// TODO Auto-generated method stub
//不是指定的程序,不hook
if (!arg0.packageName.equals("com.pingplusplus.demoapp") )
return;
//打印日志在XposedInstall.apk里
XposedBridge.log("Loaded app: " + arg0.packageName);
//hook TelephonyManager类里面的getDeviceId,修改手机imei码妥妥的
XposedHelpers.findAndHookMethod(TelephonyManager.class.getName(), arg0.classLoader, "getDeviceId", new Object[] { new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("劫持结束了~");
//将返回得imei值设置为我想要的值
param.setResult("1234567890");
}
} });
}
}
XposedHelpers.findAndHookMethod有两个回调方法beforeHookedMethod,afterHookedMethod。一个在方法调用前回调,一个在方法调用之后回调。
//包名+类名
com.example.loginhook.Main
在AndroidManifest.xml声明meta-data
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposeddescription"
android:value="模块名,在XposedInstall显示" />
<meta-data
android:name="xposedminversion"
android:value="30" />
application>
然后运行程序,在XposedInstall的模块功能可以看到新加了一个模块
勾选模块,会提示你重启手机,这样才会生效。
这样就可以修改包名为com.pingplusplus.demoapp的程序的getDeviceId()方法了,在程序中打印一下,输出的imei码是不是变了?
除了修改方法的返回值,还可以用它来广告注入。你想在哪个程序注入广告,,只需知道那个程序的包名+主activity,劫持他的onCreate方法,在这里打开另一个透明的activity,就可以实现广告了
首先定义一个AdActivity接入第三方广告
public class AdActivity extends Activity implements InterstitialAdListener{
public static String url = null;
public static byte FS_DESIRE_AD_FORM = 0;
private String LOG_TAG = "unlock";
private RelativeLayout layout;
public static TextView adCount ;
public static TextView adBeaconCount;
private InterstitialAd ad;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//全屏广告实例
ad = new InterstitialAd(this,"2b8dbd92edd74a97b3ba6b0189bef125",true,this);
// 设置全屏格式
ad.setDesireAdForm(InterstitialAd.ADWO_INTERSTITIAL);
// 设置请求广告类型 可选。
// ad.setDesireAdType((byte) 0);
// 开始请求全屏广告
ad.prepareAd();
}
@Override
public void onReceiveAd() {
Log.e(LOG_TAG, "onReceiveAd");
}
@Override
public void onLoadAdComplete() {
Log.e(LOG_TAG, "onLoadAdComplete");
// 成功完成下载后,展示广告
ad.displayAd();
}
@Override
public void onFailedToReceiveAd(ErrorCode errorCode) {
Log.e(LOG_TAG, "onFailedToReceiveAd");
}
@Override
public void onAdDismiss() {
Log.e(LOG_TAG, "onAdDismiss");
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(LOG_TAG, "onDestroy");
// 请在这里释放全屏广告资源
if (ad != null) {
ad.dismiss();
ad = null;
}
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
// 开始请求广告
Log.e(LOG_TAG, "onAttachedToWindow");
}
@Override
public void OnShow() {
// TODO Auto-generated method stub
}
实现一个action ,为了隐式调用
<activity android:name="com.example.loginhook.AdActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"//
android:hardwareAccelerated="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="com.example.loginhook.action.AD" />
intent-filter>
activity>
接下来实现hook,在应用宝的主页添加广告
@Override
public void handleLoadPackage(LoadPackageParam arg0) throws Throwable {
if (!arg0.packageName.equals("com.tencent.android.qqdownloader") )
return;
XposedHelpers.findAndHookMethod("com.tencent.assistantv2.activity.MainActivity", arg0.classLoader, "onCreate", new Object[]{Bundle.class,
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("onCreate" + param.method.getName());
CMD.execCommand1("am start -a com.example.loginhook.action.AD");
}
}});
}
也就是打开应用宝的时候启动一个透明的广告,看起来就像是应用宝里面的广告,感觉66的
代码下载https://github.com/JadynChan/xposehookdemo