1. 程式人生 > >支付寶後臺不死的黑科技

支付寶後臺不死的黑科技

近期支付寶升級到了9.0,除了加入微信功能外,還新增了金鐘罩功能,不要說普通的各種加速球,火箭神馬的不能殺死他外,連格外牛逼的綠色守護也奈何不了他。在綠色守護裡面,支付寶始終顯示為“服務正在被 支付寶 使用”,不會自動休眠,惱火死了。那麼問題來了,他是怎麼做到的呢?

支付寶幹了啥?

這就是支付寶在綠色守護裡的狀態,它一直處在不會被自動休眠的這個category裡面。不要問我第一個是啥,後面會有。
sneaky_alipaysneaky_alipay

我們知道,Android有一個oom的機制,系統會根據程序的優先順序,給每個程序一個oom權重值,當系統記憶體緊張時,系統會根據這個優先順序去選擇將哪些程序殺掉,以騰出空間保證更高優先順序的程序能正常執行。要想讓程序長期存活,提高優先順序是個不二之選。這個可以在adb中,通過以下命令檢視:

1
su cat /proc/pid/oom_adj

這個值越小,說明程序的優先順序越高,越不容易被程序kill掉。通常如果是負數,表示該程序為系統程序,肯定不會被殺掉,如果是0,表示是前臺程序,即當前使用者正在操作的程序,除非萬不得已,也不會被殺掉,1則表示是可見程序,通常表示有一個前臺服務,會再通知欄有一個劃不掉的通知,比如放歌,下載檔案什麼的。再增大,則優先順序逐漸降低,順序為服務程序,快取程序,空程序等等。

因此首先,我們來檢視支付寶程序的oom_adj。不出意料,其值很高:1。但這又在意料之外,因為支付寶既沒有新增系統服務,也沒有常駐通知欄,也沒有顯示彈窗啊。不過既然情況已經這樣了,那我們還是看一下他的服務狀態吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
[email protected]:/ $ dumpsys activity services com.eg.android.AlipayGphone

* ServiceRecord{17d6e8a5 u0 com.eg.android.AlipayGphone/com.alipay.android.launcher.service.LauncherService$InnerService}
intent={cmp=com.eg.android.AlipayGphone/com.alipay.android.launcher.service.LauncherService$InnerService
}

packageName=com.eg.android.AlipayGphone
processName=com.eg.android.AlipayGphone
baseDir=/data/app/com.eg.android.AlipayGphone-2/base.apk
dataDir=/data/data/com.eg.android.AlipayGphone
app=ProcessRecord{38365c98 14176:com.eg.android.AlipayGphone/u0a66}
isForeground=true foregroundId=168816881 foregroundNoti=Notification(pri=0 contentView=com.eg.android.AlipayGphone/0x1090077 vibrate=null sound=null defaults=0x0 flags=0x40 color=0xff00bcd4 vis=PRIVATE)
createTime=-19m10s188ms startingBgTimeout=-18m55s186ms
lastActivity=-19m10s188ms restartTime=-19m10s188ms createdFromFg=false
startRequested=true delayedStop=false stopIfKilled=true callStart=true lastStartId=1

原來真有一個前臺服務!

這不科學!Service的startForeground函式是要提供一個Notification引數的啊。查資料麻煩,還不如直接反編譯支付寶的程式碼來得快。知道了這個service的名字,我們就可以直搗黃龍了。在LauncherService裡面,我們找到了如下程式碼:

sneaky_foreground_servicesneaky_foreground_service

這是一段開啟前臺服務的程式碼,針對不同api,18一下直接簡單粗暴的給了一個空的notification,並沒有用到上面抓到的InnerService。當然,開啟adb看一看,18一下確實就LauncherService自己在負責前臺。18以上,則另行處理。試了試,18一下這麼幹,還真的可以。在用這個老版本手機的時候,一併發現原來好多的應用都是這麼幹的,什麼豌豆莢啦,369手機助手神馬的,好吧,算我孤陋寡聞了。但18以上的這段程式碼沒有看太明白,於是,想開啟他的InnerService看看到底有什麼鬼。然而讓我失望的是,InnerService裡面並沒有開啟前臺服務的程式碼,而是把主流程給隱藏在了onStartCommand的一個包裹函式中。這裡他用到了aspectj框架,在onStartCommand上做了一個切點,那麼具體開啟前臺服務的流程肯定就在這個切點裡面了。但是,但是,尼瑪的,我看不懂aspectj啊,跟也跟不過去。沒辦法,只好繞回來,去google了。幸好幸好,讓我找到了方法,看上去,也是和支付寶的思路是一樣,

