日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

那些年Android黑科技①:只要活着,就有希望

發布時間:2025/3/15 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 那些年Android黑科技①:只要活着,就有希望 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:
這個世界上手機有三大系統,蘋果、 安卓、 中國安卓 。本篇強烈呼吁大家不要去做哪些違反用戶體驗的黑科技功能,研究研究玩玩就好了啦。全當增長技術,在真實的項目開發中盡量能不用就不要用得好。道理大家都懂的。

目錄

那些年Android黑科技①:只要活著,就有希望

  • android應用內執行shell
  • 雙進程保活aidl版
  • 雙進程保活jni版
  • 保活JobService版

那些年Android黑科技②:欺騙的藝術

  • hook技術
  • 欺騙系統之偷梁換柱

那些年Android黑科技③:干大事不擇手段

  • 應用卸載反饋
  • Home鍵監聽
  • 桌面添加快捷方式
  • 無法卸載app(DevicePolicManager)
  • 無網絡權限偷偷上傳數據

android應用內執行shell

android系統本身是Linux作為內核,我們一般開發中使用 adb shell 命令來操作。但其實本身在應用內也是可以執行的。強大的地方是在root的情況下,可以實現靜默安裝和操作一切你想在設備內做事情。其方法如下。

調用工具代碼:

/*** 是否是在root下執行命令** @param commands 命令數組* @param isRoot 是否需要root權限執行*/public static void execCmd(String[] commands, boolean isRoot) {//便于觀看刪除來不影響的部分代碼,完整的可以在文中的github里找到。process = Runtime.getRuntime().exec(isRoot ? "su" : "sh");os = new DataOutputStream(process.getOutputStream());for (String command : commands) {if (command == null) continue;os.write(command.getBytes());os.writeBytes("\n");os.flush();}os.writeBytes("exit\n");os.flush();result = process.waitFor();successMsg = new StringBuilder();errorMsg = new StringBuilder();successResult = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));}

沒有root權限的情況下在屏幕上操作,實測可被執行的命令只有swipe和部分keyevent可以生效,其余的可以通過adb的方式調用成功。但是一但在應用內通過shell是不可以的。這確保了android手機的安全。

其中keyevent 返回鍵 音量鍵可以調用 而home按鍵這種則不可以。
如果你試圖調用dumpsys activity activities 來查看。會拋出權限的異常如下。實測中我有申請權限,但一樣無法在應用內部調起。

Permission Denial: can't dump ActivityManager from from pid=12414, uid=10369 without permission android.permission.DUMP0
image.png

使用參考:


Root情況下靜默安裝:

String command = "LD_LIBRARY_PATH=/vendor/lib:/system/lib pm install " +"apk路徑";ShellUtils.execCmd(command, ture);

代碼:https://github.com/BolexLiu/AndroidShell


雙進程保活aidl版 (android5.0以下)

原理介紹:實現的機制并不復雜,通過AIDL的方式開啟兩個服務分別在不同進程中啟動,然后互相守護監聽對方是否被關閉,如果有一方被斷開連接,另一方測重啟服務。因為android在5.0之前銷毀進程是一個一個銷毀的,他并不能同時銷毀兩個。所以可以做這件事。(被修改的rom除外,比如華為4.4就不行,但三星可以。)

1.配置服務進程。注意process屬性會獨立在另一個進程中。

<service android:name=".Service.LocalService" /><service android:name=".Service.RemoteService" android:process=".Remote"/>

2.我們擁有兩個服務LocalService RemoteService。項目運行后第一件事,同時啟動服務。

startService(new Intent(this, LocalService.class));startService(new Intent(this, RemoteService.class));

3.在LocalService中綁定RemoteService并監聽對方的創建和銷毀,RemoteService中的實現也一樣。

@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {super.onStartCommand(intent, flags, startId);Log.e(TAG, TAG + " onStartCommand");// 綁定遠程服務bindService(new Intent(this, RemoteService.class), mLocalServiceConnection, Context.BIND_IMPORTANT);return START_STICKY;}//連接遠程服務class localServiceConnection implements ServiceConnection {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {try {// 與遠程服務通信MyProcessAIDL process = MyProcessAIDL.Stub.asInterface(service);Log.e(TAG, "連接" + process.getServiceName() + "服務成功");} catch (RemoteException e) {e.printStackTrace();}}@Overridepublic void onServiceDisconnected(ComponentName name) {// RemoteException連接過程出現的異常,才會回調,unbind不會回調// 監測,遠程服務已經死掉,則重啟遠程服務Log.e(TAG, "遠程服務掛掉了,遠程服務被殺死");// 啟動遠程服務startService(new Intent(LocalService.this, RemoteService.class));// 綁定遠程服務bindService(new Intent(LocalService.this, RemoteService.class), mLocalServiceConnection, Context.BIND_IMPORTANT);}}

代碼:https://github.com/BolexLiu/DoubleProcess


雙進程保活jni版 (android5.0以下)

原理介紹:這種雙進程守利用了Linux子進程在父進程被干掉后還能運行而實現。所以我們要做的是通過java去fork一段C的代碼。通過動態鏈接庫封裝起來。然后在C代碼里不斷輪訓父進程的ppid是否存活。如果掛掉了側重新喚醒。

1.配置服務進程。注意process屬性會獨立在另一個進程中。

<serviceandroid:name=".service.DaemonService"android:process=":daemon"></service>

2.在DaemonService里利用靜態代碼塊調起so。

public class DaemonService extends Service{// 便于閱讀省略無關代碼,詳情去移步至github···static {System.loadLibrary("daemon");} }

3.so中的C代碼輪訓進程判斷是否存活。

//便于閱讀省略無關代碼,詳情去移步至github··· //fork子進程,以執行輪詢任務pid_t pid = fork();LOGI("fork=%d", pid);if (pid < 0) { // fork失敗了} else if (pid == 0) { // 可以一直采用一直判斷文件是否存在的方式去判斷,但是這樣效率稍低,下面使用監聽的方式,死循環,每個一秒判斷一次,這樣太浪費資源了。int check = 1;while (check) {pid_t ppid = getppid();LOGI("pid=%d", getpid());LOGI("ppid=%d", ppid);if (ppid == 1) {LOGI("ppid == 1");if (sdkVersion >= 17) {LOGI("> 17");int ret = execlp("am", "am", "startservice", "--user", "0","-n", name,(char *) NULL);} else {execlp("am", "am", "startservice", "-n",name,(char *) NULL);LOGI("else");}check = 0;} else {}sleep(1);}}

感謝CharonChui開源代碼。處應該有掌聲!

代碼:https://github.com/CharonChui/DaemonService

保活 JobService版 (android5.0++)

原理: JobService是官方推薦的方式,即使app完成被殺死的狀態下也能調用起來,本質是向系統注冊一個任務。通過getSystemService拿到系統的JobScheduler。然后通過JobInfo.Buidler進行構造。需要注意的是一定要指定被觸發的條件。比如:設備充電中、空閑狀態、連接wifi... 非常類似以前的廣播保護原理。但是實現不一樣。這次是我們反向注冊給系統,而不是接收系統的廣播。

1.在AndroidManifest進行配置添加permission屬性

<serviceandroid:name=".MyJobService"android:permission="android.permission.BIND_JOB_SERVICE" />

2.MyJobServer繼承JobService類:

@Overridepublic boolean onStartJob(JobParameters params) {//該方法被觸發調用 可以做喚醒其他服務的操作return true;}@Overridepublic boolean onStopJob(JobParameters params) {return true;}

3.在合適的地方向系統注冊

JobScheduler scheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); ComponentName componentName = new ComponentName(MainActivity.this, MyJobService.class); JobInfo.Builder builder = new JobInfo.Builder(++mJobId, componentName); String delay = mDelayEditText.getText().toString(); if (delay != null && !TextUtils.isEmpty(delay)) { //設置JobService執行的最小延時時間 builder.setMinimumLatency(Long.valueOf(delay) * 1000); } String deadline = mDeadlineEditText.getText().toString(); if (deadline != null && !TextUtils.isEmpty(deadline)) { //設置JobService執行的最晚時間 builder.setOverrideDeadline(Long.valueOf(deadline) * 1000); } boolean requiresUnmetered = mWiFiConnectivityRadioButton.isChecked(); boolean requiresAnyConnectivity = mAnyConnectivityRadioButton.isChecked(); //設置執行的網絡條件 if (requiresUnmetered) { builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED); } else if (requiresAnyConnectivity) { builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); } builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked());//是否要求設備為idle狀態 builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked());//是否要設備為充電狀態 scheduler.schedule(builder.build());

注意jobScheduler無法兼容Android 5.0以下的設備,可以參考下面的項目,在低版本中也可以使用。

實際測試 :
研究了一段時間發現這個玩意,在國內的廠商定制過后的rom好多不起作用。 比如魅族 和小米上 如果把app殺死以后,這個服務也調用不起來了。但是在模擬器和aosp版本的Rom上是可行的。我測試時用的電池充電狀態來調用job服務。

代碼:https://github.com/evant/JobSchedulerCompat


第一部分就先到這里。后續還有兩篇續集會緊接著營養跟上,如果你覺得不錯可以關注我一波點個喜歡神馬的哈哈。



作者:香脆的大雞排
鏈接:http://www.jianshu.com/p/cb2deed0f2d8
來源:簡書

著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。



總結

以上是生活随笔為你收集整理的那些年Android黑科技①:只要活着,就有希望的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。