天天看點

Android 二:root 手機的原理 - happy劉藝

Android 二:root 手機的原理

前面講如何利用adb 指令擷取root權限,是基于手機已經被root過。如果手機,還沒被root,則可用一下方法root

轉載:http://www.juapk.com/thread-2000-1-1.html 輕描淡寫編輯

一、 概述

本文介紹了android中擷取root權限的方法以及原理,讓大家對android玩家中常說的“越獄”有一個更深層次的認識。

二、 Root的介紹

1.       Root 的目的

可以讓我們擁有掌控手機系統的權限,比如删除一些system/app下面的無用軟體,更換開關機鈴聲和動畫,攔截狀态欄彈出的廣告等。

2.       Root的原理介紹

谷歌的android系統管理者使用者就叫做root,該帳戶擁有整個系統至高無上的權利,它可以通路和修改你手機幾乎所有的檔案,隻有root才具備最進階别的管理權限。我們root手機的過程也就是獲得手機最高使用權限的過程。同時為了防止不良軟體也取得root使用者的權限,當我們在root的過程中,還會給系統裝一個程式,用來作為運作提示,由使用者來決定,是否給予最高權限。這個程式的名字叫做Superuser.apk。當某些程式執行su指令想取得系統最高權限的時候,Superuser就會自動啟動,攔截該動作并作出詢問,當使用者認為該程式可以安全使用的時候,那麼我們就選擇允許,否則,可以禁止該程式繼續取得最高權限。Root的過程其實就是把su檔案放到/system/bin/ Superuser.apk 放到system/app下面,還需要設定/system/bin/su可以讓任意使用者可運作,有set uid和set gid的權限。即要在android機器上運作指令:adb shell chmod 4755 /system/bin/su。而通常,廠商是不會允許我們随便這麼去做的,我們就需要利用作業系統的各種漏洞,來完成這個過程。

特别說明:我們燒機中的Eng版本并沒有Root權限

3.       Root的方法

從Root的原理我們了解到,root過程分三步:

a.       adb push su /system/bin

b.       adb push SuperUser.apk /system/app

c.       adb shell chmod 4755 /system/bin/su

若系統是eng版的,做到以上三步,那麼我們Root就大功告成,但實際是不行的。為什麼呢?原因有三:

1、user版的/system路徑是隻讀權限,不能簡單寫入

2、 chmod需要Root權才能運作(死循環了)

3、有些系統在啟動時會自動将su的4755權限設成755,甚至直接删除su

那麼針對這種情況,我們怎麼辦呢?非常簡單:燒一個eng版本的boot.img就行了

可以用展訊的燒錄工具,或者用fastboot模式從sd卡燒一個boot.img檔案即可

至此,我們Root就成功了,可以用R.E(Root Explorer)在根目錄建立和删除檔案。

三、 深入了解Root機制

其流程是:

1.       Su 被使用者調用

2.       Su 建立了一個socket監聽

3.       Su 向Superuser發送了一個廣播,說是有一個程式要請求root

4.       Su 等待socket 資料接收。有逾時處理。

5.       Superuser 界面收到廣播後,彈出一個對話框,詢問使用者

6.       Superuser 向傳來的資料中的socket寫回使用者應答結果。

7.       Su 根據socket得到的結果處理應該不應該繼續執行

8.       完成提權管理

superuser.apk這個程式是root成功後,專門用來管理root權限使用的,防止被惡意程式濫用。

源碼位址: http://superuser.googlecode.com/svn/trunk

我們有兩點疑問:

1.  superuser是怎麼知道誰想用root權限? 

2.  superuser是如何把使用者的選擇告訴su程式的?

即superuser和su程式是如何通訊的,他們倆位于不通的時空,一個在java虛拟中,一個在linux的真實程序中。

superuser共有兩個activity: SuperuserActivity和 SuperuserRequestActivity ,其中SuperuserActivity主要是用來管理白名單的,就是記住哪個程式已經被允許使用root權限了,省的每次用時都問使用者。

SuperuserRequestActivity 就是用來詢問使用者目前有個程式想使用root權限,是否允許,是否一直允許,即放入白名單。

這個白名單比較關鍵,是一個sqlite資料庫檔案,位置:

/data/data/com.koushikdutta.superuser/databases/superuser.sqlite

上文說過,root的本質就是往 /system/bin/下放一個su檔案,不檢查調用者權限的su檔案。普通程式可以調用該su來運作root權限的指令。superuser.apk中就自帶了一個這樣的su程式。一開始superuser會檢測/system/bin/su是否存在:

File su =

new

File(

"/system/bin/su"

);

// 檢測su檔案是否存在,如果不存在則直接傳回

if

(!su.exists())  {

Toast toast = Toast.makeText(

this

,

"Unable to find /system/bin/su."

, Toast.LENGTH_LONG);

toast.show();

return

;

}

//如果大小一樣,則認為su檔案正确,直接傳回了事。

if

