何為hook
Hook英文翻譯過來就是“鈎子”的意思,那我們在什么時候使用這個“鈎子”呢?
我們知道,在Android操作系統中系統維護着自己的一套事件分發機制。應用程序,包括應用觸發事件和后台邏輯處理,也是根據事件流程一步步的向下執行。而“鈎子”的意思,就是在事件傳送到終點前截獲並監控事件的傳輸,像個鈎子勾上事件一樣。並且能夠在勾上事件時,處理一些自己特定的事件。如下圖所示:

Hook的這個本領,使它能夠將自身的代碼“融入”被勾住(Hook)的程序的進程中,成為目標進程的一個部分。我們也知道,在Android系統中使用了沙箱機制,普通用戶程序的進程空間都是獨立的,程序的運行彼此間都不受干擾。
這就使我們希望通過一個程序改變其他程序的某些行為的想法不能直接實現,但是Hook的出現給我們開拓了解決此類問題的道路。當然,根據Hook對象與Hook后處理的事件方式不同,Hook還分為不同的種類,如消息Hook、API Hook等。
注:上述言論來自北漂周大神http://blog.csdn.net/yzzst/article/details/47318751
主要功能就是,修改或者監聽他人程序方法的返回值,這逼裝的瞬間就給滿分。
Xpose
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’)
- 新建一個類實現IXposedHookLoadPackage接口
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");
}
} });
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
XposedHelpers.findAndHookMethod有兩個回調方法beforeHookedMethod,afterHookedMethod。一個在方法調用前回調,一個在方法調用之后回調。
- 然后需要聲明程序入口,在assets新建xposed_init文件聲明該類
//包名+類名
com.example.loginhook.Main
- 1
- 2
在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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
然后運行程序,在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
}
- 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
實現一個action ,為了隱式調用
<!-- @android:style/Theme.Translucent.NoTitleBar -->
<activity android:name="com.example.loginhook.AdActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"// android:hardwareAccelerated="true">
<intent-filter>
<!-- 廣告的action -->
<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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
接下來實現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");
}
}});
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
也就是打開應用寶的時候啟動一個透明的廣告,看起來就像是應用寶里面的廣告,感覺66的
分類:
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
何為hook
Hook英文翻譯過來就是“鈎子”的意思,那我們在什么時候使用這個“鈎子”呢?
我們知道,在Android操作系統中系統維護着自己的一套事件分發機制。應用程序,包括應用觸發事件和后台邏輯處理,也是根據事件流程一步步的向下執行。而“鈎子”的意思,就是在事件傳送到終點前截獲並監控事件的傳輸,像個鈎子勾上事件一樣。並且能夠在勾上事件時,處理一些自己特定的事件。如下圖所示:

Hook的這個本領,使它能夠將自身的代碼“融入”被勾住(Hook)的程序的進程中,成為目標進程的一個部分。我們也知道,在Android系統中使用了沙箱機制,普通用戶程序的進程空間都是獨立的,程序的運行彼此間都不受干擾。
這就使我們希望通過一個程序改變其他程序的某些行為的想法不能直接實現,但是Hook的出現給我們開拓了解決此類問題的道路。當然,根據Hook對象與Hook后處理的事件方式不同,Hook還分為不同的種類,如消息Hook、API Hook等。
注:上述言論來自北漂周大神http://blog.csdn.net/yzzst/article/details/47318751
主要功能就是,修改或者監聽他人程序方法的返回值,這逼裝的瞬間就給滿分。
Xpose
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’)
- 新建一個類實現IXposedHookLoadPackage接口
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");
}
} });
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
XposedHelpers.findAndHookMethod有兩個回調方法beforeHookedMethod,afterHookedMethod。一個在方法調用前回調,一個在方法調用之后回調。
- 然后需要聲明程序入口,在assets新建xposed_init文件聲明該類
//包名+類名
com.example.loginhook.Main
- 1
- 2
在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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
然后運行程序,在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
}
- 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
實現一個action ,為了隱式調用
<!-- @android:style/Theme.Translucent.NoTitleBar -->
<activity android:name="com.example.loginhook.AdActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"// android:hardwareAccelerated="true">
<intent-filter>
<!-- 廣告的action -->
<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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
接下來實現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");
}
}});
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
也就是打開應用寶的時候啟動一個透明的廣告,看起來就像是應用寶里面的廣告,感覺66的
