안드로이드 악성코드 분석 시, 원본 dex를 숨기기 위해 dex파일 동적로딩을 하는 경우가 많이 있습니다.

 

동적으로 Dex파일을 로드하기 위해선 파일 혹은 메모리에서 로드하는데 다음과 같은 함수를 사용하게 됩니다.

 

From file:
dalvik.system.DexFile.loadDex depreciated after API 26
dalvik.system.DexClassLoader
dalvik.system.PathClassLoader


From memory:
dalvik.system.InMemoryDexClassLoader (not common in malwares)

 

파일을 통한 동적로딩 중 DexClassLoader함수를 이용하여 동적로딩하는 코드 작성 및 분석 방법을 확인하겠습니다.

android developer를 통해 확인한 dexclassloader 함수 형식입니다.

아래는 dexclassloader를 이용하여 외부 apk의 dex를 로드하는 코드 예제입니다.

 

dexclassloader.java


public class MainActivity extends AppCompatActivity {
   static final int BUF_SIZE = 8 * 1024;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      findViewById(R.id.button).setOnClickListener(
      new Button.OnClickListener(){
         public void onClick(View v){
         String text = loadClass2();
         Toast.makeText(getApplicationContext(),text,Toast.LENGTH_LONG).show();
         }
      });

   }

 

   private String loadClass2(){
      String APPJS = "test.apk";   // 불러올 apk 이름 명시
      File dexInternalStoragePath = new File(getDir("cache",Context.MODE_PRIVATE), APPJS);
      BufferedInputStream bis = null;
      OutputStream dexWriter = null;

      try {                             // asset 폴더 내 저장된 apk파일을 앱 내 read가 가능한 영역으로 복사                    

                                        // (/data/data/<app>/app_cache/)
         bis = new BufferedInputStream(getAssets().open(APPJS));
         dexWriter = new BufferedOutputStream(new FileOutputStream(dexInternalStoragePath));
         byte[] buf = new byte[BUF_SIZE];
         int len;
         while ((len = bis.read(buf, 0, BUF_SIZE)) > 0) {
            dexWriter.write(buf, 0, len);
         }
         dexWriter.close();
         bis.close();
      } catch (Exception e) {
// TODO Auto-generated catch block
         e.printStackTrace();
      }

      final File optimizedDexOutputPath = getDir("cache",Context.MODE_PRIVATE);    // 복사한 apk파일 경로 획득
      DexClassLoader dexClassLoader = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(), null,getClassLoader());     //dex 파일 로드
     try {
        Class clazz = dexClassLoader.loadClass("com.example.user.test.test");  // dex 파일 내 class 로드
        Object object = clazz.newInstance();
        Method method = clazz.getMethod("get_Message");    //class 내 method 로드
        String text = (String) method.invoke(object);   //method 호출
        return text;
      }catch (Exception e){
        e.printStackTrace();
      }
      return "Error..!!";
   }

}


test.java(test.apk)

 

package com.example.user.flag;

 

 

public class test{
  public String get_Message(){
      return "Catch Me!";
   }

}

 

test.java의 경우 앱 실행은 되지 않지만 빌드를 통해 apk파일 생성 및 dexclassloader.java가 있는 프로젝트 assets 파일 내 apk파일 복사


이렇게 작성된 앱의 경우, assets파일 내 apk파일이 존재하는 것을 모른다면 test.java의 내용을 알기 어렵습니다.

 

원본 Dex 추출을 위해 앱 실행 및 단말기 내 /proc/<pid>/maps를 확인하여 불러오는 dex파일의 위치를 확인합니다.

그 후 해당 위치(위 예제 앱의 경우 /data/data/<package_name>/app_cache/)에 복사한 dex파일이 존재합니다.

 

다만, 복사한 dex파일은 odex파일로 dex형식으로 변환하여 원본소스코드 확인이 가능합니다.

'Mobile' 카테고리의 다른 글

Frida cheat sheet  (0) 2020.10.11
MultiDex Dynamic Debug(feat. JEB)  (0) 2020.05.18
odex to dex  (0) 2020.05.08
ro.debuggable 변경을 통한 동적 디버깅  (2) 2019.09.23
IDA DEX,SO 동적디버깅  (0) 2019.09.23

what is odex file?

- Android에서 앱 설치 시점에 컴파일하여 실행을 위한 최적화된 파일로 변환하며, 현재 단말기에서 최적화를 위해 변환되어 저장되는 파일

 

안드로이드 분석 시, apk 내 dex파일이 없는 앱이 존재하는데 해당 앱에는 dex 파일 대신 odex파일을 통해 앱을 실행시킵니다.

