360和和金山手機衛士都有一個讓廣大android開發者比較蛋疼的一個功能:那就是檢查廣告通知!
當有通知欄有廣告的時候,運行360執行檢查,它會告訴你是哪個應用程序的廣告(當然,這裡並不局限於廣告,他們是獲得所有通知,然後過濾),然後他會讓用戶選擇:不處理;關閉通知(實際上是把這個進程kill掉,整個軟件停止運行);卸載此軟件。
雖然我沒有發布過android應用,但是我知道,靠軟件賺錢的各位,本來收入已經夠尴尬的了,再加上這些操蛋的軟件提供這些操蛋的功能……哎
大家不喜歡收費軟件那咱們就免費,點點廣告支持一下總行吧,就是不點,你就放在那呗(當然,有的軟件發起廣告來沒玩沒了也挺操蛋)
說了這麼多廢話,我們就來看看那些所謂的殺毒軟件是如何對付大家的
到了關鍵的地方,實際也就那麼一行代碼……又讓大家失望了。。。
Shell代碼
adb shell dumpsys notification
比如,我現在在我機器上面執行一下,輸出的結果為
Log代碼
Current Notification Manager state:
Notification List:
NotificationRecord{41453c70 pkg=com.zdworks.android.toolbox id=7f090092 tag=null pri=0}
icon=0x0 / <name unknown>
contentIntent=null
deleteIntent=null
tickerText=null
contentView=null
defaults=0x0
flags=0x62
sound=null
vibrate=null
ledARGB=0x0 ledOnMS=0 ledOffMS=0
NotificationRecord{415f48e8 pkg=com.zdworks.android.toolbox id=7f090080 tag=null pri=100}
icon=0x7f0200fd / com.zdworks.android.toolbox:drawable/barttery_notify_icon
contentIntent=PendingIntent{41949028: PendingIntentRecord{412e3c20 com.zdworks.android.toolbox startActivity}}
deleteIntent=null
tickerText=電量提示
contentView=android.widget.RemoteViews@416e7b90
defaults=0x0
flags=0x22
sound=null
vibrate=null
ledARGB=0x0 ledOnMS=0 ledOffMS=0
NotificationRecord{416db3e0 pkg=android id=1040414 tag=null pri=100}
icon=0x10804f5 / android:drawable/stat_sys_adb
contentIntent=PendingIntent{41275de8: PendingIntentRecord{416dade8 android startActivity}}
deleteIntent=null
tickerText=USB 調試已連接
contentView=android.widget.RemoteViews@416daf40
defaults=0x0
flags=0x2
sound=null
vibrate=null
ledARGB=0x0 ledOnMS=0 ledOffMS=0
NotificationRecord{41790de8 pkg=com.htc.android.psclient id=7f020010 tag=null pri=100}
icon=0x7f020010 / com.htc.android.psclient:drawable/usb_to_pc_notify
contentIntent=PendingIntent{416c3e38: PendingIntentRecord{417bc968 com.htc.android.psclient startActivity}}
deleteIntent=null
tickerText=null
contentView=android.widget.RemoteViews@4169d128
defaults=0x0
flags=0x2
sound=null
vibrate=null
ledARGB=0x0 ledOnMS=0 ledOffMS=0
mSoundNotification=null
mSound=com.android.server.NotificationPlayer@413e73b8
mVibrateNotification=null
mDisabledNotifications=0x0
mSystemReady=true
現在大家知道了吧,這麼簡單就把咱們給搞定了
下面的事情就簡單
1.想辦法獲取這段log
2.提取包名
3.根據數據庫中的黑名單白名單不同處理
4.你的應用很可能在黑名單中,最後的結果也基本是進程被殺死
(這裡就不演示3、4部分了,只演示1、2)
Java代碼
testButton = (Button)findViewById(R.id.exec);
testButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String[] commands = {"dumpsys notification"};
Process process = null;
DataOutputStream dataOutputStream = null;
try {
process = Runtime.getRuntime().exec("su");
dataOutputStream = new DataOutputStream(process.getOutputStream());
int length = commands.length;
for (int i = 0; i < length; i++) {
Log.e(TAG, "commands[" + i + "]:" + commands[i]);
dataOutputStream.writeBytes(commands[i] + "\n");
}
dataOutputStream.writeBytes("exit\n");
dataOutputStream.flush();
process.waitFor();
BufferedReader reader = null;
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
List<String> lineList = new ArrayList<String>();
final StringBuilder log = new StringBuilder();
String separator = System.getProperty("line.separator");
Pattern pattern = Pattern.compile("pkg=[^\\s]+");
while ((line = reader.readLine()) != null) {
if(line != null && line.trim().startsWith("NotificationRecord")){
Matcher matcher = pattern.matcher(line);
if(matcher.find()){
lineList.add(matcher.group());
}else{
Log.e(TAG, "what's this?!");
}
}
log.append(line);
log.append(separator);
}
Log.v(TAG, "log:" + log.toString());
int size = lineList.size();
for (int i = 0; i < size; i++) {
Log.i(TAG, "app:" + lineList.get(i));
}
} catch (Exception e) {
Log.e(TAG, "copy fail", e);
} finally {
try {
if (dataOutputStream != null) {
dataOutputStream.close();
}
process.destroy();
} catch (Exception e) {
}
}
Log.v(TAG, "finish");
}
});
}
上面的這段代碼實在沒什麼技術含量,讓給位網友見笑了
按順序簡單解釋一下
首先,我們先執行dumpsys notification這條命令,這在上一期的代碼中已經有了
然後通過process.getInputStream()獲得其輸出按行讀取,這裡只關心類似於下面這種的log
Log代碼
NotificationRecord{40dacad8 pkg=com.htc.android.psclient id=7f020010 tag=null pri=100}
然後從中提取出包名即可
其中的正則就是為了提取包名用的,想了解正則的同學可以看我的正則教程
深入入門正則表達式(java)
這裡我執行的結果為(看來有一個應用提示了兩個通知)
Java代碼
app:pkg=com.zdworks.android.toolbox
app:pkg=com.zdworks.android.toolbox
app:pkg=android
app:pkg=com.htc.android.psclient
之後的工作就是把這個list展示給用戶,讓用戶去選擇了
既然360可以這樣,病毒為什麼不可以呢?病毒Fake.apk可以在半夜偷偷安裝應用Real.apk,幾秒鐘後,Fake.apk執行上面的這些操作,獲取360,然後kill!爽!
大家有興趣可以反編譯一下金山和360,他們基本就是這麼干的,我發現360比較壞,至於為什麼這麼說,大家自己去發現吧