- ADB 사용법 추가 확인 주소 : http://developer.android.com/guide/developing/tools/adb.html#commandsummary
@ 안드로이드 파일시스템과 데이터 구조
: 물리 메모리와 파일시스템과 데이터 구조는 안드로이드 기기의 데이터 저장소를 위한 기본요소다. 그러한 요소들을 깊이 있게 이해하게 되면 안드로이드 기기를 잘 이해할 수 있을 뿐만 아니라 새롱누 파일시스템과 데이터 구조를 보게 되더라도 스스로 조사할수 있게 된다.
- yaffs2.tar.gz 를 다운 받아서 설치한 뒤 디바이스에 마운트해서 해당 값을 확인할 수 있다.
- Shared Preferences
-- boolean, float, int, long, strings 에 대한 값이 저장된다.
-- 경로 : /data/data/apk_pkg_name/shared_prefs
- SQLite 정보 위치 ( /data/data/com.android.webkit )
-- app_icons, app_cache, app_geolocation : 아이콘 DB 1개 , 웹 어플 데이터 캐시 1개, GPS 위치와 권한과 관련된 DB 2개
-- app_databases 웹사이트 지원을 위한 로컬 데이터 베이스 저장소를 제공하는 21개의 데이터 베이스
-- databases : 브라우저와 브라우저 캐시를 위한 데이터 베이스 3개
- db 보는 명령어
-- sqlite3 db.db
@ 안드로이드 포렌식 기술
: 안드로이드 기기에서 포렌식 이미지를 획득하기 위한 기술을 여러가지가 있다. 만약 분석 대상 기기가 패스코드로 보호돼 있다면 그것을 회피하거나 우회해서 데이터를 추출해야만 한다. 패스코드를 회피하기 위한 기술을 여러가지가 있지만 어느 상황에서나 항상 패스코드를 회피하는 것은 불가능하다. 일단 기기에 접근 가능하면 포렌식 분석가는 삭제되지 않은 데이터에 초점이 맞춰진 콘텐트 프로바이더를 통한 논리적인 데이터 획득이나 물리적인 데이터 획득 방법 중에서 어느 기술을 사요할 것인지 선택할 수 있다. 물리적 데이터 획득 기술은 이용하면 더 많은 데이터를 얻을 수 있지만 일반적으로 더 복잡한 분석 기술을 필요로 한다.
- APK 보안 검토 툴 : http://viaforensics.com/appwatchdog/
- AFLogical : 콘텐트 프로바이더로 접근할 수 있는 정보를 추출한다. viaForensics에서 무료 배포.
: 조사할 안드로이드 기기를 획득하는 것은 연구나 개발, 논의 에 있어서 매우 주요한 부분이지만 안드로이드 포렌식에서는 단지 시작일 뿐이다. 분석을 위해서는 논리적 물리적 기술이 모두 필요하다. 하지만, 물리적 데이터 획득 이후에 더 많은 양의 분석이 요구 된다. 이 부분에서 목적은 포렌식 분석가나 보안 엔지니어가 안드로이드 기기를 조사할 수 있는 기술, 심지어 포렌식 툴이 제대로 지원하지 못하는 파일시스템이라고 하더라도 그것을 조사할 수 있는 기술을 제공하는 것이다. 기존의 포렌식 툴과 리눅스 명령. 그리고 경우에 따라서는 헥스 분석을 사용하면 조사가 필요한 데이터 대부분을 분석할 수 있다.
- Hex : 포렌식 분석가의 좋은 친구
-- $ sudo apt-get install ncurses-hexedit // 매우 빠른 터미널 기반의 헥스 에디터; 다른 것을 써도 된다.
- strings 를 활용해서 정보의 갯수를 알 수 있다; 정보의 유/무
-- $ strings --all --radix=x mmssms.db | grep 312123123 | wc -l // 해당 정보 312123123가 몇 개 존재하는 지 알수 있다.
- FAT 포렌식 분석
-- log2timeline을 이용한다. 그 전에 앞에서 활용했던 SD 카드 이미지 만들기, TSK의 mmls로 이미지를 조사하고, 이미지를 마운트해야 한다. ( 기타 추가 설명은 p 384에 있다. )
하지만 이런 경우 Decor되기 위한 View로 변환(.getDecorView())되어 버린 액티비티들은, 원래 액티비티가 가지고 있는 라이프 사이클을 완전하게 수행하지 못하게 되어버렸습니다.
그래서 Intent 플래그 중 FLAG_ACTIVITY_CLEAR_TOP 을 써서 계속해서 새로 호출하며 화면을 갱신하는 방법을 택하지 않았었나 생각되구요. (기본적으로 생성:onCreate()onDestroy()과 파괴:onDestroy()는 수행이 됨) ActivityGroup이라는 공통의 부모가 있기는 하지만, 자식 액티비티들간의 데이터의 교환도 어려웠구요.
어쨋든 이런 문제점들과, 태블릿의 특성인 한 화면 안에서 여러개의 액티비티를 동시에 보여주는것에 적합하게 나온것이 Fragment입니다.
액티비티 대신에 Fragment라는 녀석으로 조각 조각 따로 만들어 주는 거지요.
예전 방식이 리스트를 보여주는 액티비티 A에서 뭔가를 눌렀을 때, 그 내부 컨텐츠를 보여주는 액티비티 B로 이동하는 형식이었다면, Fragment는 한번에 리스트와 컨텐츠를 동시에 한 화면에서 볼 수 있게 해 주는 것입니다. 이때 왼쪽의 리스트 부분을 하나의 fragment로, 오른쪽의 컨텐츠 부분을 다른 하나의 fragment로 구성을 해주고, 이 둘을 가지고 있는 Activity가 존재하는 것이지요.
ActivityGroup에서의 Child Activity와 비교하여
생각해보면, ActivityGroup과 개념이 많이 다르지 않습니다. ActivityGroup은 Child Activity들을 View로 만들어서 화면에 보여주는 것이라면, Honeycomb에서는 View대신에 Fragment라는 것을 사용해서 Activity와 유사한 방식의 Lifecycle을 갖는 조금 다른 뷰를 만들어내서 화면에 보여주는게 된것이죠.
Activity 기반의 Lifecycle을 가지고 있기 때문에, 실제 액티비티 하나를 운용하는것 처럼 사용하면 됩니다.
Fragment는 일반 객체처럼 new 키워드를 사용해서 생성하게 됩니다. 기존에 액티비티에서 사용하는 startActivity와는 조금 다르죠.
또 한화면에 여러개의 Fragment를 동시에 보여줄 수 있기때문에, 한번에 보여지는 Fragment들간에 데이터 교환이 빈번하게 발생하게 되는데, Activity에서 하듯이 intent를 통해서 하는게 아닌, interface를 통해서 데이터를 교환하면 되기 때문에 상당히 편리해진것을 느낄 수 있습니다.
Fragment의 생성, Activity에 붙이기(Attach)
기본적인 Honeycomb, 태블릿 UI를 구성을 생각하면, 좌측에 리스트가 보이고, 우측에 리스트에서 선택한 컨텐츠가 보이는 형식일겁니다.
간단한 예제를 만들기 위해, 아래와 같이 세개의 클래스를 만들어줍니다.
ExampleFragmentActivity extends Activity ExampleListFragment extends Fragment ExampleContentFragment extends Fragment
// FragmentTransaction을 통해 Fragment에 대한 변경사항을 적용한다.
ft.commit();
}
생성은 일반적인 자바 객체를 생성하듯 new 를 사용해서 생성해줍니다.
// 왼쪽의 List로 사용할 ExampleListFragment를 생성한다. ExampleListFragment listFragment = newExampleListFragment();
액티비티에 붙이는 건, FragmentTransaction의 replace메소드를 이용합니다. // FragmentTransaction의 replace메소드를 통해, 액티비티에 붙인다. ft.replace(R.id.example_fragment_activity_ll_list_fragment, listFragment, TAG_LIST);
Activity로부터 Fragment 가져오기
Activity의 어느 메소드라도, Fragment를 액티비티에 붙인 이후에는, 아래와 같은 코드를 통해 Activity에 붙어있는 Fragment를 가져올 수 있습니다. 이때 String tag를 사용해서 가져올 수 있습니다. 태그는 위에서 액티비티에 프래그먼트를 붙일 때 사용했던 태그입니다.
- Fragment 는 Activity에 포함 가능한 sub activity로 볼 수 있는데, Activity 의 life cycle 과 비슷한 cycle 을 타고 간다. Fragment 도 Activity 처럼 extends 를 해서 작성 및 사용한다.
- Fragment 는 Xml 에서도 정의 가능한데 <fragment> 태그를 사용한다.
- Fragment 는 Back Stack 을 가지고 있다. 이것은 system 에서 관리해주는 activity back stack 과는 다르며, activity 에 유지되는, programmer 가 관리하는 back stack 이다.
- Fragment 의 life cycle 중 onCreate(), onCreateView(), onPause() 는 거의 반드시 기술한다. onCreate 는 생성시, onCreateView 는 View 최초 생성시 호출되며, onCreateView는 fragment의 root view 를 return 한다. onPause 는 activity life cycle 의 onPause 와 비슷하다.
- Fragment 의 sub class 들은 DialogFragment, ListFragment, PreferenceFragment 들이 있다.
- system 이 fragment 를 restore 할 때 ( 예를 들면 activity 의 restart ), fragment 들을 구분하기 위해서 fragment 에 id 를 부여해야 한다. 3가지 방법이 있는데, android:id 로 unique ID 를 주던가, android:tag 로 unique String 을 주면 된다. 둘 다 주지 않으면, system 이 container view 의 ID 를 사용한다.
- fragment 를 add, remove, replace 할 때는 "반드시" FragmentTransaction API 를 사용해야만한다. 다음과 같은 방법으로 해준다.
fragmentTransaction.add(R.id.fragment_container, fragment); // first param is viewgroup id.
fragmentTransaction.commit();
- fragment 를 UI 가 없는 녀석으로 만들어 background 작업을 하도록 사용할 수도 있다. 이때는 add( Fragment fragment, String tag ) 를 통해 등록을 한다. 이렇게 등록을 하면 onCreateView() 가 호출되지 않는다. 물론 구현할 필요도 없다. 등록시의 tag 는 findFragmentByTag() 를 통해 해당 fragment 에 접근하는데 쓰인다.
- FragmentManager 를 통해서 fragment 를 control 하는데 다음과 같은 일들을 할 수 있다.
1. findFragmentById 나 findFragmentByTag 를 통해서 fragment 를 얻어올 수 있다.
2. popBackStack() 을 통해 Activity 에서 BackKey 를 누른 것과 비슷한 효과를 낼 수 있다.
3. addOnBackStackChangedListener 를 통해 listener 등록도 가능하다.
4. FragmentTransaction 을 얻어 operation 을 할수도 있다.
- FragmentTransaction 을 통해, add(), remove(), replace(), commit() 등을 호출 가능하고, addToBackStack() 을 통해 activity 에서 관리하는 back stack 에 FragmentTransaction 을 등록 가능하다. BackKey 가 눌렸을 때 back stack 이 작동한다.
- fragment 가 addTobackStack() 을 통해 remove 되는 경우는 stopped state 에 들어가고, 그렇지 않을 경우에는 destory state 로 들어간다.
- commit() 전에 setTransition() API 를 통해, transition animation 을 줄 수 있다.
- commit() 된 transaction 은 바로 실행되지 않고, main thread 에 schedule 되어 처리된다.executePendingTransaction() 을 통해 commit() 된 녀석을 바로 실행시킬 수 있지만, 다른 thread 와의 work 에 dependency 가 있지 않는 한은 쓸 일이 없을 것이다.
- commit() 은 activity 가 state save 하기 전에 이루어져야 한다. state save 후에 commit() 이 불린다면 exception 이 발생한다. 만약 state save 와 관계없이, fragement 의 state 저장과 관련없게 작동하게 하려면 commit() 대신 commitAllowingStateLoss() 를 호출해줘야 한다.
- Fragment 에서 option menu를 구성하려면 onCreate() 에서 setHasOptionsMenu() 를 call 해주어야 한다. 그렇지 않으면, fragment의 onCreateOptionsMenu() 가 불리지 않는다. 마찬가지로, menu item 이 click 되면 onOptionsItemSelected() 가 호출된다.
- fragment 에도 registerForContextMenu() API 가 있으며, context menu 생성시 onCreateContextMenu() 가 불리고, item click 시 onContextItemSelected() 가 불린다.
- Fragment 에 전달되는 event 들은 사실 activity 가 먼저 받고, 그 다음에 fragment 에 전달이 되는 형태이다. 물론 activity 에서 다 처리하고, fragment 로 전달하지 않도록 하는 방법도 있다.
- fragment 도 bundle 에 state 를 저장할 수 있다. fragment 의 onSaveInstanceState() 에서 저장하고, onCreate(), onCreateView() 혹은 onActivityCreated() 에서 restore 해주면 된다.