(su.length() == suStream.available())

{

suStream.close();

return

;  

//

}

// 如果檢測到/system/bin/su檔案存在,但是不對頭,則把自帶的su先寫到"/data/data/com.koushikdutta.superuser/su"

//再寫到/system/bin/su。

byte

[] bytes =

new

byte

[suStream.available()];

DataInputStream dis =

new

DataInputStream(suStream);

dis.readFully(bytes);

FileOutputStream suOutStream =

new

FileOutputStream(

"/data/data/com.koushikdutta.superuser/su"

);

suOutStream.write(bytes);

suOutStream.close();

Process process = Runtime.getRuntime().exec(

"su"

);

DataOutputStream os =

new

DataOutputStream(process.getOutputStream());

os.writeBytes(

"mount -oremount,rw /dev/block/mtdblock3 /system\n"

);

os.writeBytes(

"busybox cp /data/data/com.koushikdutta.superuser/su /system/bin/su\n"

);

os.writeBytes(

"busybox chown 0:0 /system/bin/su\n"

);

os.writeBytes(

"chmod 4755 /system/bin/su\n"

);

os.writeBytes(

"exit\n"

);

os.flush();

有程序使用root權限,superuser是怎麼知道的呢,關鍵是句:

sprintf(sysCmd, "am start -a android.intent.action.MAIN

                                    -n com.koushikdutta.superuser/com.koushikdutta.superuser.SuperuserRequestActivity

                                 --ei uid %d --ei pid %d > /dev/null", g_puid, ppid);

  if (system(sysCmd))

   return executionFailure("am.");

   原理是am指令,am的用法:

usage: am [subcommand] [options]

start an Activity: am start [-D] [-W] <INTENT>

-D: enable debugging

-W: wait

for

launch to complete

start a Service: am startservice <INTENT>

send a broadcast Intent: am broadcast <INTENT>

start an Instrumentation: am instrument [flags] <COMPONENT>

-r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT)

-e <NAME> <VALUE>: set argument <NAME> to <VALUE>

-p <FILE>: write profiling data to <FILE>

-w: wait

for

instrumentation to finish before returning

start profiling: am profile <PROCESS> start <FILE>

stop profiling: am profile <PROCESS> stop

<INTENT> specifications include these flags:

[-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]

[-c <CATEGORY> [-c <CATEGORY>] ...]

[-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]

[--esn <EXTRA_KEY> ...]

[--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]

[-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]

[-n <COMPONENT>] [-f <FLAGS>]

[--grant-read-uri-permission] [--grant-write-uri-permission]

[--debug-log-resolution]

[--activity-brought-to-front] [--activity-clear-top]

[--activity-clear-when-task-reset] [--activity-exclude-from-recents]

[--activity-launched-from-history] [--activity-multiple-task]

[--activity-no-animation] [--activity-no-history]

[--activity-no-user-action] [--activity-previous-is-top]

[--activity-reorder-to-front] [--activity-reset-task-

if

-needed]

[--activity-single-top]

[--receiver-registered-only] [--receiver-replace-pending]

[<URI>]

還有個疑點,就是su怎麼知道使用者是允許root權限還是反對呢?原來是上面提到的白名單起來作用,superuser把使用者的選擇放入:

/data/data/com.koushikdutta.superuser/databases/superuser.sqlite   資料庫中,然後su程序再去讀該資料庫來判斷是否允許。

static

int

checkWhitelist()

{

sqlite3 *db;

int

rc = sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL);

if

(!rc)

{

char

*errorMessage;

char

query[

1024

];

sprintf(query,

"select * from whitelist where _id=%d limit 1;"

, g_puid);

struct whitelistCallInfo callInfo;

callInfo.count =

;

callInfo.db = db;

rc = sqlite3_exec(db, query, whitelistCallback, &callInfo, &errorMessage);

if

(rc != SQLITE_OK)

{

sqlite3_close(db);

return

;

}

sqlite3_close(db);

return

callInfo.count;

}

sqlite3_close(db);

return

;

}

四、 資源檔案的擷取

從上文的源碼位址擷取源代碼,替換系統的system/extras/su/下面的su.c和Android.mk檔案,使用編譯指令 ./mk td28 u adr system/extras/su/編譯成功後會生成out/target/product/hsdroid/system/xbin/su檔案,而Superuser.apk就是普通的apk檔案,都在源碼位址裡面可以下載下傳,下載下傳後倒入到eclipse即可直接運作。

五、 總結

在閱讀完本文後,可以站在專業的角度了解root的真正原理,以及有使用者有需求時我們可以幫助其快速的解決問題。

Android手機Root授權原理細節全解析

判斷手機是否root了

 轉載二:

2、可以修改根目錄下的default.prop提權:

根目錄預設是不允許修改的,執行

mount -o remount,rw rootfs /
      

用vi打開default.prop,找到ro.secure,修改為ro.secure=0,儲存後重新開機,再adbshell一下,就會有root權限了