본문 바로가기

Android/File

안드로이드/Android 루팅 여부 확인 하기

안드로이드/Android 루팅 여부 확인 하기

안드로이드 프로젝트를 진행하면서 루팅에 대한 체크 여부를 확인해야 할때가 있습니다. 그런데 루팅이란 무었일까요?

루팅이란 '안드로이드 기기에서 최고관리자 권한을 얻는 것'으로 생각하시면 됩니다. 어쩌면 아이폰에서의 탈옥(Jail Break)과 비슷하다 생각하셔도 될 것 같습니다. 아이폰에서 탈옥을 한다고 해도 당장 아무것도 달라지는 것은 없습니다. 시디아(Cydia)를 통해 앱스토어에서는 지원되지 않는 어플을 다운받고 나서야 비로소 탈옥의 이점을 느낄 수 있습니다. 
 
마찬가지로 안드로이드 기기에서 루팅을 한다고 해서 당장 달라지는 것은 없습니다. 특정한 어플을 다운받아 실행시켰을 때 해당어플이 -루팅 이전에는 접근할 수 없었던- 시스템 영역을 임의로 수정하는 것이 가능하도록 만드는 것이 루팅입니다. 또한 탐색기 어플로 기기 내부의 파일들을 보는 것 뿐만아니라 수정하는 것도 가능해집니다.

이러한 권한에 대한 문제나 보안, 루팅 때문에 일어나는 문제가 있기 때문에 프로젝트를 진행할 시 루팅 여부를 판단해서 제어해야 하는데요. 현재 안드로이드 폰에서 루팅 여부를 체크하는 방법은 아래의 방법입니다.

 
try {
	Runtime.getRuntime().exec("su");
} catch ( Exception e) {
	// 루팅 안되있으면 Exception
	Log.d("test", "rooting X");
}


위에서 보시는 것과 같이 루팅이 되어있다면 정상 작동하고, 루팅이 되어있지 않다면 Exception이 떨어집니다. 왜냐하면 su 는 시스템의 root권한을 얻는 명령인데, 루팅된 폰에서 실행되기 때문입니다.

그래서 요즘 루팅 프로그램은 일시적으로 su 명령을 안먹도록 하는 방법도 갖추고 있다는데, 이럴때는 system/bin/su 혹은 system/xbin/su Path 가 있는지 확인하면 되겠습니다. 만약 루팅 프로그램이 이 su 명령 자체도 바꾸어 버린다면 (위치를 바꾸거나 이름을 바꾸면) 대략 난감한 상황이 되는데, 이럴때는 뭐 폰 제조사에서 루팅 체크하는 특별한 루틴을 넣어서 확인하도록 하는 방법을 강구해봐야 겠습니다.

위에서 언급한 것을 응용해서 su 대신에 다른 시스템 명령을 넣으면 안드로이드 시스템 명령을 실행할 수 있습니다.


현재 대부분의 금융어플이나 뱅킹어플등에서는 아래의 4개의 파일 Path 여부를 체크해서 루팅 여부를 판단하고 있는데요. 루팅을 한 폰으로는 이러한 금융 어플들을 사용할 수 없기 때문에 , 루트익스플로러를 사용해서 아래 파일을 삭제하시면 됩니다.
  
대부분 감지하는 어플이 아래 데이타 파일이 있는지 검사하는게 일반적입니다.

/system/bin/su
/system/xbin/su
/system/app/superuser.apk 
/data/data/com.noshufou.android.su

위의 파일들을 삭제하면 금융어플 잘 돌아가지만 루팅은 해제 됩니다.


위의 4가지 파일들을 체크하는 로직을 만들어봤는데요, 루팅한 폰으로 테스트를 해보진 못했는데 사용 하실 분은 가져다 쓰시기 바랍니다. 작동원리는 먼저 su파일을 실행해서 System 권한이 풀려있는지 여부를 확인하고, 루팅 의심 파일들의 존재 여부를 확인하는 코드 입니다.^^

package arabiannight.tistory.com;

import java.io.File;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;

public class TestRootingCheckActivity extends Activity {

	public static final String ROOT_PATH = Environment.
            getExternalStorageDirectory() + "";
	public static final String ROOTING_PATH_1 = "/system/bin/su";
	public static final String ROOTING_PATH_2 = "/system/xbin/su";
	public static final String ROOTING_PATH_3 = "/system/app/SuperUser.apk";
	public static final String ROOTING_PATH_4 = "/data/data/com.noshufou.android.su";
	
	public String[] RootFilesPath = new String[]{
			ROOT_PATH + ROOTING_PATH_1 ,
			ROOT_PATH + ROOTING_PATH_2 , 
			ROOT_PATH + ROOTING_PATH_3 , 
			ROOT_PATH + ROOTING_PATH_4
	};
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		boolean isRootingFlag = false;

		try {
			Runtime.getRuntime().exec("su");
			isRootingFlag = true;
		} catch ( Exception e) {
			// Exception 나면 루팅 false;
			isRootingFlag = false;
		}
		
		if(!isRootingFlag){
			isRootingFlag = checkRootingFiles(createFiles(RootFilesPath));
		}
		
		Log.d("test", "isRootingFlag = " + isRootingFlag);
	}

	/**
	 * 루팅파일 의심 Path를 가진 파일들을 생성 한다.
	 */
	private File[] createFiles(String[] sfiles){
		File[] rootingFiles = new File[sfiles.length];
		for(int i=0 ; i < sfiles.length; i++){
			rootingFiles[i] = new File(sfiles[i]);
		}
		return rootingFiles;
	}
	
	/**
	 * 루팅파일 여부를 확인 한다.
	 */
	private boolean checkRootingFiles(File... file){
		boolean result = false;
		for(File f : file){
			if(f != null && f.exists() && f.isFile()){
				result = true;
				break;
			}else{
				result = false;
			}
		}
		return result;
	}
}




파일첨부 : 
출처 : 
http://blog.naver.com/PostView.nhn?blogId=softdx&logNo=60149126708
출처 : 
http://xorlife.tistory.com/354