android的漏洞在哪?

原來,google在4.3的時候終於發現有太多流氓應用,為了提高優先順序,開啟了前臺服務,但又不想讓使用者知道,因此需要不顯示通知欄。於是找到了android在開啟前臺服務時候的一個漏洞,給一個非法的Notification引數,讓系統先把ServiceRecord裡面的isForeground標記給打上,然後等到顯示通知欄時,發現引數並不合法,android於是什麼也不幹,就不顯示通知欄提醒了。

當一票app都這麼幹的時候,google覺得不能忍了,於是在ServiceRecordpostNotification函式裡面裡面,我們看到了如下程式碼:

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
try {
if (localForegroundNoti.icon == 0) {
// It is not correct for the caller to supply a notification
icon, but this used to be able to slip through, so for
those dirty apps give it the app's icon.
localForegroundNoti.icon = appInfo.icon;

// Do not allow apps to present a sneaky invisible content view either.
localForegroundNoti.contentView = null;
localForegroundNoti.bigContentView = null;
CharSequence appName = appInfo.loadLabel(
ams.mContext.getPackageManager());
if (appName == null) {
appName = appInfo.packageName;
}
ctx = null;
try {
ctx = ams.mContext.createPackageContext(
appInfo.packageName, 0);
Intent runningIntent = new Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
runningIntent.setData(Uri.fromParts("package",
appInfo.packageName, null));
PendingIntent pi = PendingIntent.getActivity(ams.mContext, 0,
runningIntent, PendingIntent.FLAG_UPDATE_CURRENT);
localForegroundNoti.setLatestEventInfo(ctx,
ams.mContext.getString(
com.android.internal.R.string
.app_running_notification_title,
appName),
ams.mContext.getString(
com.android.internal.R.string
.app_running_notification_text,
appName),
pi);
} catch (PackageManager.NameNotFoundException e) {
localForegroundNoti.icon = 0;
}
}

裡面可以看到,android再也不讓你欺騙系統了,是前臺服務就必須要顯示一個通知欄提醒。於是,像豌豆莢,360這些,在高版本系統上也沒有前臺服務了,默默的再後臺,然後等著被幹掉。

既然如此,那支付寶是怎麼做到的呢?真實應了那句話,流氓不可怕,就怕流氓有文化。大門給關上了,那我就翻窗戶吧。

在啟動前臺服務的時候一定要給一個Notification,那我可不可以在啟動前臺服務後,呼叫NotificationManager的cancelNotification把這個Notification給取消掉呢?來看看原始碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 在NotificationManagerService.java中
public void cancelNotificationWithTag(String pkg, String tag, int id, int userId) {
checkCallerIsSystemOrSameApp(pkg);
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg);
// Don't allow client applications to cancel foreground service notis.
cancelNotification(pkg, tag, id, 0,
Binder.getCallingUid() == Process.SYSTEM_UID
? 0 : Notification.FLAG_FOREGROUND_SERVICE, false, userId);
}

// 實現函式的宣告,如果在mustNotHaveFlags裡面,請求會被直接彈掉,通知不會被取消。
boolean cancelAllNotificationsInt(String pkg, int mustHaveFlags,
int mustNotHaveFlags, boolean doit, int userId)
{

...
}

從中間可以看到,對於不是系統UID的使用者來說,如果Notification帶有FLAG_FOREGROUND_SERVICE標記,你是取消不掉的,這類通知只有系統能取消,而給使用者的唯一入口就是Service#stopForegroundService,在呼叫這個介面的時候,會將前臺狀態置為false,如果傳入引數為true,再同時把Notification給cancel掉。看似沒有漏洞,然而聰(jian)明(zha)的人還是很多很多的。stop是單向的先取消前臺狀態,然後cancel notification。也就是說,cancel的時候就不會再去修改service的狀態了。所以,假如我同時啟動兩個service,並且將他們同時置為前臺狀態,然後共享同一個NotificationID,也是就說,此時會出現兩個前臺服務,但通知管理器裡只有一個關聯的通知。 這時我們在其中一個服務中呼叫stopForeground(true),這個服務前臺狀態會被取消,同時狀態列通知也被移除。*BUTTTTT!* 另外一個服務呢?他並沒有受到影響,還是前臺服務狀態,但是此時,狀態列通知已經沒了! 這就是支付寶的黑科技。

