고수 개발자가 아닌 일반 유저가 할 수 있는 이미지 파일 교체, 수정을 제외한 트윅 작업의 대부분은 sxml, smali 등의 텍스트 파일 수정입니다.

물론 수작업으로 하면 되는데 이걸 쉽게 반복할 수 있는 방법이 스크립트를 이용하는 것이지요.
제가 스크립트에 관심을 가지게 된 것도 이런 이유입니다.

feature.xml 을 수정만 하면 카메라 무음이 되던 시절입니다.
루익으로 파일을 열어서 라인을 찾고 true 로 바꾸었지요.
펌업이 있으면 매번 반복하는게 싫어서 구글링했던 정리해봅니다.

비지박스 명령 중에 sed 는 텍스트 파일을 수정, 삭제, 첨가 하는 기능이 있습니다.

#shutter sound menu
sed -i '/ShutterSoundMenu/s/false/true/g' /system/csc/feature.xml

-- 요 구문은 xml 파일에서 ShutterSoundMenu 라는 문구가 들어간 라인을 찾아서
s = substitute 대체 하라는 명령입니다. false 가 true 로 바뀌는 거지요.
-i 옵션은 대상 xml 파일을 직접 수정하는 옵션입니다.

#browser close menu
sed -i '/WEB/a<CscFeature_Web_AddOptionToTerminate>true</CscFeature_Web_AddOptionToTerminate>' /system/csc/feature.xml
sed -i '/WEB/a<CscFeature_Web_TerminateAppOnCloseAllAction>true</CscFeature_Web_TerminateAppOnCloseAllAction>' /system/csc/feature.xml

-- 요 구문은 없는 라인을 추가하는 명령입니다. WEB 이라는 단어가 들어간 라인 뒤에 a = add 하는 거지요. 그러니 이 명령은 false true 가 들어있지 않고 넣으려는 라인의 텍스트가 존재하는겁니다.
지우는 d delete 명령 옵션도 있으나 유저 입장에서 크게 쓰지 않는 기능입니다. 




자 이번엔 텍스트 파일 중에서 일부분만 뽑아내는 기능에 관한 설명입니다.
head, tail, awk 등으로 가능합니다.

head -n 4 text.txt | tail -n +2

-- 이 명령은 text.txt 파일에서 2째줄에서 4째줄까지만 뽑아줍니다.
head 는 문서의 앞부분을 자르는거고 반대로 tail은 뒷부분을 자르는거지요.
먼저 4째줄까지의 앞부분을 자르면 1에서 4까지 잘라질것이고 이걸 파이프 | 로 받아서 다시 2째줄 이후의 꼬리 부분을 자르면 남는건 2~4 줄 부분이 되는 겁니다.

cat text.txt | awk 'NR < 2 { next } { print } NR == 4 { exit }'

awk 로도 가능합니다.
(awk 는 개발자 3명의 이름 이니셜을 모아서 명명되었습니다. 아주 다양한 기능이 존재하는 명령이라 그 기능을 어떤 한 단어로 지정하기도 어렵습니다.)
cat 로 문서를 읽는데 행번호가 2보다 작으면 건너뛰고 크면 인쇄 print 합니다. 행번호가 4 가 되면 인쇄후 종료하게 됩니다.
head, tail 보다는 눈에 잘 들어옵니다. 물론 결과는 같습니다.


몇가지 예제를 설명하고 마차겠습니다.
외장메모리 쓰기 금지를 수정하는 방법과 환경설정에서 설치된 모든 폰트를 가능하게 하는 SPapa 님 트윅을 smali 파일에 적용하는 방법입니다.

파일은 첨부하고 핵심 내용만 설명합니다.

file=platform.xml
scode="android.permission.WRITE_EXTERNAL_STORAGE"
ecode="/permission"

slineno=$( grep -n $scode $file | cut -d":" -f1 )
elines=$( grep -n $ecode $file | cut -d":" -f1 )
해당 구문의 start 라인과 end 라인을 찾으려 합니다.

