1、首先從manifest.xml檔案中定位主要的java類。檔案主要代碼如下:
<application android:icon="@drawable/z4small" android:label="@string/z4root"> <activity android:name="z4root" android:theme="@style/Theme" android:launchMode="singleInstance" android:label="z4root" android:finishOnTaskLaunch="true" android:multiprocess="true" android:process=":three" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="Phase1" android:theme="@style/Theme" android:launchMode="singleInstance" android:label="Phase1" android:finishOnTaskLaunch="true" android:multiprocess="true" android:process=":three" android:screenOrientation="portrait"> </activity> <activity android:name="Phase2" android:theme="@style/Theme" android:launchMode="singleInstance" android:label="Phase2" android:finishOnTaskLaunch="true" android:multiprocess="true" android:process=":two" android:screenOrientation="portrait"> </activity> <activity android:name="PhaseRemove" android:theme="@style/Theme" android:launchMode="singleInstance" android:label="PhaseRemove" android:finishOnTaskLaunch="true" android:multiprocess="true" android:process=":four" android:screenOrientation="portrait"> </activity>
主類為z4root.java,Phase1.java,Phase2.java用來實現,一次性root和永久root功能。
2、進入z4root.java。
onCreate()方法中定義了3個按鈕的監聽器方法:rootbutton.setOnClickListener(new OnClickListener() ,temprootbutton.setOnClickListener(new OnClickListener() ,unrootbutton.setOnClickListener(new OnClickListener()。這三個按鈕對應程式運行介面的一次root、永久root和取消root。我只關心root過程,也就是前兩個方法,從代碼中可以看到它們都調用了Intent
i = new Intent(z4root.this, Phase1.class);startActivity(i);載入Phase1這個activity。
區別在於SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInt(PREFS_MODE, MODE_PERMROOT);
傳入的參數不同,用以區別暫時root、永久root和取消root(MODE_TEMPROOT=1, MODE_PERMROOT=0, MODE_UNROOT=2)。
上面三行代碼的解釋:sharedPreferences用於存取和修改軟體配置參數資料的介面,
1、getSharedPreferences(PREFS_NAME, 0);返回SharedPreferences屬性值,PREFS_NAME=“z4rootprefs”,一個檔案的應用,如果沒有該檔案則建立。
2、edit()修改SharedPreferences屬性值,在提交後生效。PREFS_MODE=“rootmode”
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);boolean AdsEnabled = settings.getBoolean(PREFS_ADS, true);if (AdsEnabled) {setContentView(R.layout.z4rootwadd);} else {setContentView(R.layout.z4root);}rootbutton = (Button) findViewById(R.id.rootbutton);unrootbutton = (Button) findViewById(R.id.unrootbutton);detailtext = (TextView) findViewById(R.id.detailtext);temprootbutton = (Button) findViewById(R.id.temprootbutton);rootbutton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if (disabled)return;disabled = true;Intent i = new Intent(z4root.this, Phase1.class);SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);SharedPreferences.Editor editor = settings.edit();editor.putInt(PREFS_MODE, MODE_PERMROOT);editor.commit();startActivity(i);finish();}});temprootbutton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if (disabled)return;disabled = true;Intent i = new Intent(z4root.this, Phase1.class);SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);SharedPreferences.Editor editor = settings.edit();editor.putInt(PREFS_MODE, MODE_TEMPROOT);editor.commit();startActivity(i);finish();}});unrootbutton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if (disabled)return;disabled = true;Intent i;if (forceunroot) {i = new Intent(z4root.this, Phase1.class);SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);SharedPreferences.Editor editor = settings.edit();editor.putInt(PREFS_MODE, MODE_UNROOT);editor.commit();} else {i = new Intent(z4root.this, PhaseRemove.class);}startActivity(i);finish();}});new Thread() {public void run() {dostuff();};}.start();}
3、Phase1.java
Phase1 這個Activity中主要的類是Phase1。onCreate()方法中通過run()方法調用都stuff()方法。這應該是實現root的關鍵方法。
public void dostuff() {PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "z4root");wl.acquire();saystuff("Saving required file...");try {SaveIncludedFileIntoFilesFolder(R.raw.rageagainstthecage, "rageagainstthecage", getApplicationContext());} catch (Exception e1) {// TODO Auto-generated catch blocke1.printStackTrace();}final int[] processId = new int[1];final FileDescriptor fd = Exec.createSubprocess("/system/bin/sh", "-", null, processId);Log.i("AAA", "Got processid: " + processId[0]);final FileOutputStream out = new FileOutputStream(fd);final FileInputStream in = new FileInputStream(fd);// final int[] processId_t = new int[1];// final FileDescriptor fd_t = Exec.createSubprocess("/system/bin/sh",// "-", null, processId_t);// Log.i("AAA", "Got processid_t: " + processId_t[0]);//// final FileOutputStream out_t = new FileOutputStream(fd_t);// final FileInputStream in_t = new FileInputStream(fd_t);new Thread() {public void run() {byte[] mBuffer = new byte[4096];// byte[] mBuffer_t = new byte[4096];int read = 0;while (read >= 0) {try {read = in.read(mBuffer);String str = new String(mBuffer, 0, read);Log.i("AAA", str);if (str.contains("Forked")) {Log.i("BBB", "FORKED FOUND!");saystuff("Forking completed");Intent intent = new Intent(getApplicationContext(), AlarmReceiver.class);PendingIntent sender = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);// Get the AlarmManager serviceAlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);// for (int i=5;i<120;i+=15) {Calendar cal = Calendar.getInstance();cal.add(Calendar.SECOND, 5);am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);// }// Get the AlarmManager servicesaystuff("Aquiring root shell...");wl.release();Thread.sleep(20000);finish();return;}if (str.contains("Cannot find adb")) {runOnUiThread(new Runnable() {@Overridepublic void run() {showDialog(SHOW_SETTINGS_DIALOG);}});}} catch (Exception e) {read = -1;e.printStackTrace();}}};}.start();try {String command = "chmod 777 " + getFilesDir() + "/rageagainstthecage\n";out.write(command.getBytes());out.flush();command = getFilesDir() + "/rageagainstthecage\n";out.write(command.getBytes());out.flush();saystuff("Running exploit in order to obtain root access...");} catch (Exception ex) {ex.printStackTrace();}}