下面是一個示例程式,Service名字就叫AlipayService啦:sneaky_foreground_service. 第一個圖裡面那個和支付寶一起不會被幹掉的就是它了。支付寶的service因為還被其他程序繫結,所以顯示 服務正在被 支付寶 使用, 而這個Circles純粹是演示用,就懶得整了。

原文地址: http://zhoujianghua.com/2015/07/28/black_technology_in_alipay/

相關推薦

支付後臺科技

近期支付寶升級到了9.0,除了加入微信功能外,還新增了金鐘罩功能,不要說普通的各種加速球,火箭神馬的不能殺死他外,連格外牛逼的綠色守護也奈何不了他。在綠色守護裡面,支付寶始終顯示為“服務正在被 支付寶 使用”,不會自動休眠,惱火死了。那麼問題來了,他是怎麼做到的呢? 支付寶

WebView網頁中使用到支付調起來,提示ERR_UNKNOWN_URL_SCHEME

ace ngs new repl try 不一定 ring 可能 sys 在WebView中如果使用到支付寶,需要添加以下代碼,否則操作系統會將支付寶的URL攔截,導致你打不開支付寶頁面。 mWebView.setWebViewClient(new WebViewClie

安卓後臺保活科技 播放無聲音樂

1、準備一段無聲的音訊,新建一個播放音樂的Service類,將播放模式改為無限迴圈播放。在其onDestroy方法中對自己重新啟動。 public class PlayerMusicService extends Service { private final static String TAG

支付一個被人關注的隱私保護細節,你發現了嗎?

11月29日訊息 ,支付寶正式對外宣佈,支付寶全球使用者數已經超過9億,其中,在國內的活躍使用者中,70%的使用者使用3項及以上支付寶的服務。 在我們的日常生活中,可以說只要有智慧手機就一定會安裝支付寶,使用頻率也和微信、QQ等不相上下。 但你有沒有注意到,支付寶切換到後臺之後顯示介面會主動

【完美解決】WebView網頁中使用到支付調起來,提示ERR_UNKNOWN_URL_SCHEME

在WebView中如果使用到支付寶,需要新增以下程式碼,否則作業系統會將支付寶的URL攔截,導致你打不開支付寶頁面。 webView.setWebViewClient(new WebViewC

支付公眾存款堪比建行,為啥黑客支付

維護 安全 用戶 數據保護 數量 全世界 學習 自啟 升級 首先支付寶乃至阿裏巴巴整個核心平臺的網絡在08年大規模升級維護後,不誇張的說和五角大樓一個安全級別,這並非說黑客團隊攻不進去,而是黑進去以後的數據連鎖機制無人可破,數據保護有自啟和人為兩種,觸動後的結果就是阿裏巴巴

【轉載】史上最全:TensorFlow 好玩的技術、應用和你知道的科技

tube map 高性能 知識 seq 出現 執行時間 mes lex 【導讀】TensorFlow 在 2015 年年底一出現就受到了極大的關註,經過一年多的發展,已經成為了在機器學習、深度學習項目中最受歡迎的框架之一。自發布以來,TensorFlow 不斷在完善並增加新

iOS 手機沒有安裝支付的情況下,調支付網頁的解決的方法

sar inf order 手機 tin popu 全部 shared bject NSArray *array = [[UIApplication sharedApplication] windows]; UIWindow* win=[array objectAt

win10 當前操作環境支持支付控件 完美解決辦法

配置 div 接下來 下載 .cn 用戶 重要 分享 alipay 第一步,修改系統配置 在運行中輸入“gpedit.msc”打開本地組策略編輯器: 打運行窗口的方法是:按win鍵+R (按下win鍵再按R鍵之後 同時松開) w

支付老大位置保?第三方支付江湖變數依舊

auto 很快 問題 商業 頭條 許可 play 百度 應對 比達咨詢2017年第2季度中國第三方移動支付市場發展報告顯示,第2季度的第三方移動支付市場交易規模中,支付寶占51.9%,財付通占34.1%。這就意味著,在目前的第三方移動支付市場中,支付寶和財付通雙雄格局已定

支付app支付java後臺流程及原理分析

system 分析 req eterm 格式 prop 通過 false 由於 java版支付寶app支付流程及原理分析   本實例是基於springmvc框架編寫 一、流程步驟 1.執行流程 當手機端app(就是你公司開發的a

android 集成支付app支付(原生態)-包括android前端與java後臺

請求 call 修改 quest ali log gif 操作 asm 本文講解了 android開發的原生態app集成了支付寶支付, 還提供了java後臺服務器處理支付寶支付的加密代碼, app前端與java後臺服務器使用json數據格式交互信息,java後臺服務主要用來

[科技]市面上太常見的cin掛和cout掛

str fine n+1 register () sync ans 版本 stat CCPC賽後摸魚搞了個新的奇怪外掛 這裏貼上利用sgetn和sputn來實現的讀入讀出掛,理論上比fread更優 期望在賽中TLE的代碼能強行卡過去hhh 利用小規模的Codeforces

支付等大型支付系統後臺系統是如何對賬和風控的

作者:天順 連結:http://www.zhihu.com/question/20091391/answer/15591658 來源:知乎 著作權歸作者所有,轉載請聯絡作者獲得授權。 先扯淡一下對賬,這坑有點大,容我慢慢填。剛剛打了半小時的草稿由於沒儲存,宕機後被系統吃掉了……知乎貌似原來有自動儲存

針對APP的後臺支付程式碼(微信和支付

APP支付: 1.微信支付: 這是app支付時,一個完整的流程 1.1首先要去微信開放平臺註冊,並建立APP 1.2取得微信支付的許可權 1.3 商戶平臺有公眾號平臺和APP平臺兩種,一定要是APP平臺,可以在下面這個地方

針對APP的後臺支付代碼(微信和支付

pri pac edi all stat 微信開放平臺 gate java web 公鑰 APP支付: 1.微信支付: 這是app支付時,一個完整的流程 1.1首先要去微信開放平臺註冊,並創建APP 1.2取得微信支付的權限 1.3 商戶平臺有公眾號平臺和APP平

11月16日科技聯播:香港地鐵正式接入港版支付;官方證實正調查滴滴優步併購案

香港地鐵正式引入支付寶,2020年將能掃碼進站;滴滴優步合併案仍未完結,市場監管總局迴應正進行反壟斷調查;Facebook否認因庫克批評而禁用iPhone;拼多多遭美做空機構質疑,公司表示財務報表完全符合要求;一起來看今天的科技快訊: 香港地鐵接入港版支付寶,計劃2020年可掃碼乘車 香港地鐵今日宣佈

後臺技術大揭祕,看這篇你雙十一要損失幾個億!

轉眼間雙十一來了, 聽說你已經把寶貝提前收藏, 只待今天瘋狂“剁手” 那麼問題來了,除了買買買, 你需要程式猿男朋友嗎? 會寫程式碼搶秒殺的那種, 為了你雙十一的便利,我什麼都願意, 但請發現我默默的付出,記住我的好! 據不完全統計,正是因為大家熱情的刷刷刷,阿里巴巴

微信H5 使用瀏覽器能喚起支付小程式

記錄一下,自己遇到的一些問題: 業務需求:  h5放在微信公眾號 和 支付寶生活號裡面, 在公眾號登入H5時,點選付款需要進入 支付寶小程式 遇到的問題  : 1.微信直接無法調起支付寶: 這邊可以參考微信公眾平臺無法使用支付寶收付款的解決方案整合:https:/

除了支付,微信也能查詢賬單了!再也擔心錢花哪去了!

通常大家在使用微信或者支付寶的時候,都知道支付寶的賬單查詢在【我的】--【賬單】裡面查詢。但是使用微信支付時,卻不知道微信支付賬單在哪裡。 今天,小編就和大家分享一下微信支付賬單在哪裡查詢,以後,就能輕鬆檢視以往的支付記錄以及賬單了! 1. 開啟微信主頁,點選【我】--【錢包】。