grep -n 명령은 특정 텍스트를 찾아주고 그 라인 번호를 함께 반환합니다.
357:android.permission.WRITE_EXTERNAL_STORAGE
이런 형식으로 결과를 보여주게 되지요
cut 명령은 -d":" -f1 은 콜론으로 라인을 나누어서 첫번째 부분을 가져온다는 말입니다.
그렇다면 결과는 357 숫자만 남게 되는거지요.
/permission은 그 파일에서 여러개 존재하게 되지요. 그래서 여러개의 숫자가 결과로 남게 됩니다.

for l in $elines ; do
  if [ "$l" -ge $slineno ] ; then
     elineno=$l
     break
  fi
done

이 구문은 그 여러개의 숫자 중에서 먼저 검색했던 end 라인값 중에서 start 라인보다 큰 첫번째 숫자를 구하면 해당 부분의 영역 첫줄과 마지막 줄을 알 수 있습니다.

그 줄번호를 알면 앞서 설명했던 방법으로 그 부분만 뽑을 수 있는거지요.

headno=`expr $slineno - 2`
head -n $headno $file > top_file
elineno=$((elineno+1))
tail -n +"$elineno" $file > bottom_file

요건 start 라인의 앞부분까지 top_file 로 자르고
end 라인 앞부분까지 botton_file 로 잘랐습니다.

cat top_file > mfile
cat >> mfile << "EOF"
    <permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
        <group gid="sdcard_r" />
        <group gid="sdcard_rw" />
        <group gid="media_rw" />
    </permission>
EOF
cat bottom_file >> mfile

잘라낸 앞부분을 mfie 에 저장하고
이어서  원하는 문구를 뒤에 붙이고
아까 잘라냈던 뒷부분을 마저 붙이면 수정된 텍스트가 생기게 됩니다.


마찬가지 방법입니다
file=FontListPreference.smali
scode1=".method"
scode2="checkFont(Ljava/lang/String;)Z"
ecode1=".end"
ecode2="method"

slineno=$( cat $file | grep -n $scode1 | grep $scode2 | sed "s/[^0-9]//g" )
elines=$( cat $file | grep -n $ecode1 | grep $ecode2 | sed "s/[^0-9]//g" )

시작줄, 끝줄을 찾고

for l in $elines ; do
     if [ "$l" -ge $slineno ] ; then
          elineno=$l
          break
     fi
done

해당 end 라인값을 결정하고

head -n $headno $file > top_file
tailno=`expr $tline - $elineno`
tail -n $tailno $file > bottom_file

앞부분과 뒷부분을 뽑아내서 임시저장 하고

cat top_file mysmali.smali bottom_file > new.smali

3개를 하나로 뭉치는 거지요.



뭔가에 적용할 아이디어가 있으신 분은 본인만의 자동화 스크립트에 한번 도전해보십시오.
Extra Form
첨부
mod_smali.sh  [File Size:875Bytes/Download:4]
mod_rw_media.sh  [File Size:1.6KB/Download:6]
댓글을 남겨야 다운로드가 가능합니다. 감사의 댓글을 달고 오른쪽 확인버튼을 눌러주세요.
다운로드시 일주일에 한개 이상의 게시물 작성이 필요합니다. 지금 자유게시판에 회원님의 하루를 남겨보세요.
추천♡버튼을 잊지 마세요. 추천인과 회원님 모두 포인트가 적립됩니다.

짱구삼촌 님의 SIGNATURE

profile

그래도 아직은 사랑이, 낡은 외투처럼 너덜너덜해져서 이제는 갖다 버려야 할, 그러나 버리지 못하고...

"신은 그저 질문하는 자일 뿐... 운명은 내가 던지는 질문이다. 답은 그대들이 찾아라."

댓글 2
댓글 쓰기 권한이 없습니다.
정렬 목록 검색 쓰기
등록된 글이 없습니다.
1 - 2