안경잡이개발자

728x90
반응형

  Apktool을 이용해 APK 파일을 리버싱한 뒤에 이를 다시 재빌드(Rebuild)할 때 가끔 다음의 오류를 만날 수 있다.

 

brut.androlib.AndrolibException: brut.common.BrutException: could not exec (exit code = 1)

 

  이 오류는 Apktool을 이용해 리패키징을 진행할 때 마주칠 수 있는 오류이다. 이 오류는 대부분 AAPT 관련 이슈로 발생한다. AAPT(Android Asset Packaging Tool)안드로이드에서 사용되는 문자열, 이미지 등의 에셋(Asset)을 효율적으로 컴파일하고 패키징하기 위한 도구이다. 안드로이드 앱을 개발할 때는 별도의 에셋 폴더에 문자열, 이미지를 모아 놓는데 이것이 실제 코드와 함께 동작할 수 있도록 한다.

 

방법 1) 리패키징할 때 AAPT v2 사용 강제하기

 

  2020년 기준으로 최신 앱들은 AAPT v2를 사용하는 경우가 많은데, Apktool의 버전에 따라서 이를 처리하는 방법이 다르다. 예를 들어 Apktool v.2.3.4는 AAPT v1과 v2 바이너리를 모두 묶어서 .jar 파일에 넣는다. 이러한 과정에서 리패키징 오류가 발생할 수 있는데, AAPT v2 사용을 강제한다면 문제가 해결될 가능성이 있다.

 

  필자의 경우 Apktool v.2.4.1을 이용하였으며, 재빌드 과정에서 --use-aapt2 옵션을 넣어주었다. 일단 먼저 디컴파일을 하면 다음과 같이 실행될 것이다. 정상적으로 디컴파일이 완료된 것을 확인할 수 있다.

 

apktool -f d test.apk -o test_aapt_v2

 

 

  이후에 재빌드를 할 때 AAPT v2를 강제하지 않으면 다음과 같은 오류가 발생할 수 있다. 그것도 매우 많은 오류가 한꺼번에 발생할 수 있다. 아마 대부분 아래와 같은 오류를 만나서 헤맬 것이다.

 

apktool -f b test_aapt_v2

 

 

  이때 다음과 같이 AAPT v2 사용을 강제하면, 오류가 해결될 가능성이 있다.

 

apktool -f b test_aapt_v2 --use-aapt2

 

  다만 일부 앱에서는 AAPT v2를 강제하여도 오류가 남아 있거나 새로운 오류가 등장할 수 있다. 필자의 경우에도 여전히 오류가 남아 있어서, 다른 방법을 찾아야 했다. --use-aapt2 옵션을 추가하여 문제가 해결된 사람들은 여기에서 끝내도 된다.

 

 

방법 2) Apktool 버전 바꾸어 보기

 

  Apktool의 버전을 교체해본다. 필자의 경우 Apktool 최신 버전(Latest)인 2.4.1을 이용했는데, 이전 버전인 Apktool 2.3.4를 함께 이용해 보는 것도 방법이다. 포럼의 일부 게시글에서는 디컴파일과 리패키징에서 사용하는 Apktool의 버전을 다르게 하라는 조언이 있으며, 이를 통해 해결했다는 사례를 찾을 수 있었다.

 

  혹은 아예 더 낮은 Apktool 버전을 사용하면 일부 앱에 대해서는 정상 동작한다는 사례를 찾을 수 있었다. 따라서 자신의 앱에 대하여 오류가 발생한다면, 여러 가지 버전의 Apktool을 적용해보자. 참고로 필자의 경우에 이 방법을 사용해도 리패키징에서 실패하였다.

 

방법 3) Java 버전 바꾸어 보기

 

  포럼에서는 32-bit로 설치된 Java를 제거하고, 64-bit Java를 설치했더니 문제가 해결된 사례가 있었다고 한다. 필자의 경우 이건 적용해보지 않았다.

 

방법 4) 디컴파일 과정에서 리소스 제거하기

 

  만약 애초에 발생한 오류가 리소스(Resource) 컴파일 과정에서 발생한 것이라면, 리소스는 제외하고 디코딩을 한다면 나중에 리패키징을 할 때 오류가 발생하지 않는다. 소스코드를 수정하는 과정에서 리소스는 건드리지 않고 Java (smali) 코드만 수정하는 것이 목표인 경우, 이 방법만으로도 오류 없이 분석을 진행할 수 있다.

 

  공식 문서에 따르면 다음과 같이 기술되어 있다.

 

  "This will prevent the decompile of resources. This keeps the resources.arsc intact without any decode. If only editing Java (smali) then this is the recommended action for faster decompile & rebuild."

 

  여기에서 resources.arsc 각종 리소스 정보를 담고 있는 파일이다. 우리가 앱을 수정할 때 리소스 파일을 수정하게 되는 일이 필요할 수 있는데, 이때는 이 파일을 디코딩하여 우리가 분석할 수 있는 형태로 변환해야 한다. 예를 들어 새로운 이미지를 추가하거나, 문자열을 추가할 때 꼭 필요할 것이다. 만약 이런 행위 없이, 취약점 분석이 목적이라면 사실 resources.arsc 디코딩은 필요하지 않을 것이다.

 

  저자의 경우 취약점 분석이 목적이므로, 리소스를 제외하고 디코딩을 수행했다.

 

apktool -f d test.apk -o test_without_resource -r

 

 

  이 경우에 다시 리패키징을 할 때 오류가 발생하지 않는다.

 

apktool b test_without_resource

 

 

  필자는 앱을 분석할 때 리소스를 직접 추가하여 앱을 확장할 목적이 없고, 단순히 smali 코드 수정 및 분석이 주 목적이어서 이러한 방법을 이용해도 문제가 없는 상황이다. 결과적으로 다음과 같이 dist 폴더 안에 APK 파일이 생성된다.

 

 

※ 요약 ※

 

  깃허브와 포럼에서 찾아 본 결과, 해결 가능성이 있다고 제안된 방법들은 다음과 같다.

 

  1. 빌드할 때 --use-aapt2 옵션 넣어서, AAPT v2 사용 강제하기
  2. 빌드할 때 이전 Apktool 버전 사용해보기 (디컴파일 때와 다른 버전으로)
  3. Java 버전 및 운영체제 환경 바꾸어서 다시 빌드하기 (32bit -> 64bit)
  4. 리소스 수정이 필요하지 않은 경우, 디컴파일 할 때 -r 옵션 넣어서 resources.arsc 파일 제외하고 디코딩하기

 

  단, 앱 리소스 수정이 꼭 필요하면 1, 2, 3번 적용해보면서 문제 해결하야 할 것이다. 다만 취약점 분석이 목적이라면 대개 resources.arsc를 갈아 끼울 필요는 없고, smali 코드 수정이 필요한 정도라서 4번으로 진행해도 될 것이다.

728x90
반응형

Comment +0