odex파일의 경우 안드로이드에서 자체적으로 앱 설치 시 컴파일 되는 파일이므로 리눅스 실행파일 헤더를 가지게 되며, 이를 dex파일로 변환해줘야 기존의 디컴파일 툴을 통해 원본 소스코드 확인이 가능합니다.

 

odex to dex

odex 파일 변환을 위해서는 baksmali/smali.jar가 필요하며 아래 주소를 통해 다운받을 수 있습니다.

 

www.bitbucket.org/JesusFreke/smali/downloads/

 

JesusFreke / smali / Downloads — Bitbucket

 

bitbucket.org

baksmali / smali.jar 다운로드 후 변환하고자 하는 odex파일을 같은 디렉토리에 위치 시킨 후 다음 명령어를 입력합니다.

java -jar baksmali.jar d <변환하고자 하는 odex파일 및 경로> -o <결과값이 저장될 폴더명>

 

명령어를 실행하면 아래와 같이 odex파일에서 smali 파일을 추출합니다

smali.jar를 통해 획득한 smali코드를 dex파일로 변환합니다.

java -jar smali.jar a <결과값이 저장된 폴더명> -o classes.dex

명령어를 실행하면 classes.dex파일을 획득할 수 있으며, jadx/jd-gui와 같은 툴을 통해 원본 소스코드 확인이 가능합니다.

 

참고

odex : www.howlling.tistory.com/55

'Mobile' 카테고리의 다른 글

MultiDex Dynamic Debug(feat. JEB)  (0) 2020.05.18
Dynamic Code Loading in Android (feat.DexClassloader)  (3) 2020.05.08
ro.debuggable 변경을 통한 동적 디버깅  (2) 2019.09.23
IDA DEX,SO 동적디버깅  (0) 2019.09.23
DVIA (Binary Patching)  (0) 2019.09.03

https://securitynote.tistory.com/13

 

[Android] DirtyCow(더티카우) 취약점 (CVE-2016-5195)

DirtyC0w(더티카우) 취약점 (CVE-2016-5195) 개요 1) DirtyC0w (더티카우) 취약점이란? : 2016년 10월 CVE-2016-5195 취약점 : 루트 권한으로도 변경할 수 없었던 default.prop 파일을 익스플로잇을 통해 수정 가..

securitynote.tistory.com

ro.debuggable을 변경하면 앱 manifest.xml파일에 android:debuggable="true" 옵션이 없어도 동적 디버깅이 가능하다는 내용이다.

 

하지만... root explorer로 ro.debuggable을 변경한 후 설레는 맘으로 동적 디버깅을 시도했으나...

 

??

 

이상하게 ro.debuggable=1인데도 동적디버깅이 되지 않았다.

 

https://www.bodkin.ren/index.php/archives/533/

 

Android 「动态分析」打开调试开关的三种方法 - SewellDinG @ 老 锥

应用的动态调试是Android逆向的大类,而打开可调试开关则是动态调试的第一步,总结一下打开开关的三种方法; AndroidManifest.xml 最常规的方法,拿到一个应用后,直接反编译,在AndroidManifest.xml的application中添加android:debuggable="true"字段,在回编译、签名、安装、然后进行动态调试; mprop 修改系统调试的总开关字段,由于系统文件只可读,强制修改重新编译镜像再刷入设备又很复杂还不安全,这里可以注入init进程,修改内存中的ro.d

www.bodkin.ren

위 포스팅을 통해 해답을 찾았는데

 

default.prop의 값을 변경해도 메모리에 올라와있는 속성 값은 그대로 0 이기 때문에 동적 디버깅이 되지 않는다.

 

위 블로그에서 mprop라는 파일을 다운받아, 실행하면 ro.debuggable값이 1로 패치 된다.

 

Usage

./mprop ro.debuggable 1

 

어떤 원리인지 궁금해서 살펴본 결과, /proc/1/maps의 /dev/__properties__안의 값을 변경하고 있다.

 

실제 단말기에서 확인한 결과, /init 프로세스의 /dev/__properties__의 메모리 주소를 확인한 후 인자로 받은 변경하고자 하는 속성값을 검색 후 값을 변경하는 것으로 보인다.

 

해당 메모리 주소의 값을 살펴보니 인자로 넣어 준 debuggable의 값이 들어있고 정상적으로 0x31(1)로 값이 변경된 것을 확인할 수 있었다.

 

이 후, manifest.xml 파일에 android:debuggable="true"값이 없어도 정상적으로 동적 디버깅이 가능함.

 

갓 중국...

'Mobile' 카테고리의 다른 글

Dynamic Code Loading in Android (feat.DexClassloader)  (3) 2020.05.08
odex to dex  (0) 2020.05.08
IDA DEX,SO 동적디버깅  (0) 2019.09.23
DVIA (Binary Patching)  (0) 2019.09.03
Cydia Impactor 에러 모음  (1) 2019.09.03

+ Recent posts